authorbors <bors@rust-lang.org> 2026-06-28 02:37:46 UTC
committerbors <bors@rust-lang.org> 2026-06-28 02:37:46 UTC
logfd07dbfc91b7b6b3fa76d957e130c51e654131ee
tree090a2604fc3cef2b54a3fd9b3746e779f31b259e
parent8b95a26baf5820929d86a844317160905e7b325b
parent2f26f3a0bec4a63d2299ac740a05690c5ff5bc53

Auto merge of #158508 - jhpratt:rollup-FKOfwV9, r=jhpratt

Rollup of 15 pull requests Successful merges: - rust-lang/rust#158497 (stdarch subtree update) - rust-lang/rust#152225 (Add supertrait item shadowing for type-level path resolution) - rust-lang/rust#158194 (Adds RmetaLinkCache a per-link cache that uses path as the key of dec…) - rust-lang/rust#158466 (rustdoc: show impl Trait<Box<Local>> for Foreign, etc on Local's docs) - rust-lang/rust#158501 (miri subtree update) - rust-lang/rust#153097 (Expand `OptionFlatten`'s iterator methods) - rust-lang/rust#157614 (Move tests drop) - rust-lang/rust#157996 (perf: drop the full-crate AST walk in check_unused) - rust-lang/rust#158163 (Fix too-short variance slice in `variances_of` cycle recovery) - rust-lang/rust#158233 (Allow the unstable attribute on foreign type) - rust-lang/rust#158433 (Fix inconsistent safety requirement in VecDeque::nonoverlapping_ranges) - rust-lang/rust#158464 (Reorganize `tests/ui/issues` [15/N]) - rust-lang/rust#158470 (Upgrade `jsonsocck` and `jsondoclint` to edition 2024.) - rust-lang/rust#158485 (Reorganize `tests/ui/issues` [16/N]) - rust-lang/rust#158488 (Upgrade `rustdoc-json-types` to 2024 edition.)

310 files changed, 5879 insertions(+), 2810 deletions(-)

compiler/rustc_attr_parsing/src/attributes/stability.rs+1
......@@ -40,6 +40,7 @@ const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
4040 Allow(Target::Static),
4141 Allow(Target::ForeignFn),
4242 Allow(Target::ForeignStatic),
43 Allow(Target::ForeignTy),
4344 Allow(Target::ExternCrate),
4445]);
4546
compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs+1-1
......@@ -19,7 +19,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
1919 }
2020
2121 match intrinsic {
22 "llvm.prefetch" => {
22 "llvm.prefetch.p0" => {
2323 // Nothing to do. This is merely a perf hint.
2424 }
2525
compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs+1-1
......@@ -1044,7 +1044,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
10441044#[cfg(feature = "master")]
10451045pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> {
10461046 let gcc_name = match name {
1047 "llvm.prefetch" => {
1047 "llvm.prefetch.p0" => {
10481048 let gcc_name = "__builtin_prefetch";
10491049 let func = cx.context.get_builtin_function(gcc_name);
10501050 cx.functions.borrow_mut().insert(gcc_name.to_string(), func);
compiler/rustc_codegen_llvm/src/intrinsic.rs+1-1
......@@ -412,7 +412,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
412412 let ptr = args[0].immediate();
413413 let locality = fn_args.const_at(1).to_leaf().to_i32();
414414 self.call_intrinsic(
415 "llvm.prefetch",
415 "llvm.prefetch.p0",
416416 &[self.val_ty(ptr)],
417417 &[
418418 ptr,
compiler/rustc_codegen_ssa/src/back/archive.rs+18-8
......@@ -22,7 +22,7 @@ use rustc_target::spec::Arch;
2222use tracing::trace;
2323
2424use super::metadata::{create_compressed_metadata_file, search_for_section};
25use super::rmeta_link;
25use super::rmeta_link::{self, RmetaLinkCache};
2626use super::symbol_edit::{apply_edits, collect_internal_names};
2727use crate::common;
2828// Public for ArchiveBuilderBuilder::extract_bundled_libs
......@@ -311,7 +311,7 @@ fn find_binutils_dlltool(sess: &Session) -> OsString {
311311}
312312
313313pub enum AddArchiveKind<'a> {
314 Rlib(/*skip*/ &'a dyn Fn(&str, ArchiveEntryKind) -> bool),
314 Rlib(&'a mut RmetaLinkCache, /*skip*/ &'a dyn Fn(&str, ArchiveEntryKind) -> bool),
315315 Other,
316316}
317317
......@@ -466,7 +466,11 @@ pub fn try_extract_macho_fat_archive(
466466}
467467
468468impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
469 fn add_archive(&mut self, archive_path: &Path, ar_kind: AddArchiveKind<'_>) -> io::Result<()> {
469 fn add_archive(
470 &mut self,
471 archive_path: &Path,
472 mut ar_kind: AddArchiveKind<'_>,
473 ) -> io::Result<()> {
470474 let mut archive_path = archive_path.to_path_buf();
471475 if self.sess.target.llvm_target.contains("-apple-macosx")
472476 && let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
......@@ -481,8 +485,14 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
481485 let archive_map = unsafe { Mmap::map(File::open(&archive_path)?)? };
482486 let archive = ArchiveFile::parse(&*archive_map)
483487 .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
484 let metadata_link = match ar_kind {
485 AddArchiveKind::Rlib(..) => rmeta_link::read(&archive, &archive_map, &archive_path),
488 let skip = match &ar_kind {
489 AddArchiveKind::Rlib(_, skip) => Some(*skip),
490 AddArchiveKind::Other => None,
491 };
492 let metadata_link = match &mut ar_kind {
493 AddArchiveKind::Rlib(cache, _) => cache.get_or_insert_with(&archive_path, || {
494 rmeta_link::read(&archive, &archive_map, &archive_path)
495 }),
486496 AddArchiveKind::Other => None,
487497 };
488498 let archive_index = self.src_archives.len();
......@@ -512,9 +522,9 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> {
512522 } else {
513523 ArchiveEntryKind::Other
514524 };
515 let drop = match ar_kind {
516 AddArchiveKind::Rlib(skip) => skip(&file_name, kind),
517 AddArchiveKind::Other => false,
525 let drop = match skip {
526 Some(skip) => skip(&file_name, kind),
527 None => false,
518528 };
519529 if !drop {
520530 let source = if entry.is_thin() {
compiler/rustc_codegen_ssa/src/back/link.rs+14-2
......@@ -59,6 +59,7 @@ use super::archive::{
5959use super::command::Command;
6060use super::linker::{self, Linker};
6161use super::metadata::{MetadataPosition, create_wrapper_file};
62use super::rmeta_link::RmetaLinkCache;
6263use super::rpath::{self, RPathConfig};
6364use super::{apple, rmeta_link, versioned_llvm_target};
6465use crate::base::needs_allocator_shim_for_linking;
......@@ -86,6 +87,7 @@ pub fn link_binary(
8687 let _timer = sess.timer("link_binary");
8788 let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
8889 let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new();
90 let mut rmeta_link_cache = RmetaLinkCache::default();
8991 for &crate_type in &crate_info.crate_types {
9092 // Ignore executable crates if we have -Z no-codegen, as they will error.
9193 if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen())
......@@ -139,6 +141,7 @@ pub fn link_binary(
139141 link_staticlib(
140142 sess,
141143 archive_builder_builder,
144 &mut rmeta_link_cache,
142145 &compiled_modules,
143146 &crate_info,
144147 &metadata,
......@@ -150,6 +153,7 @@ pub fn link_binary(
150153 link_natively(
151154 sess,
152155 archive_builder_builder,
156 &mut rmeta_link_cache,
153157 crate_type,
154158 &out_filename,
155159 &compiled_modules,
......@@ -502,6 +506,7 @@ fn link_rlib<'a>(
502506fn link_staticlib(
503507 sess: &Session,
504508 archive_builder_builder: &dyn ArchiveBuilderBuilder,
509 rmeta_link_cache: &mut RmetaLinkCache,
505510 compiled_modules: &CompiledModules,
506511 crate_info: &CrateInfo,
507512 metadata: &EncodedMetadata,
......@@ -531,7 +536,7 @@ fn link_staticlib(
531536 let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
532537 ab.add_archive(
533538 path,
534 AddArchiveKind::Rlib(&|fname: &str, entry_kind| {
539 AddArchiveKind::Rlib(rmeta_link_cache, &|fname: &str, entry_kind| {
535540 // Ignore metadata and rmeta-link files.
536541 if fname == METADATA_FILENAME || fname == rmeta_link::FILENAME {
537542 return true;
......@@ -939,6 +944,7 @@ fn report_linker_output(
939944fn link_natively(
940945 sess: &Session,
941946 archive_builder_builder: &dyn ArchiveBuilderBuilder,
947 rmeta_link_cache: &mut RmetaLinkCache,
942948 crate_type: CrateType,
943949 out_filename: &Path,
944950 compiled_modules: &CompiledModules,
......@@ -965,6 +971,7 @@ fn link_natively(
965971 flavor,
966972 sess,
967973 archive_builder_builder,
974 rmeta_link_cache,
968975 crate_type,
969976 tmpdir,
970977 temp_filename,
......@@ -2562,6 +2569,7 @@ fn linker_with_args(
25622569 flavor: LinkerFlavor,
25632570 sess: &Session,
25642571 archive_builder_builder: &dyn ArchiveBuilderBuilder,
2572 rmeta_link_cache: &mut RmetaLinkCache,
25652573 crate_type: CrateType,
25662574 tmpdir: &Path,
25672575 out_filename: &Path,
......@@ -2690,6 +2698,7 @@ fn linker_with_args(
26902698 cmd,
26912699 sess,
26922700 archive_builder_builder,
2701 rmeta_link_cache,
26932702 crate_info,
26942703 crate_type,
26952704 tmpdir,
......@@ -3126,6 +3135,7 @@ fn add_upstream_rust_crates(
31263135 cmd: &mut dyn Linker,
31273136 sess: &Session,
31283137 archive_builder_builder: &dyn ArchiveBuilderBuilder,
3138 rmeta_link_cache: &mut RmetaLinkCache,
31293139 crate_info: &CrateInfo,
31303140 crate_type: CrateType,
31313141 tmpdir: &Path,
......@@ -3178,6 +3188,7 @@ fn add_upstream_rust_crates(
31783188 cmd,
31793189 sess,
31803190 archive_builder_builder,
3191 rmeta_link_cache,
31813192 crate_info,
31823193 tmpdir,
31833194 cnum,
......@@ -3309,6 +3320,7 @@ fn add_static_crate(
33093320 cmd: &mut dyn Linker,
33103321 sess: &Session,
33113322 archive_builder_builder: &dyn ArchiveBuilderBuilder,
3323 rmeta_link_cache: &mut RmetaLinkCache,
33123324 crate_info: &CrateInfo,
33133325 tmpdir: &Path,
33143326 cnum: CrateNum,
......@@ -3339,7 +3351,7 @@ fn add_static_crate(
33393351 let mut archive = archive_builder_builder.new_archive_builder(sess);
33403352 if let Err(error) = archive.add_archive(
33413353 cratepath,
3342 AddArchiveKind::Rlib(&|f, entry_kind| {
3354 AddArchiveKind::Rlib(rmeta_link_cache, &|f, entry_kind| {
33433355 if f == METADATA_FILENAME || f == rmeta_link::FILENAME {
33443356 return true;
33453357 }
compiler/rustc_codegen_ssa/src/back/rmeta_link.rs+17-1
......@@ -2,9 +2,10 @@
22//! and potentially other data collected and used when building or linking a rlib.
33//! See <https://github.com/rust-lang/rust/issues/138243>.
44
5use std::path::Path;
5use std::path::{Path, PathBuf};
66
77use object::read::archive::ArchiveFile;
8use rustc_data_structures::fx::FxHashMap;
89use rustc_serialize::opaque::mem_encoder::MemEncoder;
910use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder};
1011use rustc_serialize::{Decodable, Encodable};
......@@ -54,3 +55,18 @@ pub fn read_from_data(archive_data: &[u8], rlib_path: &Path) -> Option<RmetaLink
5455 let archive = ArchiveFile::parse(archive_data).ok()?;
5556 read(&archive, archive_data, rlib_path)
5657}
58
59#[derive(Default)]
60pub struct RmetaLinkCache {
61 cache: FxHashMap<PathBuf, Option<RmetaLink>>,
62}
63
64impl RmetaLinkCache {
65 pub fn get_or_insert_with(
66 &mut self,
67 rlib_path: &Path,
68 load: impl FnOnce() -> Option<RmetaLink>,
69 ) -> Option<&RmetaLink> {
70 self.cache.entry(rlib_path.to_path_buf()).or_insert_with(load).as_ref()
71 }
72}
compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs+2-4
......@@ -409,9 +409,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
409409
410410 pub(super) fn report_ambiguous_assoc_item(
411411 &self,
412 bound1: ty::PolyTraitRef<'tcx>,
413 bound2: ty::PolyTraitRef<'tcx>,
414 matching_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
412 matching_candidates: &[ty::PolyTraitRef<'tcx>],
415413 qself: AssocItemQSelf,
416414 assoc_tag: ty::AssocTag,
417415 assoc_ident: Ident,
......@@ -443,7 +441,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
443441 // predicates!).
444442 // FIXME: Turn this into a structured, translatable & more actionable suggestion.
445443 let mut where_bounds = vec![];
446 for bound in [bound1, bound2].into_iter().chain(matching_candidates) {
444 for &bound in matching_candidates {
447445 let bound_id = bound.def_id();
448446 let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind(
449447 tcx,
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+77-3
......@@ -24,6 +24,7 @@ use std::{assert_matches, slice};
2424use rustc_abi::FIRST_VARIANT;
2525use rustc_ast::LitKind;
2626use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
27use rustc_data_structures::sso::SsoHashSet;
2728use rustc_errors::codes::*;
2829use rustc_errors::{
2930 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, StashKey,
......@@ -1262,6 +1263,74 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12621263 )
12631264 }
12641265
1266 /// When there are multiple traits which contain an identically named
1267 /// associated item, this function eliminates any traits which are a
1268 /// supertrait of another candidate trait.
1269 ///
1270 /// This is the type-level analogue of
1271 /// `rustc_hir_typeck::method::probe::ProbeContext::collapse_candidates_to_subtrait_pick`;
1272 /// keep both implementations in sync.
1273 ///
1274 /// This implements RFC #3624.
1275 fn collapse_candidates_to_subtrait_pick(
1276 &self,
1277 matching_candidates: &[ty::PolyTraitRef<'tcx>],
1278 ) -> Option<ty::PolyTraitRef<'tcx>> {
1279 if !self.tcx().features().supertrait_item_shadowing() {
1280 return None;
1281 }
1282
1283 let mut child_trait = matching_candidates[0];
1284 let mut supertraits: SsoHashSet<_> =
1285 traits::supertrait_def_ids(self.tcx(), child_trait.def_id()).collect();
1286
1287 let mut remaining_candidates: Vec<_> = matching_candidates[1..].iter().copied().collect();
1288 while !remaining_candidates.is_empty() {
1289 let mut made_progress = false;
1290 let mut next_round = vec![];
1291
1292 for remaining_trait in remaining_candidates {
1293 if supertraits.contains(&remaining_trait.def_id()) {
1294 made_progress = true;
1295 continue;
1296 }
1297
1298 // This candidate is not a supertrait of the `child_trait`.
1299 // Check if it's a subtrait of the `child_trait`, instead.
1300 // If it is, then it must have been a subtrait of every
1301 // other pick we've eliminated at this point. It will
1302 // take over at this point.
1303 let remaining_trait_supertraits: SsoHashSet<_> =
1304 traits::supertrait_def_ids(self.tcx(), remaining_trait.def_id()).collect();
1305 if remaining_trait_supertraits.contains(&child_trait.def_id()) {
1306 child_trait = remaining_trait;
1307 supertraits = remaining_trait_supertraits;
1308 made_progress = true;
1309 continue;
1310 }
1311
1312 // Neither `child_trait` or the current candidate are
1313 // supertraits of each other.
1314 // Don't bail here, since we may be comparing two supertraits
1315 // of a common subtrait. These two supertraits won't be related
1316 // at all, but we will pick them up next round when we find their
1317 // child as we continue iterating in this round.
1318 next_round.push(remaining_trait);
1319 }
1320
1321 if made_progress {
1322 // If we've made progress, iterate again.
1323 remaining_candidates = next_round;
1324 } else {
1325 // Otherwise, we must have at least two candidates which
1326 // are not related to each other at all.
1327 return None;
1328 }
1329 }
1330
1331 Some(child_trait)
1332 }
1333
12651334 /// Search for a single trait bound whose trait defines the associated item given by
12661335 /// `assoc_ident`.
12671336 ///
......@@ -1296,10 +1365,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12961365 };
12971366
12981367 if let Some(bound2) = matching_candidates.next() {
1368 let all_matching_candidates: Vec<_> =
1369 [bound1, bound2].into_iter().chain(matching_candidates).collect();
1370 if let Some(bound) = self.collapse_candidates_to_subtrait_pick(&all_matching_candidates)
1371 {
1372 return Ok(bound);
1373 }
1374
12991375 return Err(self.report_ambiguous_assoc_item(
1300 bound1,
1301 bound2,
1302 matching_candidates,
1376 &all_matching_candidates,
13031377 qself,
13041378 assoc_tag,
13051379 assoc_ident,
compiler/rustc_hir_typeck/src/method/probe.rs+4
......@@ -2359,6 +2359,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
23592359 /// multiple conflicting picks if there is one pick whose trait container is a subtrait
23602360 /// of the trait containers of all of the other picks.
23612361 ///
2362 /// This is the method-probe analogue of
2363 /// `rustc_hir_analysis::hir_ty_lowering::HirTyLowerer::collapse_candidates_to_subtrait_pick`;
2364 /// keep both implementations in sync.
2365 ///
23622366 /// This implements RFC #3624.
23632367 fn collapse_candidates_to_subtrait_pick(
23642368 &self,
compiler/rustc_query_impl/src/handle_cycle_error.rs+1-1
......@@ -105,7 +105,7 @@ pub(crate) fn variances_of<'tcx>(
105105 err: Diag<'_>,
106106) -> &'tcx [ty::Variance] {
107107 let _guar = err.delay_as_bug();
108 let n = tcx.generics_of(def_id).own_params.len();
108 let n = tcx.generics_of(def_id).count();
109109 tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n))
110110}
111111
compiler/rustc_resolve/src/check_unused.rs+8-5
......@@ -10,9 +10,9 @@
1010//
1111// Checking for unused imports is split into three steps:
1212//
13// - `UnusedImportCheckVisitor` walks the AST to find all the unused imports
14// inside of `UseTree`s, recording their `NodeId`s and grouping them by
15// the parent `use` item
13// - `UnusedImportCheckVisitor` visits the `use` items collected during late
14// resolution to find all the unused imports inside of `UseTree`s, recording
15// their `NodeId`s and grouping them by the parent `use` item
1616//
1717// - `calc_unused_spans` then walks over all the `use` items marked in the
1818// previous step to collect the spans associated with the `NodeId`s and to
......@@ -410,7 +410,7 @@ fn calc_unused_spans(
410410}
411411
412412impl Resolver<'_, '_> {
413 pub(crate) fn check_unused(&mut self, krate: &ast::Crate) {
413 pub(crate) fn check_unused(&mut self, use_items: Vec<&ast::Item>) {
414414 let tcx = self.tcx;
415415 let mut maybe_unused_extern_crates = FxHashMap::default();
416416
......@@ -465,7 +465,10 @@ impl Resolver<'_, '_> {
465465 base_id: ast::DUMMY_NODE_ID,
466466 item_span: DUMMY_SP,
467467 };
468 visit::walk_crate(&mut visitor, krate);
468 // `use_items` is in crate DFS order, so diagnostics and side effects are unchanged.
469 for item in use_items {
470 visitor.visit_item(item);
471 }
469472
470473 visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);
471474
compiler/rustc_resolve/src/late.rs+17-8
......@@ -5623,12 +5623,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
56235623}
56245624
56255625/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
5626/// lifetime generic parameters and function parameters.
5627struct ItemInfoCollector<'a, 'ra, 'tcx> {
5626/// lifetime generic parameters and function parameters. Also collects all `use` and
5627/// `extern crate` items so that `check_unused` doesn't need to walk the crate again.
5628struct ItemInfoCollector<'a, 'ast, 'ra, 'tcx> {
56285629 r: &'a mut Resolver<'ra, 'tcx>,
5630 /// All `use` and `extern crate` items, in the order in which they are visited.
5631 use_items: Vec<&'ast Item>,
56295632}
56305633
5631impl ItemInfoCollector<'_, '_, '_> {
5634impl ItemInfoCollector<'_, '_, '_, '_> {
56325635 fn collect_fn_info(&mut self, decl: &FnDecl, id: NodeId) {
56335636 self.r
56345637 .delegation_fn_sigs
......@@ -5662,7 +5665,7 @@ fn required_generic_args_suggestion(generics: &ast::Generics) -> Option<String>
56625665 if required.is_empty() { None } else { Some(format!("<{}>", required.join(", "))) }
56635666}
56645667
5665impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
5668impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> {
56665669 fn visit_item(&mut self, item: &'ast Item) {
56675670 match &item.kind {
56685671 ItemKind::TyAlias(TyAlias { generics, .. })
......@@ -5695,11 +5698,13 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
56955698 }
56965699 }
56975700
5701 ItemKind::Use(..) | ItemKind::ExternCrate(..) => {
5702 self.use_items.push(item);
5703 }
5704
56985705 ItemKind::Mod(..)
56995706 | ItemKind::Static(..)
57005707 | ItemKind::ConstBlock(..)
5701 | ItemKind::Use(..)
5702 | ItemKind::ExternCrate(..)
57035708 | ItemKind::MacroDef(..)
57045709 | ItemKind::GlobalAsm(..)
57055710 | ItemKind::MacCall(..)
......@@ -5730,9 +5735,12 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
57305735}
57315736
57325737impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
5733 pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
5738 /// Returns the `use` and `extern crate` items of the crate, for use by `check_unused`.
5739 pub(crate) fn late_resolve_crate<'ast>(&mut self, krate: &'ast Crate) -> Vec<&'ast Item> {
57345740 with_owner(self, CRATE_NODE_ID, |this| {
5735 visit::walk_crate(&mut ItemInfoCollector { r: this }, krate);
5741 let mut info_collector = ItemInfoCollector { r: this, use_items: Vec::new() };
5742 visit::walk_crate(&mut info_collector, krate);
5743 let use_items = info_collector.use_items;
57365744 let mut late_resolution_visitor = LateResolutionVisitor::new(this);
57375745 late_resolution_visitor
57385746 .resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
......@@ -5745,6 +5753,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
57455753 crate::diagnostics::UnusedLabel,
57465754 );
57475755 }
5756 use_items
57485757 })
57495758 }
57505759}
compiler/rustc_resolve/src/lib.rs+3-2
......@@ -2082,9 +2082,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20822082 self.tcx
20832083 .sess
20842084 .time("finalize_macro_resolutions", || self.finalize_macro_resolutions(krate));
2085 self.tcx.sess.time("late_resolve_crate", || self.late_resolve_crate(krate));
2085 let use_items =
2086 self.tcx.sess.time("late_resolve_crate", || self.late_resolve_crate(krate));
20862087 self.tcx.sess.time("resolve_main", || self.resolve_main());
2087 self.tcx.sess.time("resolve_check_unused", || self.check_unused(krate));
2088 self.tcx.sess.time("resolve_check_unused", || self.check_unused(use_items));
20882089 self.tcx.sess.time("resolve_report_errors", || self.report_errors(krate));
20892090 self.tcx
20902091 .sess
library/alloc/src/collections/vec_deque/mod.rs+1-1
......@@ -267,7 +267,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
267267 ///
268268 /// - Ranges must not overlap: `src.abs_diff(dst) >= count`.
269269 /// - Ranges must be in bounds of the logical buffer: `src + count <= self.capacity()` and `dst + count <= self.capacity()`.
270 /// - `head` must be in bounds: `head < self.capacity()`.
270 /// - `head` must be in bounds: `head < self.capacity()`, unless `self.capacity() == 0`, in which case `head == 0`.
271271 #[cfg(not(no_global_oom_handling))]
272272 unsafe fn nonoverlapping_ranges(
273273 &mut self,
library/core/src/option.rs+97-3
......@@ -581,6 +581,7 @@
581581use crate::clone::TrivialClone;
582582use crate::iter::{self, FusedIterator, TrustedLen};
583583use crate::marker::Destruct;
584use crate::num::NonZero;
584585use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try};
585586use crate::panicking::{panic, panic_display};
586587use crate::pin::Pin;
......@@ -2666,18 +2667,111 @@ impl<A: Iterator> Iterator for OptionFlatten<A> {
26662667 type Item = A::Item;
26672668
26682669 fn next(&mut self) -> Option<Self::Item> {
2669 self.iter.as_mut()?.next()
2670 match &mut self.iter {
2671 Some(iter) => iter.next(),
2672 None => None,
2673 }
26702674 }
26712675
26722676 fn size_hint(&self) -> (usize, Option<usize>) {
2673 self.iter.as_ref().map(|i| i.size_hint()).unwrap_or((0, Some(0)))
2677 match &self.iter {
2678 Some(iter) => iter.size_hint(),
2679 None => (0, Some(0)),
2680 }
2681 }
2682
2683 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2684 match &mut self.iter {
2685 Some(iter) => iter.advance_by(n),
2686 None => NonZero::new(n).map_or(Ok(()), Err),
2687 }
2688 }
2689
2690 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2691 match &mut self.iter {
2692 Some(iter) => iter.nth(n),
2693 None => None,
2694 }
2695 }
2696
2697 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2698 where
2699 Fold: FnMut(Acc, Self::Item) -> Acc,
2700 {
2701 match self.iter {
2702 Some(iter) => iter.fold(init, fold),
2703 None => init,
2704 }
2705 }
2706
2707 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2708 where
2709 Fold: FnMut(Acc, Self::Item) -> R,
2710 R: Try<Output = Acc>,
2711 {
2712 match &mut self.iter {
2713 Some(iter) => iter.try_fold(init, fold),
2714 None => try { init },
2715 }
2716 }
2717
2718 fn count(self) -> usize {
2719 match self.iter {
2720 Some(iter) => iter.count(),
2721 None => 0,
2722 }
2723 }
2724
2725 fn last(self) -> Option<Self::Item> {
2726 match self.iter {
2727 Some(iter) => iter.last(),
2728 None => None,
2729 }
26742730 }
26752731}
26762732
26772733#[unstable(feature = "option_into_flat_iter", issue = "148441")]
26782734impl<A: DoubleEndedIterator> DoubleEndedIterator for OptionFlatten<A> {
26792735 fn next_back(&mut self) -> Option<Self::Item> {
2680 self.iter.as_mut()?.next_back()
2736 match &mut self.iter {
2737 Some(iter) => iter.next_back(),
2738 None => None,
2739 }
2740 }
2741
2742 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
2743 match &mut self.iter {
2744 Some(iter) => iter.advance_back_by(n),
2745 None => NonZero::new(n).map_or(Ok(()), Err),
2746 }
2747 }
2748
2749 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2750 match &mut self.iter {
2751 Some(iter) => iter.nth_back(n),
2752 None => None,
2753 }
2754 }
2755
2756 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
2757 where
2758 Fold: FnMut(Acc, Self::Item) -> Acc,
2759 {
2760 match self.iter {
2761 Some(iter) => iter.rfold(init, fold),
2762 None => init,
2763 }
2764 }
2765
2766 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
2767 where
2768 Fold: FnMut(Acc, Self::Item) -> R,
2769 R: Try<Output = Acc>,
2770 {
2771 match &mut self.iter {
2772 Some(iter) => iter.try_rfold(init, fold),
2773 None => try { init },
2774 }
26812775 }
26822776}
26832777
library/stdarch/.github/workflows/main.yml+2
......@@ -337,6 +337,8 @@ jobs:
337337 cargo run --bin=stdarch-gen-loongarch --release -- crates/stdarch-gen-loongarch/lasx.spec
338338 git diff --exit-code
339339 - name: Check hexagon
340 env:
341 STDARCH_GEN_MODE: check
340342 run: |
341343 cargo run -p stdarch-gen-hexagon --release
342344 git diff --exit-code
library/stdarch/Cargo.lock+87-25
......@@ -268,6 +268,22 @@ version = "1.0.2"
268268source = "registry+https://github.com/rust-lang/crates.io-index"
269269checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
270270
271[[package]]
272name = "errno"
273version = "0.3.14"
274source = "registry+https://github.com/rust-lang/crates.io-index"
275checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
276dependencies = [
277 "libc",
278 "windows-sys",
279]
280
281[[package]]
282name = "fastrand"
283version = "2.4.1"
284source = "registry+https://github.com/rust-lang/crates.io-index"
285checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
286
271287[[package]]
272288name = "find-msvc-tools"
273289version = "0.1.9"
......@@ -282,13 +298,14 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
282298
283299[[package]]
284300name = "getrandom"
285version = "0.2.17"
301version = "0.3.4"
286302source = "registry+https://github.com/rust-lang/crates.io-index"
287checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
303checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
288304dependencies = [
289305 "cfg-if",
290306 "libc",
291 "wasi",
307 "r-efi 5.3.0",
308 "wasip2",
292309]
293310
294311[[package]]
......@@ -299,7 +316,7 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
299316dependencies = [
300317 "cfg-if",
301318 "libc",
302 "r-efi",
319 "r-efi 6.0.0",
303320 "rand_core 0.10.0",
304321 "wasip2",
305322 "wasip3",
......@@ -445,6 +462,12 @@ version = "0.5.6"
445462source = "registry+https://github.com/rust-lang/crates.io-index"
446463checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
447464
465[[package]]
466name = "linux-raw-sys"
467version = "0.12.1"
468source = "registry+https://github.com/rust-lang/crates.io-index"
469checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
470
448471[[package]]
449472name = "log"
450473version = "0.4.29"
......@@ -457,6 +480,12 @@ version = "2.8.0"
457480source = "registry+https://github.com/rust-lang/crates.io-index"
458481checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
459482
483[[package]]
484name = "once_cell"
485version = "1.21.4"
486source = "registry+https://github.com/rust-lang/crates.io-index"
487checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
488
460489[[package]]
461490name = "once_cell_polyfill"
462491version = "1.70.2"
......@@ -529,7 +558,7 @@ checksum = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b"
529558dependencies = [
530559 "env_logger 0.11.10",
531560 "log",
532 "rand 0.10.0",
561 "rand 0.10.1",
533562]
534563
535564[[package]]
......@@ -541,6 +570,12 @@ dependencies = [
541570 "proc-macro2",
542571]
543572
573[[package]]
574name = "r-efi"
575version = "5.3.0"
576source = "registry+https://github.com/rust-lang/crates.io-index"
577checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
578
544579[[package]]
545580name = "r-efi"
546581version = "6.0.0"
......@@ -549,20 +584,19 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
549584
550585[[package]]
551586name = "rand"
552version = "0.8.5"
587version = "0.9.4"
553588source = "registry+https://github.com/rust-lang/crates.io-index"
554checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
589checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
555590dependencies = [
556 "libc",
557591 "rand_chacha",
558 "rand_core 0.6.4",
592 "rand_core 0.9.5",
559593]
560594
561595[[package]]
562596name = "rand"
563version = "0.10.0"
597version = "0.10.1"
564598source = "registry+https://github.com/rust-lang/crates.io-index"
565checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
599checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
566600dependencies = [
567601 "getrandom 0.4.2",
568602 "rand_core 0.10.0",
......@@ -570,21 +604,21 @@ dependencies = [
570604
571605[[package]]
572606name = "rand_chacha"
573version = "0.3.1"
607version = "0.9.0"
574608source = "registry+https://github.com/rust-lang/crates.io-index"
575checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
609checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
576610dependencies = [
577611 "ppv-lite86",
578 "rand_core 0.6.4",
612 "rand_core 0.9.5",
579613]
580614
581615[[package]]
582616name = "rand_core"
583version = "0.6.4"
617version = "0.9.5"
584618source = "registry+https://github.com/rust-lang/crates.io-index"
585checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
619checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
586620dependencies = [
587 "getrandom 0.2.17",
621 "getrandom 0.3.4",
588622]
589623
590624[[package]]
......@@ -648,6 +682,19 @@ version = "0.1.27"
648682source = "registry+https://github.com/rust-lang/crates.io-index"
649683checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
650684
685[[package]]
686name = "rustix"
687version = "1.1.4"
688source = "registry+https://github.com/rust-lang/crates.io-index"
689checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
690dependencies = [
691 "bitflags",
692 "errno",
693 "libc",
694 "linux-raw-sys",
695 "windows-sys",
696]
697
651698[[package]]
652699name = "ryu"
653700version = "1.0.23"
......@@ -787,11 +834,19 @@ dependencies = [
787834 "walkdir",
788835]
789836
837[[package]]
838name = "stdarch-gen-common"
839version = "0.1.0"
840dependencies = [
841 "tempfile",
842]
843
790844[[package]]
791845name = "stdarch-gen-hexagon"
792846version = "0.1.0"
793847dependencies = [
794848 "regex",
849 "stdarch-gen-common",
795850]
796851
797852[[package]]
......@@ -805,7 +860,7 @@ dependencies = [
805860name = "stdarch-gen-loongarch"
806861version = "0.1.0"
807862dependencies = [
808 "rand 0.8.5",
863 "rand 0.9.4",
809864]
810865
811866[[package]]
......@@ -838,7 +893,7 @@ version = "0.0.0"
838893dependencies = [
839894 "core_arch",
840895 "quickcheck",
841 "rand 0.8.5",
896 "rand 0.9.4",
842897]
843898
844899[[package]]
......@@ -864,6 +919,19 @@ version = "0.6.18"
864919source = "registry+https://github.com/rust-lang/crates.io-index"
865920checksum = "43d0e35dc7d73976a53c7e6d7d177ef804a0c0ee774ec77bcc520c2216fd7cbe"
866921
922[[package]]
923name = "tempfile"
924version = "3.27.0"
925source = "registry+https://github.com/rust-lang/crates.io-index"
926checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
927dependencies = [
928 "fastrand",
929 "getrandom 0.4.2",
930 "once_cell",
931 "rustix",
932 "windows-sys",
933]
934
867935[[package]]
868936name = "termcolor"
869937version = "1.4.1"
......@@ -921,12 +989,6 @@ dependencies = [
921989 "winapi-util",
922990]
923991
924[[package]]
925name = "wasi"
926version = "0.11.1+wasi-snapshot-preview1"
927source = "registry+https://github.com/rust-lang/crates.io-index"
928checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
929
930992[[package]]
931993name = "wasip2"
932994version = "1.0.2+wasi-0.2.9"
library/stdarch/ci/intrinsic-test.sh+19-12
......@@ -1,13 +1,19 @@
11#!/usr/bin/env sh
22
3set -ex
4
53if [ $# -lt 2 ]; then
6 >&2 echo "Usage: $0 <TARGET> <CC>"
4 >&2 echo "Usage: $0 <TARGET> <CC> <..args for \`cargo test\`..>"
75 exit 1
86fi
97
10case ${2} in
8set -ex
9
10# Pop both arguments and leave "$@" as containing args to be forwarded to `cargo test`
11TARGET="$1"
12shift
13CC_KIND="$1"
14shift
15
16case ${CC_KIND} in
1117 clang)
1218 export CC="${CLANG_PATH}"
1319 CC_ARG_STYLE=clang
......@@ -22,7 +28,7 @@ case ${2} in
2228 CC_ARG_STYLE=clang
2329 ;;
2430 *)
25 >&2 echo "Unknown compiler: ${2}"
31 >&2 echo "Unknown compiler: ${CC_KIND}"
2632 exit 1
2733 ;;
2834esac
......@@ -35,7 +41,7 @@ echo "PROFILE=${PROFILE}"
3541
3642INTRINSIC_TEST="--manifest-path=crates/intrinsic-test/Cargo.toml"
3743
38case ${1} in
44case ${TARGET} in
3945 aarch64_be*)
4046 export CFLAGS="-I${AARCH64_BE_TOOLCHAIN}/aarch64_be-none-linux-gnu/libc/usr/include --sysroot={AARCH64_BE_TOOLCHAIN}/aarch64_be-none-linux-gnu/libc -Wno-nonportable-vector-initialization"
4147 ARCH=aarch64_be
......@@ -60,24 +66,25 @@ case ${1} in
6066
6167esac
6268
63case "${1}" in
69case "${TARGET}" in
6470 x86_64-unknown-linux-gnu*)
6571 env -u CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER \
6672 cargo run "${INTRINSIC_TEST}" --release \
6773 --bin intrinsic-test -- intrinsics_data/x86-intel.xml \
6874 --skip "crates/intrinsic-test/missing_${ARCH}_common.txt" \
69 --skip "crates/intrinsic-test/missing_${ARCH}_${2}.txt" \
70 --target "${1}" \
75 --skip "crates/intrinsic-test/missing_${ARCH}_${CC_KIND}.txt" \
76 --target "${TARGET}" \
7177 --cc-arg-style "${CC_ARG_STYLE}"
7278 ;;
7379 *)
7480 cargo run "${INTRINSIC_TEST}" --release \
7581 --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \
7682 --skip "crates/intrinsic-test/missing_${ARCH}_common.txt" \
77 --skip "crates/intrinsic-test/missing_${ARCH}_${2}.txt" \
78 --target "${1}" \
83 --skip "crates/intrinsic-test/missing_${ARCH}_${CC_KIND}.txt" \
84 --target "${TARGET}" \
7985 --cc-arg-style "${CC_ARG_STYLE}"
8086 ;;
8187esac
8288
83cargo test --manifest-path=rust_programs/Cargo.toml --target "${1}" --profile "${PROFILE}" --tests
89cargo test --manifest-path=rust_programs/Cargo.toml --target "${TARGET}" --profile "${PROFILE}" \
90 --tests "$@"
library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs+1-1
......@@ -11903,7 +11903,7 @@ pub unsafe fn vluti4q_lane_s8<const LANE: i32>(a: int8x16_t, b: uint8x8_t) -> in
1190311903 unsafe extern "unadjusted" {
1190411904 #[cfg_attr(
1190511905 any(target_arch = "aarch64", target_arch = "arm64ec"),
11906 link_name = "llvm.aarch64.neon.vluti4q.lane.v8i8"
11906 link_name = "llvm.aarch64.neon.vluti4q.lane.v16i8"
1190711907 )]
1190811908 fn _vluti4q_lane_s8(a: int8x16_t, b: uint8x8_t, n: i32) -> int8x16_t;
1190911909 }
library/stdarch/crates/core_arch/src/aarch64/prefetch.rs+1-1
......@@ -2,7 +2,7 @@
22use stdarch_test::assert_instr;
33
44unsafe extern "unadjusted" {
5 #[link_name = "llvm.prefetch"]
5 #[link_name = "llvm.prefetch.p0"]
66 fn prefetch(p: *const i8, rw: i32, loc: i32, ty: i32);
77}
88
library/stdarch/crates/core_arch/src/aarch64/sve/generated.rs+315-291
......@@ -1844,7 +1844,7 @@ pub fn svadrd_u64base_u64index(bases: svuint64_t, indices: svuint64_t) -> svuint
18441844#[cfg_attr(test, assert_instr(and))]
18451845pub fn svand_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
18461846 unsafe extern "unadjusted" {
1847 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.and.z.nvx16i1")]
1847 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.and.z.nxv16i1")]
18481848 fn _svand_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t;
18491849 }
18501850 unsafe { _svand_b_z(pg, op1, op2) }
......@@ -2936,7 +2936,7 @@ pub fn svasrd_n_s64_z<const IMM2: i32>(pg: svbool_t, op1: svint64_t) -> svint64_
29362936#[cfg_attr(test, assert_instr(bic))]
29372937pub fn svbic_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
29382938 unsafe extern "unadjusted" {
2939 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.bic.z.nvx16i1")]
2939 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.bic.z.nxv16i1")]
29402940 fn _svbic_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t;
29412941 }
29422942 unsafe { _svbic_b_z(pg, op1, op2) }
......@@ -4560,7 +4560,7 @@ pub fn svcmla_lane_f32<const IMM_INDEX: i32, const IMM_ROTATION: i32>(
45604560 unsafe extern "unadjusted" {
45614561 #[cfg_attr(
45624562 target_arch = "aarch64",
4563 link_name = "llvm.aarch64.sve.fcmla.lane.x.nxv4f32"
4563 link_name = "llvm.aarch64.sve.fcmla.lane.nxv4f32"
45644564 )]
45654565 fn _svcmla_lane_f32(
45664566 op1: svfloat32_t,
......@@ -7658,7 +7658,10 @@ pub fn svcvt_f64_f32_z(pg: svbool_t, op: svfloat32_t) -> svfloat64_t {
76587658#[cfg_attr(test, assert_instr(scvtf))]
76597659pub fn svcvt_f32_s32_m(inactive: svfloat32_t, pg: svbool_t, op: svint32_t) -> svfloat32_t {
76607660 unsafe extern "unadjusted" {
7661 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.scvtf.f32i32")]
7661 #[cfg_attr(
7662 target_arch = "aarch64",
7663 link_name = "llvm.aarch64.sve.scvtf.nxv4f32.nxv4i32"
7664 )]
76627665 fn _svcvt_f32_s32_m(inactive: svfloat32_t, pg: svbool4_t, op: svint32_t) -> svfloat32_t;
76637666 }
76647667 unsafe { _svcvt_f32_s32_m(inactive, pg.sve_into(), op) }
......@@ -7682,66 +7685,137 @@ pub fn svcvt_f32_s32_z(pg: svbool_t, op: svint32_t) -> svfloat32_t {
76827685 svcvt_f32_s32_m(svdup_n_f32(0.0), pg, op)
76837686}
76847687#[doc = "Floating-point convert"]
7685#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_m)"]
7688#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_m)"]
7689#[inline]
7690#[target_feature(enable = "sve")]
7691#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7692#[cfg_attr(test, assert_instr(ucvtf))]
7693pub fn svcvt_f32_u32_m(inactive: svfloat32_t, pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7694 unsafe extern "unadjusted" {
7695 #[cfg_attr(
7696 target_arch = "aarch64",
7697 link_name = "llvm.aarch64.sve.ucvtf.nxv4f32.nxv4i32"
7698 )]
7699 fn _svcvt_f32_u32_m(inactive: svfloat32_t, pg: svbool4_t, op: svint32_t) -> svfloat32_t;
7700 }
7701 unsafe { _svcvt_f32_u32_m(inactive, pg.sve_into(), op.as_signed()) }
7702}
7703#[doc = "Floating-point convert"]
7704#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_x)"]
7705#[inline]
7706#[target_feature(enable = "sve")]
7707#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7708#[cfg_attr(test, assert_instr(ucvtf))]
7709pub fn svcvt_f32_u32_x(pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7710 unsafe { svcvt_f32_u32_m(transmute_unchecked(op), pg, op) }
7711}
7712#[doc = "Floating-point convert"]
7713#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_z)"]
7714#[inline]
7715#[target_feature(enable = "sve")]
7716#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7717#[cfg_attr(test, assert_instr(ucvtf))]
7718pub fn svcvt_f32_u32_z(pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7719 svcvt_f32_u32_m(svdup_n_f32(0.0), pg, op)
7720}
7721#[doc = "Floating-point convert"]
7722#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_m)"]
76867723#[inline]
76877724#[target_feature(enable = "sve")]
76887725#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
76897726#[cfg_attr(test, assert_instr(scvtf))]
7690pub fn svcvt_f32_s64_m(inactive: svfloat32_t, pg: svbool_t, op: svint64_t) -> svfloat32_t {
7727pub fn svcvt_f64_s64_m(inactive: svfloat64_t, pg: svbool_t, op: svint64_t) -> svfloat64_t {
76917728 unsafe extern "unadjusted" {
7692 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.scvtf.f32i64")]
7693 fn _svcvt_f32_s64_m(inactive: svfloat32_t, pg: svbool2_t, op: svint64_t) -> svfloat32_t;
7729 #[cfg_attr(
7730 target_arch = "aarch64",
7731 link_name = "llvm.aarch64.sve.scvtf.nxv2f64.nxv2i64"
7732 )]
7733 fn _svcvt_f64_s64_m(inactive: svfloat64_t, pg: svbool2_t, op: svint64_t) -> svfloat64_t;
76947734 }
7695 unsafe { _svcvt_f32_s64_m(inactive, pg.sve_into(), op) }
7735 unsafe { _svcvt_f64_s64_m(inactive, pg.sve_into(), op) }
76967736}
76977737#[doc = "Floating-point convert"]
7698#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_x)"]
7738#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_x)"]
76997739#[inline]
77007740#[target_feature(enable = "sve")]
77017741#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
77027742#[cfg_attr(test, assert_instr(scvtf))]
7703pub fn svcvt_f32_s64_x(pg: svbool_t, op: svint64_t) -> svfloat32_t {
7704 unsafe { svcvt_f32_s64_m(transmute_unchecked(op), pg, op) }
7743pub fn svcvt_f64_s64_x(pg: svbool_t, op: svint64_t) -> svfloat64_t {
7744 unsafe { svcvt_f64_s64_m(transmute_unchecked(op), pg, op) }
77057745}
77067746#[doc = "Floating-point convert"]
7707#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_z)"]
7747#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_z)"]
77087748#[inline]
77097749#[target_feature(enable = "sve")]
77107750#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
77117751#[cfg_attr(test, assert_instr(scvtf))]
7712pub fn svcvt_f32_s64_z(pg: svbool_t, op: svint64_t) -> svfloat32_t {
7713 svcvt_f32_s64_m(svdup_n_f32(0.0), pg, op)
7752pub fn svcvt_f64_s64_z(pg: svbool_t, op: svint64_t) -> svfloat64_t {
7753 svcvt_f64_s64_m(svdup_n_f64(0.0), pg, op)
77147754}
77157755#[doc = "Floating-point convert"]
7716#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_m)"]
7756#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_m)"]
77177757#[inline]
77187758#[target_feature(enable = "sve")]
77197759#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
77207760#[cfg_attr(test, assert_instr(ucvtf))]
7721pub fn svcvt_f32_u32_m(inactive: svfloat32_t, pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7761pub fn svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool_t, op: svuint64_t) -> svfloat64_t {
77227762 unsafe extern "unadjusted" {
7723 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.ucvtf.f32i32")]
7724 fn _svcvt_f32_u32_m(inactive: svfloat32_t, pg: svbool4_t, op: svint32_t) -> svfloat32_t;
7763 #[cfg_attr(
7764 target_arch = "aarch64",
7765 link_name = "llvm.aarch64.sve.ucvtf.nxv2f64.nxv2i64"
7766 )]
7767 fn _svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool2_t, op: svint64_t) -> svfloat64_t;
77257768 }
7726 unsafe { _svcvt_f32_u32_m(inactive, pg.sve_into(), op.as_signed()) }
7769 unsafe { _svcvt_f64_u64_m(inactive, pg.sve_into(), op.as_signed()) }
77277770}
77287771#[doc = "Floating-point convert"]
7729#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_x)"]
7772#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_x)"]
77307773#[inline]
77317774#[target_feature(enable = "sve")]
77327775#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
77337776#[cfg_attr(test, assert_instr(ucvtf))]
7734pub fn svcvt_f32_u32_x(pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7735 unsafe { svcvt_f32_u32_m(transmute_unchecked(op), pg, op) }
7777pub fn svcvt_f64_u64_x(pg: svbool_t, op: svuint64_t) -> svfloat64_t {
7778 unsafe { svcvt_f64_u64_m(transmute_unchecked(op), pg, op) }
77367779}
77377780#[doc = "Floating-point convert"]
7738#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u32]_z)"]
7781#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_z)"]
77397782#[inline]
77407783#[target_feature(enable = "sve")]
77417784#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
77427785#[cfg_attr(test, assert_instr(ucvtf))]
7743pub fn svcvt_f32_u32_z(pg: svbool_t, op: svuint32_t) -> svfloat32_t {
7744 svcvt_f32_u32_m(svdup_n_f32(0.0), pg, op)
7786pub fn svcvt_f64_u64_z(pg: svbool_t, op: svuint64_t) -> svfloat64_t {
7787 svcvt_f64_u64_m(svdup_n_f64(0.0), pg, op)
7788}
7789#[doc = "Floating-point convert"]
7790#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_m)"]
7791#[inline]
7792#[target_feature(enable = "sve")]
7793#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7794#[cfg_attr(test, assert_instr(scvtf))]
7795pub fn svcvt_f32_s64_m(inactive: svfloat32_t, pg: svbool_t, op: svint64_t) -> svfloat32_t {
7796 unsafe extern "unadjusted" {
7797 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.scvtf.f32i64")]
7798 fn _svcvt_f32_s64_m(inactive: svfloat32_t, pg: svbool2_t, op: svint64_t) -> svfloat32_t;
7799 }
7800 unsafe { _svcvt_f32_s64_m(inactive, pg.sve_into(), op) }
7801}
7802#[doc = "Floating-point convert"]
7803#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_x)"]
7804#[inline]
7805#[target_feature(enable = "sve")]
7806#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7807#[cfg_attr(test, assert_instr(scvtf))]
7808pub fn svcvt_f32_s64_x(pg: svbool_t, op: svint64_t) -> svfloat32_t {
7809 unsafe { svcvt_f32_s64_m(transmute_unchecked(op), pg, op) }
7810}
7811#[doc = "Floating-point convert"]
7812#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_s64]_z)"]
7813#[inline]
7814#[target_feature(enable = "sve")]
7815#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7816#[cfg_attr(test, assert_instr(scvtf))]
7817pub fn svcvt_f32_s64_z(pg: svbool_t, op: svint64_t) -> svfloat32_t {
7818 svcvt_f32_s64_m(svdup_n_f32(0.0), pg, op)
77457819}
77467820#[doc = "Floating-point convert"]
77477821#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f32[_u64]_m)"]
......@@ -7806,37 +7880,6 @@ pub fn svcvt_f64_s32_z(pg: svbool_t, op: svint32_t) -> svfloat64_t {
78067880 svcvt_f64_s32_m(svdup_n_f64(0.0), pg, op)
78077881}
78087882#[doc = "Floating-point convert"]
7809#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_m)"]
7810#[inline]
7811#[target_feature(enable = "sve")]
7812#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7813#[cfg_attr(test, assert_instr(scvtf))]
7814pub fn svcvt_f64_s64_m(inactive: svfloat64_t, pg: svbool_t, op: svint64_t) -> svfloat64_t {
7815 unsafe extern "unadjusted" {
7816 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.scvtf.f64i64")]
7817 fn _svcvt_f64_s64_m(inactive: svfloat64_t, pg: svbool2_t, op: svint64_t) -> svfloat64_t;
7818 }
7819 unsafe { _svcvt_f64_s64_m(inactive, pg.sve_into(), op) }
7820}
7821#[doc = "Floating-point convert"]
7822#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_x)"]
7823#[inline]
7824#[target_feature(enable = "sve")]
7825#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7826#[cfg_attr(test, assert_instr(scvtf))]
7827pub fn svcvt_f64_s64_x(pg: svbool_t, op: svint64_t) -> svfloat64_t {
7828 unsafe { svcvt_f64_s64_m(transmute_unchecked(op), pg, op) }
7829}
7830#[doc = "Floating-point convert"]
7831#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_s64]_z)"]
7832#[inline]
7833#[target_feature(enable = "sve")]
7834#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7835#[cfg_attr(test, assert_instr(scvtf))]
7836pub fn svcvt_f64_s64_z(pg: svbool_t, op: svint64_t) -> svfloat64_t {
7837 svcvt_f64_s64_m(svdup_n_f64(0.0), pg, op)
7838}
7839#[doc = "Floating-point convert"]
78407883#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u32]_m)"]
78417884#[inline]
78427885#[target_feature(enable = "sve")]
......@@ -7868,190 +7911,202 @@ pub fn svcvt_f64_u32_z(pg: svbool_t, op: svuint32_t) -> svfloat64_t {
78687911 svcvt_f64_u32_m(svdup_n_f64(0.0), pg, op)
78697912}
78707913#[doc = "Floating-point convert"]
7871#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_m)"]
7914#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_m)"]
78727915#[inline]
78737916#[target_feature(enable = "sve")]
78747917#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7875#[cfg_attr(test, assert_instr(ucvtf))]
7876pub fn svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool_t, op: svuint64_t) -> svfloat64_t {
7918#[cfg_attr(test, assert_instr(fcvtzs))]
7919pub fn svcvt_s32_f32_m(inactive: svint32_t, pg: svbool_t, op: svfloat32_t) -> svint32_t {
78777920 unsafe extern "unadjusted" {
7878 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.ucvtf.f64i64")]
7879 fn _svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool2_t, op: svint64_t) -> svfloat64_t;
7921 #[cfg_attr(
7922 target_arch = "aarch64",
7923 link_name = "llvm.aarch64.sve.fcvtzs.nxv4i32.nxv4f32"
7924 )]
7925 fn _svcvt_s32_f32_m(inactive: svint32_t, pg: svbool4_t, op: svfloat32_t) -> svint32_t;
78807926 }
7881 unsafe { _svcvt_f64_u64_m(inactive, pg.sve_into(), op.as_signed()) }
7927 unsafe { _svcvt_s32_f32_m(inactive, pg.sve_into(), op) }
78827928}
78837929#[doc = "Floating-point convert"]
7884#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_x)"]
7930#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_x)"]
78857931#[inline]
78867932#[target_feature(enable = "sve")]
78877933#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7888#[cfg_attr(test, assert_instr(ucvtf))]
7889pub fn svcvt_f64_u64_x(pg: svbool_t, op: svuint64_t) -> svfloat64_t {
7890 unsafe { svcvt_f64_u64_m(transmute_unchecked(op), pg, op) }
7934#[cfg_attr(test, assert_instr(fcvtzs))]
7935pub fn svcvt_s32_f32_x(pg: svbool_t, op: svfloat32_t) -> svint32_t {
7936 unsafe { svcvt_s32_f32_m(transmute_unchecked(op), pg, op) }
78917937}
78927938#[doc = "Floating-point convert"]
7893#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u64]_z)"]
7939#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_z)"]
78947940#[inline]
78957941#[target_feature(enable = "sve")]
78967942#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7897#[cfg_attr(test, assert_instr(ucvtf))]
7898pub fn svcvt_f64_u64_z(pg: svbool_t, op: svuint64_t) -> svfloat64_t {
7899 svcvt_f64_u64_m(svdup_n_f64(0.0), pg, op)
7943#[cfg_attr(test, assert_instr(fcvtzs))]
7944pub fn svcvt_s32_f32_z(pg: svbool_t, op: svfloat32_t) -> svint32_t {
7945 svcvt_s32_f32_m(svdup_n_s32(0), pg, op)
79007946}
79017947#[doc = "Floating-point convert"]
7902#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_m)"]
7948#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_m)"]
79037949#[inline]
79047950#[target_feature(enable = "sve")]
79057951#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
79067952#[cfg_attr(test, assert_instr(fcvtzs))]
7907pub fn svcvt_s32_f32_m(inactive: svint32_t, pg: svbool_t, op: svfloat32_t) -> svint32_t {
7953pub fn svcvt_s64_f64_m(inactive: svint64_t, pg: svbool_t, op: svfloat64_t) -> svint64_t {
79087954 unsafe extern "unadjusted" {
7909 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i32f32")]
7910 fn _svcvt_s32_f32_m(inactive: svint32_t, pg: svbool4_t, op: svfloat32_t) -> svint32_t;
7955 #[cfg_attr(
7956 target_arch = "aarch64",
7957 link_name = "llvm.aarch64.sve.fcvtzs.nxv2i64.nxv2f64"
7958 )]
7959 fn _svcvt_s64_f64_m(inactive: svint64_t, pg: svbool2_t, op: svfloat64_t) -> svint64_t;
79117960 }
7912 unsafe { _svcvt_s32_f32_m(inactive, pg.sve_into(), op) }
7961 unsafe { _svcvt_s64_f64_m(inactive, pg.sve_into(), op) }
79137962}
79147963#[doc = "Floating-point convert"]
7915#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_x)"]
7964#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_x)"]
79167965#[inline]
79177966#[target_feature(enable = "sve")]
79187967#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
79197968#[cfg_attr(test, assert_instr(fcvtzs))]
7920pub fn svcvt_s32_f32_x(pg: svbool_t, op: svfloat32_t) -> svint32_t {
7921 unsafe { svcvt_s32_f32_m(transmute_unchecked(op), pg, op) }
7969pub fn svcvt_s64_f64_x(pg: svbool_t, op: svfloat64_t) -> svint64_t {
7970 unsafe { svcvt_s64_f64_m(transmute_unchecked(op), pg, op) }
79227971}
79237972#[doc = "Floating-point convert"]
7924#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f32]_z)"]
7973#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_z)"]
79257974#[inline]
79267975#[target_feature(enable = "sve")]
79277976#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
79287977#[cfg_attr(test, assert_instr(fcvtzs))]
7929pub fn svcvt_s32_f32_z(pg: svbool_t, op: svfloat32_t) -> svint32_t {
7930 svcvt_s32_f32_m(svdup_n_s32(0), pg, op)
7978pub fn svcvt_s64_f64_z(pg: svbool_t, op: svfloat64_t) -> svint64_t {
7979 svcvt_s64_f64_m(svdup_n_s64(0), pg, op)
79317980}
79327981#[doc = "Floating-point convert"]
7933#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_m)"]
7982#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_m)"]
79347983#[inline]
79357984#[target_feature(enable = "sve")]
79367985#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7937#[cfg_attr(test, assert_instr(fcvtzs))]
7938pub fn svcvt_s32_f64_m(inactive: svint32_t, pg: svbool_t, op: svfloat64_t) -> svint32_t {
7986#[cfg_attr(test, assert_instr(fcvtzu))]
7987pub fn svcvt_u32_f32_m(inactive: svuint32_t, pg: svbool_t, op: svfloat32_t) -> svuint32_t {
79397988 unsafe extern "unadjusted" {
7940 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i32f64")]
7941 fn _svcvt_s32_f64_m(inactive: svint32_t, pg: svbool2_t, op: svfloat64_t) -> svint32_t;
7989 #[cfg_attr(
7990 target_arch = "aarch64",
7991 link_name = "llvm.aarch64.sve.fcvtzu.nxv4i32.nxv4f32"
7992 )]
7993 fn _svcvt_u32_f32_m(inactive: svint32_t, pg: svbool4_t, op: svfloat32_t) -> svint32_t;
79427994 }
7943 unsafe { _svcvt_s32_f64_m(inactive, pg.sve_into(), op) }
7995 unsafe { _svcvt_u32_f32_m(inactive.as_signed(), pg.sve_into(), op).as_unsigned() }
79447996}
79457997#[doc = "Floating-point convert"]
7946#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_x)"]
7998#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_x)"]
79477999#[inline]
79488000#[target_feature(enable = "sve")]
79498001#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7950#[cfg_attr(test, assert_instr(fcvtzs))]
7951pub fn svcvt_s32_f64_x(pg: svbool_t, op: svfloat64_t) -> svint32_t {
7952 unsafe { svcvt_s32_f64_m(transmute_unchecked(op), pg, op) }
8002#[cfg_attr(test, assert_instr(fcvtzu))]
8003pub fn svcvt_u32_f32_x(pg: svbool_t, op: svfloat32_t) -> svuint32_t {
8004 unsafe { svcvt_u32_f32_m(transmute_unchecked(op), pg, op) }
79538005}
79548006#[doc = "Floating-point convert"]
7955#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_z)"]
8007#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_z)"]
79568008#[inline]
79578009#[target_feature(enable = "sve")]
79588010#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7959#[cfg_attr(test, assert_instr(fcvtzs))]
7960pub fn svcvt_s32_f64_z(pg: svbool_t, op: svfloat64_t) -> svint32_t {
7961 svcvt_s32_f64_m(svdup_n_s32(0), pg, op)
8011#[cfg_attr(test, assert_instr(fcvtzu))]
8012pub fn svcvt_u32_f32_z(pg: svbool_t, op: svfloat32_t) -> svuint32_t {
8013 svcvt_u32_f32_m(svdup_n_u32(0), pg, op)
79628014}
79638015#[doc = "Floating-point convert"]
7964#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_m)"]
8016#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_m)"]
79658017#[inline]
79668018#[target_feature(enable = "sve")]
79678019#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7968#[cfg_attr(test, assert_instr(fcvtzs))]
7969pub fn svcvt_s64_f32_m(inactive: svint64_t, pg: svbool_t, op: svfloat32_t) -> svint64_t {
8020#[cfg_attr(test, assert_instr(fcvtzu))]
8021pub fn svcvt_u64_f64_m(inactive: svuint64_t, pg: svbool_t, op: svfloat64_t) -> svuint64_t {
79708022 unsafe extern "unadjusted" {
7971 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i64f32")]
7972 fn _svcvt_s64_f32_m(inactive: svint64_t, pg: svbool2_t, op: svfloat32_t) -> svint64_t;
8023 #[cfg_attr(
8024 target_arch = "aarch64",
8025 link_name = "llvm.aarch64.sve.fcvtzu.nxv2i64.nxv2f64"
8026 )]
8027 fn _svcvt_u64_f64_m(inactive: svint64_t, pg: svbool2_t, op: svfloat64_t) -> svint64_t;
79738028 }
7974 unsafe { _svcvt_s64_f32_m(inactive, pg.sve_into(), op) }
8029 unsafe { _svcvt_u64_f64_m(inactive.as_signed(), pg.sve_into(), op).as_unsigned() }
79758030}
79768031#[doc = "Floating-point convert"]
7977#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_x)"]
8032#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_x)"]
79788033#[inline]
79798034#[target_feature(enable = "sve")]
79808035#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7981#[cfg_attr(test, assert_instr(fcvtzs))]
7982pub fn svcvt_s64_f32_x(pg: svbool_t, op: svfloat32_t) -> svint64_t {
7983 unsafe { svcvt_s64_f32_m(transmute_unchecked(op), pg, op) }
8036#[cfg_attr(test, assert_instr(fcvtzu))]
8037pub fn svcvt_u64_f64_x(pg: svbool_t, op: svfloat64_t) -> svuint64_t {
8038 unsafe { svcvt_u64_f64_m(transmute_unchecked(op), pg, op) }
79848039}
79858040#[doc = "Floating-point convert"]
7986#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_z)"]
8041#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_z)"]
79878042#[inline]
79888043#[target_feature(enable = "sve")]
79898044#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
7990#[cfg_attr(test, assert_instr(fcvtzs))]
7991pub fn svcvt_s64_f32_z(pg: svbool_t, op: svfloat32_t) -> svint64_t {
7992 svcvt_s64_f32_m(svdup_n_s64(0), pg, op)
8045#[cfg_attr(test, assert_instr(fcvtzu))]
8046pub fn svcvt_u64_f64_z(pg: svbool_t, op: svfloat64_t) -> svuint64_t {
8047 svcvt_u64_f64_m(svdup_n_u64(0), pg, op)
79938048}
79948049#[doc = "Floating-point convert"]
7995#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_m)"]
8050#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_m)"]
79968051#[inline]
79978052#[target_feature(enable = "sve")]
79988053#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
79998054#[cfg_attr(test, assert_instr(fcvtzs))]
8000pub fn svcvt_s64_f64_m(inactive: svint64_t, pg: svbool_t, op: svfloat64_t) -> svint64_t {
8055pub fn svcvt_s32_f64_m(inactive: svint32_t, pg: svbool_t, op: svfloat64_t) -> svint32_t {
80018056 unsafe extern "unadjusted" {
8002 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i64f64")]
8003 fn _svcvt_s64_f64_m(inactive: svint64_t, pg: svbool2_t, op: svfloat64_t) -> svint64_t;
8057 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i32f64")]
8058 fn _svcvt_s32_f64_m(inactive: svint32_t, pg: svbool2_t, op: svfloat64_t) -> svint32_t;
80048059 }
8005 unsafe { _svcvt_s64_f64_m(inactive, pg.sve_into(), op) }
8060 unsafe { _svcvt_s32_f64_m(inactive, pg.sve_into(), op) }
80068061}
80078062#[doc = "Floating-point convert"]
8008#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_x)"]
8063#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_x)"]
80098064#[inline]
80108065#[target_feature(enable = "sve")]
80118066#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
80128067#[cfg_attr(test, assert_instr(fcvtzs))]
8013pub fn svcvt_s64_f64_x(pg: svbool_t, op: svfloat64_t) -> svint64_t {
8014 unsafe { svcvt_s64_f64_m(transmute_unchecked(op), pg, op) }
8068pub fn svcvt_s32_f64_x(pg: svbool_t, op: svfloat64_t) -> svint32_t {
8069 unsafe { svcvt_s32_f64_m(transmute_unchecked(op), pg, op) }
80158070}
80168071#[doc = "Floating-point convert"]
8017#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f64]_z)"]
8072#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s32[_f64]_z)"]
80188073#[inline]
80198074#[target_feature(enable = "sve")]
80208075#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
80218076#[cfg_attr(test, assert_instr(fcvtzs))]
8022pub fn svcvt_s64_f64_z(pg: svbool_t, op: svfloat64_t) -> svint64_t {
8023 svcvt_s64_f64_m(svdup_n_s64(0), pg, op)
8077pub fn svcvt_s32_f64_z(pg: svbool_t, op: svfloat64_t) -> svint32_t {
8078 svcvt_s32_f64_m(svdup_n_s32(0), pg, op)
80248079}
80258080#[doc = "Floating-point convert"]
8026#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_m)"]
8081#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_m)"]
80278082#[inline]
80288083#[target_feature(enable = "sve")]
80298084#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8030#[cfg_attr(test, assert_instr(fcvtzu))]
8031pub fn svcvt_u32_f32_m(inactive: svuint32_t, pg: svbool_t, op: svfloat32_t) -> svuint32_t {
8085#[cfg_attr(test, assert_instr(fcvtzs))]
8086pub fn svcvt_s64_f32_m(inactive: svint64_t, pg: svbool_t, op: svfloat32_t) -> svint64_t {
80328087 unsafe extern "unadjusted" {
8033 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzu.i32f32")]
8034 fn _svcvt_u32_f32_m(inactive: svint32_t, pg: svbool4_t, op: svfloat32_t) -> svint32_t;
8088 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzs.i64f32")]
8089 fn _svcvt_s64_f32_m(inactive: svint64_t, pg: svbool2_t, op: svfloat32_t) -> svint64_t;
80358090 }
8036 unsafe { _svcvt_u32_f32_m(inactive.as_signed(), pg.sve_into(), op).as_unsigned() }
8091 unsafe { _svcvt_s64_f32_m(inactive, pg.sve_into(), op) }
80378092}
80388093#[doc = "Floating-point convert"]
8039#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_x)"]
8094#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_x)"]
80408095#[inline]
80418096#[target_feature(enable = "sve")]
80428097#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8043#[cfg_attr(test, assert_instr(fcvtzu))]
8044pub fn svcvt_u32_f32_x(pg: svbool_t, op: svfloat32_t) -> svuint32_t {
8045 unsafe { svcvt_u32_f32_m(transmute_unchecked(op), pg, op) }
8098#[cfg_attr(test, assert_instr(fcvtzs))]
8099pub fn svcvt_s64_f32_x(pg: svbool_t, op: svfloat32_t) -> svint64_t {
8100 unsafe { svcvt_s64_f32_m(transmute_unchecked(op), pg, op) }
80468101}
80478102#[doc = "Floating-point convert"]
8048#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f32]_z)"]
8103#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_s64[_f32]_z)"]
80498104#[inline]
80508105#[target_feature(enable = "sve")]
80518106#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8052#[cfg_attr(test, assert_instr(fcvtzu))]
8053pub fn svcvt_u32_f32_z(pg: svbool_t, op: svfloat32_t) -> svuint32_t {
8054 svcvt_u32_f32_m(svdup_n_u32(0), pg, op)
8107#[cfg_attr(test, assert_instr(fcvtzs))]
8108pub fn svcvt_s64_f32_z(pg: svbool_t, op: svfloat32_t) -> svint64_t {
8109 svcvt_s64_f32_m(svdup_n_s64(0), pg, op)
80558110}
80568111#[doc = "Floating-point convert"]
80578112#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u32[_f64]_m)"]
......@@ -8115,37 +8170,6 @@ pub fn svcvt_u64_f32_x(pg: svbool_t, op: svfloat32_t) -> svuint64_t {
81158170pub fn svcvt_u64_f32_z(pg: svbool_t, op: svfloat32_t) -> svuint64_t {
81168171 svcvt_u64_f32_m(svdup_n_u64(0), pg, op)
81178172}
8118#[doc = "Floating-point convert"]
8119#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_m)"]
8120#[inline]
8121#[target_feature(enable = "sve")]
8122#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8123#[cfg_attr(test, assert_instr(fcvtzu))]
8124pub fn svcvt_u64_f64_m(inactive: svuint64_t, pg: svbool_t, op: svfloat64_t) -> svuint64_t {
8125 unsafe extern "unadjusted" {
8126 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fcvtzu.i64f64")]
8127 fn _svcvt_u64_f64_m(inactive: svint64_t, pg: svbool2_t, op: svfloat64_t) -> svint64_t;
8128 }
8129 unsafe { _svcvt_u64_f64_m(inactive.as_signed(), pg.sve_into(), op).as_unsigned() }
8130}
8131#[doc = "Floating-point convert"]
8132#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_x)"]
8133#[inline]
8134#[target_feature(enable = "sve")]
8135#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8136#[cfg_attr(test, assert_instr(fcvtzu))]
8137pub fn svcvt_u64_f64_x(pg: svbool_t, op: svfloat64_t) -> svuint64_t {
8138 unsafe { svcvt_u64_f64_m(transmute_unchecked(op), pg, op) }
8139}
8140#[doc = "Floating-point convert"]
8141#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_u64[_f64]_z)"]
8142#[inline]
8143#[target_feature(enable = "sve")]
8144#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
8145#[cfg_attr(test, assert_instr(fcvtzu))]
8146pub fn svcvt_u64_f64_z(pg: svbool_t, op: svfloat64_t) -> svuint64_t {
8147 svcvt_u64_f64_m(svdup_n_u64(0), pg, op)
8148}
81498173#[doc = "Divide"]
81508174#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svdiv[_f32]_m)"]
81518175#[inline]
......@@ -10041,7 +10065,7 @@ pub fn svdupq_n_u8(
1004110065#[cfg_attr(test, assert_instr(eor))]
1004210066pub fn sveor_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
1004310067 unsafe extern "unadjusted" {
10044 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.eor.z.nvx16i1")]
10068 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.eor.z.nxv16i1")]
1004510069 fn _sveor_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t;
1004610070 }
1004710071 unsafe { _sveor_b_z(pg, op1, op2) }
......@@ -10592,7 +10616,7 @@ pub fn svexpa_f32(op: svuint32_t) -> svfloat32_t {
1059210616 unsafe extern "unadjusted" {
1059310617 #[cfg_attr(
1059410618 target_arch = "aarch64",
10595 link_name = "llvm.aarch64.sve.fexpa.x.nxv4f32 "
10619 link_name = "llvm.aarch64.sve.fexpa.x.nxv4f32"
1059610620 )]
1059710621 fn _svexpa_f32(op: svint32_t) -> svfloat32_t;
1059810622 }
......@@ -10608,7 +10632,7 @@ pub fn svexpa_f64(op: svuint64_t) -> svfloat64_t {
1060810632 unsafe extern "unadjusted" {
1060910633 #[cfg_attr(
1061010634 target_arch = "aarch64",
10611 link_name = "llvm.aarch64.sve.fexpa.x.nxv2f64 "
10635 link_name = "llvm.aarch64.sve.fexpa.x.nxv2f64"
1061210636 )]
1061310637 fn _svexpa_f64(op: svint64_t) -> svfloat64_t;
1061410638 }
......@@ -27372,7 +27396,10 @@ pub fn svmls_lane_f64<const IMM_INDEX: i32>(
2737227396#[cfg_attr(test, assert_instr(fmmla))]
2737327397pub fn svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svfloat32_t {
2737427398 unsafe extern "unadjusted" {
27375 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fmmla.nxv4f32")]
27399 #[cfg_attr(
27400 target_arch = "aarch64",
27401 link_name = "llvm.aarch64.sve.fmmla.nxv4f32.nxv4f32"
27402 )]
2737627403 fn _svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svfloat32_t;
2737727404 }
2737827405 unsafe { _svmmla_f32(op1, op2, op3) }
......@@ -27385,7 +27412,10 @@ pub fn svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svflo
2738527412#[cfg_attr(test, assert_instr(fmmla))]
2738627413pub fn svmmla_f64(op1: svfloat64_t, op2: svfloat64_t, op3: svfloat64_t) -> svfloat64_t {
2738727414 unsafe extern "unadjusted" {
27388 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.fmmla.nxv2f64")]
27415 #[cfg_attr(
27416 target_arch = "aarch64",
27417 link_name = "llvm.aarch64.sve.fmmla.nxv2f64.nxv2f64"
27418 )]
2738927419 fn _svmmla_f64(op1: svfloat64_t, op2: svfloat64_t, op3: svfloat64_t) -> svfloat64_t;
2739027420 }
2739127421 unsafe { _svmmla_f64(op1, op2, op3) }
......@@ -30261,7 +30291,7 @@ pub fn svnot_u64_z(pg: svbool_t, op: svuint64_t) -> svuint64_t {
3026130291#[cfg_attr(test, assert_instr(orn))]
3026230292pub fn svorn_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
3026330293 unsafe extern "unadjusted" {
30264 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.orn.z.nvx16i1")]
30294 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.orn.z.nxv16i1")]
3026530295 fn _svorn_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t;
3026630296 }
3026730297 unsafe { _svorn_b_z(pg, op1, op2) }
......@@ -30274,7 +30304,7 @@ pub fn svorn_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
3027430304#[cfg_attr(test, assert_instr(orr))]
3027530305pub fn svorr_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t {
3027630306 unsafe extern "unadjusted" {
30277 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.orr.z.nvx16i1")]
30307 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.orr.z.nxv16i1")]
3027830308 fn _svorr_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t;
3027930309 }
3028030310 unsafe { _svorr_b_z(pg, op1, op2) }
......@@ -34341,10 +34371,7 @@ pub fn svrecps_f64(op1: svfloat64_t, op2: svfloat64_t) -> svfloat64_t {
3434134371#[cfg_attr(test, assert_instr(frecpx))]
3434234372pub fn svrecpx_f32_m(inactive: svfloat32_t, pg: svbool_t, op: svfloat32_t) -> svfloat32_t {
3434334373 unsafe extern "unadjusted" {
34344 #[cfg_attr(
34345 target_arch = "aarch64",
34346 link_name = "llvm.aarch64.sve.frecpx.x.nxv4f32"
34347 )]
34374 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.frecpx.nxv4f32")]
3434834375 fn _svrecpx_f32_m(inactive: svfloat32_t, pg: svbool4_t, op: svfloat32_t) -> svfloat32_t;
3434934376 }
3435034377 unsafe { _svrecpx_f32_m(inactive, pg.sve_into(), op) }
......@@ -34375,10 +34402,7 @@ pub fn svrecpx_f32_z(pg: svbool_t, op: svfloat32_t) -> svfloat32_t {
3437534402#[cfg_attr(test, assert_instr(frecpx))]
3437634403pub fn svrecpx_f64_m(inactive: svfloat64_t, pg: svbool_t, op: svfloat64_t) -> svfloat64_t {
3437734404 unsafe extern "unadjusted" {
34378 #[cfg_attr(
34379 target_arch = "aarch64",
34380 link_name = "llvm.aarch64.sve.frecpx.x.nxv2f64"
34381 )]
34405 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.frecpx.nxv2f64")]
3438234406 fn _svrecpx_f64_m(inactive: svfloat64_t, pg: svbool2_t, op: svfloat64_t) -> svfloat64_t;
3438334407 }
3438434408 unsafe { _svrecpx_f64_m(inactive, pg.sve_into(), op) }
......@@ -35202,19 +35226,6 @@ pub fn svreinterpret_u64_u64(op: svuint64_t) -> svuint64_t {
3520235226 unsafe { crate::intrinsics::transmute_unchecked(op) }
3520335227}
3520435228#[doc = "Reverse all elements"]
35205#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev_b8)"]
35206#[inline]
35207#[target_feature(enable = "sve")]
35208#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
35209#[cfg_attr(test, assert_instr(rev))]
35210pub fn svrev_b8(op: svbool_t) -> svbool_t {
35211 unsafe extern "unadjusted" {
35212 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.vector.reverse.nxv16i1")]
35213 fn _svrev_b8(op: svbool_t) -> svbool_t;
35214 }
35215 unsafe { _svrev_b8(op) }
35216}
35217#[doc = "Reverse all elements"]
3521835229#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev_b16)"]
3521935230#[inline]
3522035231#[target_feature(enable = "sve")]
......@@ -35222,10 +35233,10 @@ pub fn svrev_b8(op: svbool_t) -> svbool_t {
3522235233#[cfg_attr(test, assert_instr(rev))]
3522335234pub fn svrev_b16(op: svbool_t) -> svbool_t {
3522435235 unsafe extern "unadjusted" {
35225 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.vector.reverse.nxv8i1")]
35226 fn _svrev_b16(op: svbool8_t) -> svbool8_t;
35236 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.rev.b16")]
35237 fn _svrev_b16(op: svbool_t) -> svbool_t;
3522735238 }
35228 unsafe { _svrev_b16(op.sve_into()).sve_into() }
35239 unsafe { _svrev_b16(op.sve_into()) }
3522935240}
3523035241#[doc = "Reverse all elements"]
3523135242#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev_b32)"]
......@@ -35235,10 +35246,10 @@ pub fn svrev_b16(op: svbool_t) -> svbool_t {
3523535246#[cfg_attr(test, assert_instr(rev))]
3523635247pub fn svrev_b32(op: svbool_t) -> svbool_t {
3523735248 unsafe extern "unadjusted" {
35238 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.vector.reverse.nxv4i1")]
35239 fn _svrev_b32(op: svbool4_t) -> svbool4_t;
35249 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.rev.b32")]
35250 fn _svrev_b32(op: svbool_t) -> svbool_t;
3524035251 }
35241 unsafe { _svrev_b32(op.sve_into()).sve_into() }
35252 unsafe { _svrev_b32(op.sve_into()) }
3524235253}
3524335254#[doc = "Reverse all elements"]
3524435255#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev_b64)"]
......@@ -35248,10 +35259,10 @@ pub fn svrev_b32(op: svbool_t) -> svbool_t {
3524835259#[cfg_attr(test, assert_instr(rev))]
3524935260pub fn svrev_b64(op: svbool_t) -> svbool_t {
3525035261 unsafe extern "unadjusted" {
35251 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.vector.reverse.nxv2i1")]
35252 fn _svrev_b64(op: svbool2_t) -> svbool2_t;
35262 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.rev.b64")]
35263 fn _svrev_b64(op: svbool_t) -> svbool_t;
3525335264 }
35254 unsafe { _svrev_b64(op.sve_into()).sve_into() }
35265 unsafe { _svrev_b64(op.sve_into()) }
3525535266}
3525635267#[doc = "Reverse all elements"]
3525735268#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev[_f32])"]
......@@ -35367,6 +35378,19 @@ pub fn svrev_u32(op: svuint32_t) -> svuint32_t {
3536735378pub fn svrev_u64(op: svuint64_t) -> svuint64_t {
3536835379 unsafe { svrev_s64(op.as_signed()).as_unsigned() }
3536935380}
35381#[doc = "Reverse all elements"]
35382#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev[_b8])"]
35383#[inline]
35384#[target_feature(enable = "sve")]
35385#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
35386#[cfg_attr(test, assert_instr(rev))]
35387pub fn svrev_b8(op: svbool_t) -> svbool_t {
35388 unsafe extern "unadjusted" {
35389 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.vector.reverse.nxv16i1")]
35390 fn _svrev_b8(op: svbool_t) -> svbool_t;
35391 }
35392 unsafe { _svrev_b8(op) }
35393}
3537035394#[doc = "Reverse bytes within elements"]
3537135395#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrevb[_s16]_m)"]
3537235396#[inline]
......@@ -43312,19 +43336,6 @@ pub fn svusmmla_s32(op1: svint32_t, op2: svuint8_t, op3: svint8_t) -> svint32_t
4331243336 unsafe { _svusmmla_s32(op1, op2.as_signed(), op3) }
4331343337}
4331443338#[doc = "Concatenate even elements from two inputs"]
43315#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1_b8)"]
43316#[inline]
43317#[target_feature(enable = "sve")]
43318#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
43319#[cfg_attr(test, assert_instr(uzp1))]
43320pub fn svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
43321 unsafe extern "unadjusted" {
43322 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.nxv16i1")]
43323 fn _svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
43324 }
43325 unsafe { _svuzp1_b8(op1, op2) }
43326}
43327#[doc = "Concatenate even elements from two inputs"]
4332843339#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1_b16)"]
4332943340#[inline]
4333043341#[target_feature(enable = "sve")]
......@@ -43332,10 +43343,10 @@ pub fn svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
4333243343#[cfg_attr(test, assert_instr(uzp1))]
4333343344pub fn svuzp1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4333443345 unsafe extern "unadjusted" {
43335 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.nxv8i1")]
43336 fn _svuzp1_b16(op1: svbool8_t, op2: svbool8_t) -> svbool8_t;
43346 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.b16")]
43347 fn _svuzp1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t;
4333743348 }
43338 unsafe { _svuzp1_b16(op1.sve_into(), op2.sve_into()).sve_into() }
43349 unsafe { _svuzp1_b16(op1.sve_into(), op2.sve_into()) }
4333943350}
4334043351#[doc = "Concatenate even elements from two inputs"]
4334143352#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1_b32)"]
......@@ -43345,10 +43356,10 @@ pub fn svuzp1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4334543356#[cfg_attr(test, assert_instr(uzp1))]
4334643357pub fn svuzp1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4334743358 unsafe extern "unadjusted" {
43348 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.nxv4i1")]
43349 fn _svuzp1_b32(op1: svbool4_t, op2: svbool4_t) -> svbool4_t;
43359 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.b32")]
43360 fn _svuzp1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t;
4335043361 }
43351 unsafe { _svuzp1_b32(op1.sve_into(), op2.sve_into()).sve_into() }
43362 unsafe { _svuzp1_b32(op1.sve_into(), op2.sve_into()) }
4335243363}
4335343364#[doc = "Concatenate even elements from two inputs"]
4335443365#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1_b64)"]
......@@ -43358,10 +43369,10 @@ pub fn svuzp1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4335843369#[cfg_attr(test, assert_instr(uzp1))]
4335943370pub fn svuzp1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t {
4336043371 unsafe extern "unadjusted" {
43361 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.nxv2i1")]
43362 fn _svuzp1_b64(op1: svbool2_t, op2: svbool2_t) -> svbool2_t;
43372 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.b64")]
43373 fn _svuzp1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t;
4336343374 }
43364 unsafe { _svuzp1_b64(op1.sve_into(), op2.sve_into()).sve_into() }
43375 unsafe { _svuzp1_b64(op1.sve_into(), op2.sve_into()) }
4336543376}
4336643377#[doc = "Concatenate even elements from two inputs"]
4336743378#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1[_f32])"]
......@@ -43477,6 +43488,19 @@ pub fn svuzp1_u32(op1: svuint32_t, op2: svuint32_t) -> svuint32_t {
4347743488pub fn svuzp1_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4347843489 unsafe { svuzp1_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4347943490}
43491#[doc = "Concatenate even elements from two inputs"]
43492#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1[_b8])"]
43493#[inline]
43494#[target_feature(enable = "sve")]
43495#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
43496#[cfg_attr(test, assert_instr(uzp1))]
43497pub fn svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
43498 unsafe extern "unadjusted" {
43499 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp1.nxv16i1")]
43500 fn _svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
43501 }
43502 unsafe { _svuzp1_b8(op1, op2) }
43503}
4348043504#[doc = "Concatenate even quadwords from two inputs"]
4348143505#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1q[_f32])"]
4348243506#[inline]
......@@ -43592,19 +43616,6 @@ pub fn svuzp1q_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4359243616 unsafe { svuzp1q_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4359343617}
4359443618#[doc = "Concatenate odd elements from two inputs"]
43595#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2_b8)"]
43596#[inline]
43597#[target_feature(enable = "sve")]
43598#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
43599#[cfg_attr(test, assert_instr(uzp2))]
43600pub fn svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
43601 unsafe extern "unadjusted" {
43602 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.nxv16i1")]
43603 fn _svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
43604 }
43605 unsafe { _svuzp2_b8(op1, op2) }
43606}
43607#[doc = "Concatenate odd elements from two inputs"]
4360843619#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2_b16)"]
4360943620#[inline]
4361043621#[target_feature(enable = "sve")]
......@@ -43612,10 +43623,10 @@ pub fn svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
4361243623#[cfg_attr(test, assert_instr(uzp2))]
4361343624pub fn svuzp2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4361443625 unsafe extern "unadjusted" {
43615 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.nxv8i1")]
43616 fn _svuzp2_b16(op1: svbool8_t, op2: svbool8_t) -> svbool8_t;
43626 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.b16")]
43627 fn _svuzp2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t;
4361743628 }
43618 unsafe { _svuzp2_b16(op1.sve_into(), op2.sve_into()).sve_into() }
43629 unsafe { _svuzp2_b16(op1.sve_into(), op2.sve_into()) }
4361943630}
4362043631#[doc = "Concatenate odd elements from two inputs"]
4362143632#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2_b32)"]
......@@ -43625,10 +43636,10 @@ pub fn svuzp2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4362543636#[cfg_attr(test, assert_instr(uzp2))]
4362643637pub fn svuzp2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4362743638 unsafe extern "unadjusted" {
43628 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.nxv4i1")]
43629 fn _svuzp2_b32(op1: svbool4_t, op2: svbool4_t) -> svbool4_t;
43639 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.b32")]
43640 fn _svuzp2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t;
4363043641 }
43631 unsafe { _svuzp2_b32(op1.sve_into(), op2.sve_into()).sve_into() }
43642 unsafe { _svuzp2_b32(op1.sve_into(), op2.sve_into()) }
4363243643}
4363343644#[doc = "Concatenate odd elements from two inputs"]
4363443645#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2_b64)"]
......@@ -43638,10 +43649,10 @@ pub fn svuzp2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4363843649#[cfg_attr(test, assert_instr(uzp2))]
4363943650pub fn svuzp2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t {
4364043651 unsafe extern "unadjusted" {
43641 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.nxv2i1")]
43642 fn _svuzp2_b64(op1: svbool2_t, op2: svbool2_t) -> svbool2_t;
43652 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.b64")]
43653 fn _svuzp2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t;
4364343654 }
43644 unsafe { _svuzp2_b64(op1.sve_into(), op2.sve_into()).sve_into() }
43655 unsafe { _svuzp2_b64(op1.sve_into(), op2.sve_into()) }
4364543656}
4364643657#[doc = "Concatenate odd elements from two inputs"]
4364743658#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2[_f32])"]
......@@ -43757,6 +43768,19 @@ pub fn svuzp2_u32(op1: svuint32_t, op2: svuint32_t) -> svuint32_t {
4375743768pub fn svuzp2_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4375843769 unsafe { svuzp2_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4375943770}
43771#[doc = "Concatenate odd elements from two inputs"]
43772#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2[_b8])"]
43773#[inline]
43774#[target_feature(enable = "sve")]
43775#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
43776#[cfg_attr(test, assert_instr(uzp2))]
43777pub fn svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
43778 unsafe extern "unadjusted" {
43779 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.uzp2.nxv16i1")]
43780 fn _svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
43781 }
43782 unsafe { _svuzp2_b8(op1, op2) }
43783}
4376043784#[doc = "Concatenate odd quadwords from two inputs"]
4376143785#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2q[_f32])"]
4376243786#[inline]
......@@ -44397,19 +44421,6 @@ pub fn svwrffr(op: svbool_t) {
4439744421 unsafe { _svwrffr(op) }
4439844422}
4439944423#[doc = "Interleave elements from low halves of two inputs"]
44400#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1_b8)"]
44401#[inline]
44402#[target_feature(enable = "sve")]
44403#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
44404#[cfg_attr(test, assert_instr(zip1))]
44405pub fn svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
44406 unsafe extern "unadjusted" {
44407 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.nxv16i1")]
44408 fn _svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
44409 }
44410 unsafe { _svzip1_b8(op1, op2) }
44411}
44412#[doc = "Interleave elements from low halves of two inputs"]
4441344424#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1_b16)"]
4441444425#[inline]
4441544426#[target_feature(enable = "sve")]
......@@ -44417,10 +44428,10 @@ pub fn svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
4441744428#[cfg_attr(test, assert_instr(zip1))]
4441844429pub fn svzip1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4441944430 unsafe extern "unadjusted" {
44420 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.nxv8i1")]
44421 fn _svzip1_b16(op1: svbool8_t, op2: svbool8_t) -> svbool8_t;
44431 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.b16")]
44432 fn _svzip1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t;
4442244433 }
44423 unsafe { _svzip1_b16(op1.sve_into(), op2.sve_into()).sve_into() }
44434 unsafe { _svzip1_b16(op1.sve_into(), op2.sve_into()) }
4442444435}
4442544436#[doc = "Interleave elements from low halves of two inputs"]
4442644437#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1_b32)"]
......@@ -44430,10 +44441,10 @@ pub fn svzip1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4443044441#[cfg_attr(test, assert_instr(zip1))]
4443144442pub fn svzip1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4443244443 unsafe extern "unadjusted" {
44433 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.nxv4i1")]
44434 fn _svzip1_b32(op1: svbool4_t, op2: svbool4_t) -> svbool4_t;
44444 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.b32")]
44445 fn _svzip1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t;
4443544446 }
44436 unsafe { _svzip1_b32(op1.sve_into(), op2.sve_into()).sve_into() }
44447 unsafe { _svzip1_b32(op1.sve_into(), op2.sve_into()) }
4443744448}
4443844449#[doc = "Interleave elements from low halves of two inputs"]
4443944450#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1_b64)"]
......@@ -44443,10 +44454,10 @@ pub fn svzip1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4444344454#[cfg_attr(test, assert_instr(zip1))]
4444444455pub fn svzip1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t {
4444544456 unsafe extern "unadjusted" {
44446 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.nxv2i1")]
44447 fn _svzip1_b64(op1: svbool2_t, op2: svbool2_t) -> svbool2_t;
44457 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.b64")]
44458 fn _svzip1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t;
4444844459 }
44449 unsafe { _svzip1_b64(op1.sve_into(), op2.sve_into()).sve_into() }
44460 unsafe { _svzip1_b64(op1.sve_into(), op2.sve_into()) }
4445044461}
4445144462#[doc = "Interleave elements from low halves of two inputs"]
4445244463#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1[_f32])"]
......@@ -44562,6 +44573,19 @@ pub fn svzip1_u32(op1: svuint32_t, op2: svuint32_t) -> svuint32_t {
4456244573pub fn svzip1_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4456344574 unsafe { svzip1_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4456444575}
44576#[doc = "Interleave elements from low halves of two inputs"]
44577#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1[_b8])"]
44578#[inline]
44579#[target_feature(enable = "sve")]
44580#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
44581#[cfg_attr(test, assert_instr(zip1))]
44582pub fn svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
44583 unsafe extern "unadjusted" {
44584 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip1.nxv16i1")]
44585 fn _svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
44586 }
44587 unsafe { _svzip1_b8(op1, op2) }
44588}
4456544589#[doc = "Interleave quadwords from low halves of two inputs"]
4456644590#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1q[_f32])"]
4456744591#[inline]
......@@ -44677,19 +44701,6 @@ pub fn svzip1q_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4467744701 unsafe { svzip1q_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4467844702}
4467944703#[doc = "Interleave elements from high halves of two inputs"]
44680#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2_b8)"]
44681#[inline]
44682#[target_feature(enable = "sve")]
44683#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
44684#[cfg_attr(test, assert_instr(zip2))]
44685pub fn svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
44686 unsafe extern "unadjusted" {
44687 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.nxv16i1")]
44688 fn _svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
44689 }
44690 unsafe { _svzip2_b8(op1, op2) }
44691}
44692#[doc = "Interleave elements from high halves of two inputs"]
4469344704#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2_b16)"]
4469444705#[inline]
4469544706#[target_feature(enable = "sve")]
......@@ -44697,10 +44708,10 @@ pub fn svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
4469744708#[cfg_attr(test, assert_instr(zip2))]
4469844709pub fn svzip2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4469944710 unsafe extern "unadjusted" {
44700 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.nxv8i1")]
44701 fn _svzip2_b16(op1: svbool8_t, op2: svbool8_t) -> svbool8_t;
44711 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.b16")]
44712 fn _svzip2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t;
4470244713 }
44703 unsafe { _svzip2_b16(op1.sve_into(), op2.sve_into()).sve_into() }
44714 unsafe { _svzip2_b16(op1.sve_into(), op2.sve_into()) }
4470444715}
4470544716#[doc = "Interleave elements from high halves of two inputs"]
4470644717#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2_b32)"]
......@@ -44710,10 +44721,10 @@ pub fn svzip2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t {
4471044721#[cfg_attr(test, assert_instr(zip2))]
4471144722pub fn svzip2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4471244723 unsafe extern "unadjusted" {
44713 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.nxv4i1")]
44714 fn _svzip2_b32(op1: svbool4_t, op2: svbool4_t) -> svbool4_t;
44724 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.b32")]
44725 fn _svzip2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t;
4471544726 }
44716 unsafe { _svzip2_b32(op1.sve_into(), op2.sve_into()).sve_into() }
44727 unsafe { _svzip2_b32(op1.sve_into(), op2.sve_into()) }
4471744728}
4471844729#[doc = "Interleave elements from high halves of two inputs"]
4471944730#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2_b64)"]
......@@ -44723,10 +44734,10 @@ pub fn svzip2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t {
4472344734#[cfg_attr(test, assert_instr(zip2))]
4472444735pub fn svzip2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t {
4472544736 unsafe extern "unadjusted" {
44726 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.nxv2i1")]
44727 fn _svzip2_b64(op1: svbool2_t, op2: svbool2_t) -> svbool2_t;
44737 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.b64")]
44738 fn _svzip2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t;
4472844739 }
44729 unsafe { _svzip2_b64(op1.sve_into(), op2.sve_into()).sve_into() }
44740 unsafe { _svzip2_b64(op1.sve_into(), op2.sve_into()) }
4473044741}
4473144742#[doc = "Interleave elements from high halves of two inputs"]
4473244743#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2[_f32])"]
......@@ -44842,6 +44853,19 @@ pub fn svzip2_u32(op1: svuint32_t, op2: svuint32_t) -> svuint32_t {
4484244853pub fn svzip2_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t {
4484344854 unsafe { svzip2_s64(op1.as_signed(), op2.as_signed()).as_unsigned() }
4484444855}
44856#[doc = "Interleave elements from high halves of two inputs"]
44857#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2[_b8])"]
44858#[inline]
44859#[target_feature(enable = "sve")]
44860#[unstable(feature = "stdarch_aarch64_sve", issue = "145052")]
44861#[cfg_attr(test, assert_instr(zip2))]
44862pub fn svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t {
44863 unsafe extern "unadjusted" {
44864 #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.zip2.nxv16i1")]
44865 fn _svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t;
44866 }
44867 unsafe { _svzip2_b8(op1, op2) }
44868}
4484544869#[doc = "Interleave quadwords from high halves of two inputs"]
4484644870#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2q[_f32])"]
4484744871#[inline]
library/stdarch/crates/core_arch/src/aarch64/sve/mod.rs+10-2
......@@ -28,6 +28,14 @@ pub(super) trait SveInto<T>: Sized {
2828 unsafe fn sve_into(self) -> T;
2929}
3030
31impl<T> SveInto<T> for T {
32 #[inline]
33 #[target_feature(enable = "sve")]
34 unsafe fn sve_into(self) -> T {
35 self
36 }
37}
38
3139macro_rules! impl_sve_type {
3240 ($(($v:vis, $elem_type:ty, $name:ident, $elt:literal))*) => ($(
3341 #[doc = concat!("Scalable vector of type ", stringify!($elem_type))]
......@@ -130,7 +138,7 @@ macro_rules! impl_internal_sve_predicate {
130138 #[target_feature(enable = "sve")]
131139 unsafe fn sve_into(self) -> svbool_t {
132140 #[allow(improper_ctypes)]
133 unsafe extern "C" {
141 unsafe extern "unadjusted" {
134142 #[cfg_attr(
135143 target_arch = "aarch64",
136144 link_name = concat!("llvm.aarch64.sve.convert.to.svbool.nxv", $elt, "i1")
......@@ -147,7 +155,7 @@ macro_rules! impl_internal_sve_predicate {
147155 #[target_feature(enable = "sve")]
148156 unsafe fn sve_into(self) -> $name {
149157 #[allow(improper_ctypes)]
150 unsafe extern "C" {
158 unsafe extern "unadjusted" {
151159 #[cfg_attr(
152160 target_arch = "aarch64",
153161 link_name = concat!("llvm.aarch64.sve.convert.from.svbool.nxv", $elt, "i1")
library/stdarch/crates/core_arch/src/hexagon/v128.rs+1
......@@ -1,3 +1,4 @@
1// This code is automatically generated. DO NOT MODIFY.
12//! Hexagon HVX 128-byte vector mode intrinsics
23//!
34//! This module provides intrinsics for the Hexagon Vector Extensions (HVX)
library/stdarch/crates/core_arch/src/hexagon/v64.rs+1
......@@ -1,3 +1,4 @@
1// This code is automatically generated. DO NOT MODIFY.
12//! Hexagon HVX 64-byte vector mode intrinsics
23//!
34//! This module provides intrinsics for the Hexagon Vector Extensions (HVX)
library/stdarch/crates/core_arch/src/loongarch64/mod.rs+12-12
......@@ -62,56 +62,56 @@ unsafe extern "unadjusted" {
6262
6363/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
6464#[inline(always)]
65#[unstable(feature = "stdarch_loongarch", issue = "117427")]
65#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
6666pub fn crc_w_b_w(a: i8, b: i32) -> i32 {
67 unsafe { __crc_w_b_w(a.cast_unsigned() as i32, b) }
67 unsafe { __crc_w_b_w(a as i32, b) }
6868}
6969
7070/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
7171#[inline(always)]
72#[unstable(feature = "stdarch_loongarch", issue = "117427")]
72#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
7373pub fn crc_w_h_w(a: i16, b: i32) -> i32 {
74 unsafe { __crc_w_h_w(a.cast_unsigned() as i32, b) }
74 unsafe { __crc_w_h_w(a as i32, b) }
7575}
7676
7777/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
7878#[inline(always)]
79#[unstable(feature = "stdarch_loongarch", issue = "117427")]
79#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
8080pub fn crc_w_w_w(a: i32, b: i32) -> i32 {
8181 unsafe { __crc_w_w_w(a, b) }
8282}
8383
8484/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
8585#[inline(always)]
86#[unstable(feature = "stdarch_loongarch", issue = "117427")]
86#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
8787pub fn crc_w_d_w(a: i64, b: i32) -> i32 {
8888 unsafe { __crc_w_d_w(a, b) }
8989}
9090
9191/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
9292#[inline(always)]
93#[unstable(feature = "stdarch_loongarch", issue = "117427")]
93#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
9494pub fn crcc_w_b_w(a: i8, b: i32) -> i32 {
95 unsafe { __crcc_w_b_w(a.cast_unsigned() as i32, b) }
95 unsafe { __crcc_w_b_w(a as i32, b) }
9696}
9797
9898/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
9999#[inline(always)]
100#[unstable(feature = "stdarch_loongarch", issue = "117427")]
100#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
101101pub fn crcc_w_h_w(a: i16, b: i32) -> i32 {
102 unsafe { __crcc_w_h_w(a.cast_unsigned() as i32, b) }
102 unsafe { __crcc_w_h_w(a as i32, b) }
103103}
104104
105105/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
106106#[inline(always)]
107#[unstable(feature = "stdarch_loongarch", issue = "117427")]
107#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
108108pub fn crcc_w_w_w(a: i32, b: i32) -> i32 {
109109 unsafe { __crcc_w_w_w(a, b) }
110110}
111111
112112/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
113113#[inline(always)]
114#[unstable(feature = "stdarch_loongarch", issue = "117427")]
114#[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")]
115115pub fn crcc_w_d_w(a: i64, b: i32) -> i32 {
116116 unsafe { __crcc_w_d_w(a, b) }
117117}
library/stdarch/crates/core_arch/src/mips/msa.rs+1-1
......@@ -45,7 +45,7 @@ types! {
4545}
4646
4747#[allow(improper_ctypes)]
48unsafe extern "C" {
48unsafe extern "unadjusted" {
4949 #[link_name = "llvm.mips.add.a.b"]
5050 fn msa_add_a_b(a: v16i8, b: v16i8) -> v16i8;
5151 #[link_name = "llvm.mips.add.a.h"]
library/stdarch/crates/core_arch/src/nvptx/mod.rs+4-4
......@@ -19,9 +19,9 @@ mod packed;
1919pub use packed::*;
2020
2121#[allow(improper_ctypes)]
22unsafe extern "C" {
23 #[link_name = "llvm.nvvm.barrier0"]
24 fn syncthreads() -> ();
22unsafe extern "unadjusted" {
23 #[link_name = "llvm.nvvm.barrier.cta.sync.aligned.all"]
24 fn syncthreads(a: u32) -> ();
2525 #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.x"]
2626 fn block_dim_x() -> u32;
2727 #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.y"]
......@@ -54,7 +54,7 @@ unsafe extern "C" {
5454#[inline]
5555#[unstable(feature = "stdarch_nvptx", issue = "111199")]
5656pub unsafe fn _syncthreads() -> () {
57 syncthreads()
57 syncthreads(0)
5858}
5959
6060/// x-th thread-block dimension.
library/stdarch/crates/core_arch/src/nvptx/packed.rs+1-1
......@@ -7,7 +7,7 @@
77use crate::intrinsics::simd::*;
88
99#[allow(improper_ctypes)]
10unsafe extern "C" {
10unsafe extern "unadjusted" {
1111 #[link_name = "llvm.minimum.v2f16"]
1212 fn llvm_f16x2_minimum(a: f16x2, b: f16x2) -> f16x2;
1313 #[link_name = "llvm.maximum.v2f16"]
library/stdarch/crates/core_arch/src/powerpc/altivec.rs+1-1
......@@ -96,7 +96,7 @@ impl From<vector_bool_int> for m32x4 {
9696}
9797
9898#[allow(improper_ctypes)]
99unsafe extern "C" {
99unsafe extern "unadjusted" {
100100 #[link_name = "llvm.ppc.altivec.lvx"]
101101 fn lvx(p: *const i8) -> vector_unsigned_int;
102102
library/stdarch/crates/core_arch/src/powerpc/vsx.rs+1-1
......@@ -52,7 +52,7 @@ impl From<vector_bool_long> for m64x2 {
5252}
5353
5454#[allow(improper_ctypes)]
55unsafe extern "C" {
55unsafe extern "unadjusted" {
5656 #[link_name = "llvm.ppc.altivec.vperm"]
5757 fn vperm(
5858 a: vector_signed_int,
library/stdarch/crates/core_arch/src/powerpc64/vsx.rs+1-1
......@@ -17,7 +17,7 @@ use stdarch_test::assert_instr;
1717use crate::mem::transmute;
1818
1919#[allow(improper_ctypes)]
20unsafe extern "C" {
20unsafe extern "unadjusted" {
2121 #[link_name = "llvm.ppc.vsx.lxvl"]
2222 fn lxvl(a: *const u8, l: usize) -> vector_signed_int;
2323
library/stdarch/crates/core_arch/src/wasm32/memory.rs+4-2
......@@ -2,9 +2,11 @@
22use stdarch_test::assert_instr;
33
44unsafe extern "unadjusted" {
5 #[link_name = "llvm.wasm.memory.grow"]
5 #[cfg_attr(target_pointer_width = "32", link_name = "llvm.wasm.memory.grow.i32")]
6 #[cfg_attr(target_pointer_width = "64", link_name = "llvm.wasm.memory.grow.i64")]
67 fn llvm_memory_grow(mem: u32, pages: usize) -> usize;
7 #[link_name = "llvm.wasm.memory.size"]
8 #[cfg_attr(target_pointer_width = "32", link_name = "llvm.wasm.memory.size.i32")]
9 #[cfg_attr(target_pointer_width = "64", link_name = "llvm.wasm.memory.size.i64")]
810 fn llvm_memory_size(mem: u32) -> usize;
911}
1012
library/stdarch/crates/core_arch/src/x86/aes.rs+1-1
......@@ -13,7 +13,7 @@ use crate::core_arch::x86::__m128i;
1313use stdarch_test::assert_instr;
1414
1515#[allow(improper_ctypes)]
16unsafe extern "C" {
16unsafe extern "unadjusted" {
1717 #[link_name = "llvm.x86.aesni.aesdec"]
1818 fn aesdec(a: __m128i, round_key: __m128i) -> __m128i;
1919 #[link_name = "llvm.x86.aesni.aesdeclast"]
library/stdarch/crates/core_arch/src/x86/avx.rs+1-1
......@@ -3292,7 +3292,7 @@ pub const fn _mm256_cvtss_f32(a: __m256) -> f32 {
32923292
32933293// LLVM intrinsics used in the above functions
32943294#[allow(improper_ctypes)]
3295unsafe extern "C" {
3295unsafe extern "unadjusted" {
32963296 #[link_name = "llvm.x86.avx.round.pd.256"]
32973297 fn roundpd256(a: __m256d, b: i32) -> __m256d;
32983298 #[link_name = "llvm.x86.avx.round.ps.256"]
library/stdarch/crates/core_arch/src/x86/avx2.rs+1-1
......@@ -3906,7 +3906,7 @@ pub const fn _mm256_extract_epi16<const INDEX: i32>(a: __m256i) -> i32 {
39063906}
39073907
39083908#[allow(improper_ctypes)]
3909unsafe extern "C" {
3909unsafe extern "unadjusted" {
39103910 #[link_name = "llvm.x86.avx2.pmadd.wd"]
39113911 fn pmaddwd(a: i16x16, b: i16x16) -> i32x8;
39123912 #[link_name = "llvm.x86.avx2.pmadd.ub.sw"]
library/stdarch/crates/core_arch/src/x86/avx512bf16.rs+1-1
......@@ -9,7 +9,7 @@ use crate::intrinsics::simd::*;
99use stdarch_test::assert_instr;
1010
1111#[allow(improper_ctypes)]
12unsafe extern "C" {
12unsafe extern "unadjusted" {
1313 #[link_name = "llvm.x86.avx512bf16.cvtne2ps2bf16.128"]
1414 fn cvtne2ps2bf16(a: f32x4, b: f32x4) -> i16x8;
1515 #[link_name = "llvm.x86.avx512bf16.cvtne2ps2bf16.256"]
library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs+1-1
......@@ -27,7 +27,7 @@ use crate::mem::transmute;
2727use stdarch_test::assert_instr;
2828
2929#[allow(improper_ctypes)]
30unsafe extern "C" {
30unsafe extern "unadjusted" {
3131 #[link_name = "llvm.x86.avx512.vpshufbitqmb.512"]
3232 fn bitshuffle_512(data: i8x64, indices: i8x64) -> __mmask64;
3333 #[link_name = "llvm.x86.avx512.vpshufbitqmb.256"]
library/stdarch/crates/core_arch/src/x86/avx512bw.rs+1-1
......@@ -12764,7 +12764,7 @@ pub unsafe fn _mm_mask_cvtusepi16_storeu_epi8(mem_addr: *mut i8, k: __mmask8, a:
1276412764}
1276512765
1276612766#[allow(improper_ctypes)]
12767unsafe extern "C" {
12767unsafe extern "unadjusted" {
1276812768 #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"]
1276912769 fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32;
1277012770
library/stdarch/crates/core_arch/src/x86/avx512cd.rs+1-1
......@@ -563,7 +563,7 @@ pub const fn _mm_maskz_lzcnt_epi64(k: __mmask8, a: __m128i) -> __m128i {
563563}
564564
565565#[allow(improper_ctypes)]
566unsafe extern "C" {
566unsafe extern "unadjusted" {
567567 #[link_name = "llvm.x86.avx512.conflict.d.512"]
568568 fn vpconflictd(a: i32x16) -> i32x16;
569569 #[link_name = "llvm.x86.avx512.conflict.d.256"]
library/stdarch/crates/core_arch/src/x86/avx512dq.rs+1-1
......@@ -7235,7 +7235,7 @@ pub fn _mm_mask_fpclass_ss_mask<const IMM8: i32>(k1: __mmask8, a: __m128) -> __m
72357235}
72367236
72377237#[allow(improper_ctypes)]
7238unsafe extern "C" {
7238unsafe extern "unadjusted" {
72397239 #[link_name = "llvm.x86.avx512.sitofp.round.v2f64.v2i64"]
72407240 fn vcvtqq2pd_128(a: i64x2, rounding: i32) -> f64x2;
72417241 #[link_name = "llvm.x86.avx512.sitofp.round.v4f64.v4i64"]
library/stdarch/crates/core_arch/src/x86/avx512f.rs+1-1
......@@ -44215,7 +44215,7 @@ pub const _MM_PERM_DDDC: _MM_PERM_ENUM = 0xFE;
4421544215pub const _MM_PERM_DDDD: _MM_PERM_ENUM = 0xFF;
4421644216
4421744217#[allow(improper_ctypes)]
44218unsafe extern "C" {
44218unsafe extern "unadjusted" {
4421944219 #[link_name = "llvm.x86.avx512.sqrt.ps.512"]
4422044220 fn vsqrtps(a: f32x16, rounding: i32) -> f32x16;
4422144221 #[link_name = "llvm.x86.avx512.sqrt.pd.512"]
library/stdarch/crates/core_arch/src/x86/avx512ifma.rs+1-1
......@@ -347,7 +347,7 @@ pub fn _mm_maskz_madd52lo_epu64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i)
347347}
348348
349349#[allow(improper_ctypes)]
350unsafe extern "C" {
350unsafe extern "unadjusted" {
351351 #[link_name = "llvm.x86.avx512.vpmadd52l.uq.128"]
352352 fn vpmadd52luq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i;
353353 #[link_name = "llvm.x86.avx512.vpmadd52h.uq.128"]
library/stdarch/crates/core_arch/src/x86/avx512vbmi.rs+1-1
......@@ -453,7 +453,7 @@ pub fn _mm_maskz_multishift_epi64_epi8(k: __mmask16, a: __m128i, b: __m128i) ->
453453}
454454
455455#[allow(improper_ctypes)]
456unsafe extern "C" {
456unsafe extern "unadjusted" {
457457 #[link_name = "llvm.x86.avx512.vpermi2var.qi.512"]
458458 fn vpermi2b(a: i8x64, idx: i8x64, b: i8x64) -> i8x64;
459459 #[link_name = "llvm.x86.avx512.vpermi2var.qi.256"]
library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs+1-1
......@@ -2383,7 +2383,7 @@ pub const fn _mm_maskz_shrdi_epi16<const IMM8: i32>(
23832383}
23842384
23852385#[allow(improper_ctypes)]
2386unsafe extern "C" {
2386unsafe extern "unadjusted" {
23872387 #[link_name = "llvm.x86.avx512.mask.compress.store.w.512"]
23882388 fn vcompressstorew(mem: *mut i8, data: i16x32, mask: u32);
23892389 #[link_name = "llvm.x86.avx512.mask.compress.store.w.256"]
library/stdarch/crates/core_arch/src/x86/avx512vnni.rs+1-1
......@@ -873,7 +873,7 @@ pub fn _mm256_dpwuuds_epi32(src: __m256i, a: __m256i, b: __m256i) -> __m256i {
873873}
874874
875875#[allow(improper_ctypes)]
876unsafe extern "C" {
876unsafe extern "unadjusted" {
877877 #[link_name = "llvm.x86.avx512.vpdpwssd.512"]
878878 fn vpdpwssd(src: i32x16, a: i16x32, b: i16x32) -> i32x16;
879879 #[link_name = "llvm.x86.avx512.vpdpwssd.256"]
library/stdarch/crates/core_arch/src/x86/avx512vp2intersect.rs+1-1
......@@ -110,7 +110,7 @@ pub unsafe fn _mm512_2intersect_epi64(
110110}
111111
112112#[allow(improper_ctypes)]
113unsafe extern "C" {
113unsafe extern "unadjusted" {
114114 #[link_name = "llvm.x86.avx512.vp2intersect.d.128"]
115115 fn vp2intersectd_128(a: i32x4, b: i32x4) -> (u8, u8);
116116 #[link_name = "llvm.x86.avx512.vp2intersect.q.128"]
library/stdarch/crates/core_arch/src/x86/avxneconvert.rs+1-1
......@@ -176,7 +176,7 @@ pub fn _mm256_cvtneps_avx_pbh(a: __m256) -> __m128bh {
176176}
177177
178178#[allow(improper_ctypes)]
179unsafe extern "C" {
179unsafe extern "unadjusted" {
180180 #[link_name = "llvm.x86.vbcstnebf162ps128"]
181181 fn bcstnebf162ps_128(a: *const bf16) -> __m128;
182182 #[link_name = "llvm.x86.vbcstnebf162ps256"]
library/stdarch/crates/core_arch/src/x86/bmi1.rs+1-1
......@@ -131,7 +131,7 @@ pub const fn _mm_tzcnt_32(x: u32) -> i32 {
131131 x.trailing_zeros() as i32
132132}
133133
134unsafe extern "C" {
134unsafe extern "unadjusted" {
135135 #[link_name = "llvm.x86.bmi.bextr.32"]
136136 fn x86_bmi_bextr_32(x: u32, y: u32) -> u32;
137137}
library/stdarch/crates/core_arch/src/x86/bmi2.rs+1-1
......@@ -67,7 +67,7 @@ pub fn _pext_u32(a: u32, mask: u32) -> u32 {
6767 unsafe { x86_bmi2_pext_32(a, mask) }
6868}
6969
70unsafe extern "C" {
70unsafe extern "unadjusted" {
7171 #[link_name = "llvm.x86.bmi.bzhi.32"]
7272 fn x86_bmi2_bzhi_32(x: u32, y: u32) -> u32;
7373 #[link_name = "llvm.x86.bmi.pdep.32"]
library/stdarch/crates/core_arch/src/x86/fxsr.rs+1-1
......@@ -4,7 +4,7 @@
44use stdarch_test::assert_instr;
55
66#[allow(improper_ctypes)]
7unsafe extern "C" {
7unsafe extern "unadjusted" {
88 #[link_name = "llvm.x86.fxsave"]
99 fn fxsave(p: *mut u8);
1010 #[link_name = "llvm.x86.fxrstor"]
library/stdarch/crates/core_arch/src/x86/gfni.rs+1-1
......@@ -23,7 +23,7 @@ use crate::mem::transmute;
2323use stdarch_test::assert_instr;
2424
2525#[allow(improper_ctypes)]
26unsafe extern "C" {
26unsafe extern "unadjusted" {
2727 #[link_name = "llvm.x86.vgf2p8affineinvqb.512"]
2828 fn vgf2p8affineinvqb_512(x: i8x64, a: i8x64, imm8: u8) -> i8x64;
2929 #[link_name = "llvm.x86.vgf2p8affineinvqb.256"]
library/stdarch/crates/core_arch/src/x86/pclmulqdq.rs+1-1
......@@ -11,7 +11,7 @@ use crate::core_arch::x86::__m128i;
1111use stdarch_test::assert_instr;
1212
1313#[allow(improper_ctypes)]
14unsafe extern "C" {
14unsafe extern "unadjusted" {
1515 #[link_name = "llvm.x86.pclmulqdq"]
1616 fn pclmulqdq(a: __m128i, round_key: __m128i, imm8: u8) -> __m128i;
1717}
library/stdarch/crates/core_arch/src/x86/rtm.rs+1-1
......@@ -16,7 +16,7 @@
1616#[cfg(test)]
1717use stdarch_test::assert_instr;
1818
19unsafe extern "C" {
19unsafe extern "unadjusted" {
2020 #[link_name = "llvm.x86.xbegin"]
2121 fn x86_xbegin() -> i32;
2222 #[link_name = "llvm.x86.xend"]
library/stdarch/crates/core_arch/src/x86/sha.rs+1-1
......@@ -1,7 +1,7 @@
11use crate::core_arch::{simd::*, x86::*};
22
33#[allow(improper_ctypes)]
4unsafe extern "C" {
4unsafe extern "unadjusted" {
55 #[link_name = "llvm.x86.sha1msg1"]
66 fn sha1msg1(a: i32x4, b: i32x4) -> i32x4;
77 #[link_name = "llvm.x86.sha1msg2"]
library/stdarch/crates/core_arch/src/x86/sse.rs+2-2
......@@ -1987,7 +1987,7 @@ pub const fn _MM_TRANSPOSE4_PS(
19871987}
19881988
19891989#[allow(improper_ctypes)]
1990unsafe extern "C" {
1990unsafe extern "unadjusted" {
19911991 #[link_name = "llvm.x86.sse.rcp.ss"]
19921992 fn rcpss(a: __m128) -> __m128;
19931993 #[link_name = "llvm.x86.sse.rcp.ps"]
......@@ -2040,7 +2040,7 @@ unsafe extern "C" {
20402040 fn stmxcsr(p: *mut i8);
20412041 #[link_name = "llvm.x86.sse.ldmxcsr"]
20422042 fn ldmxcsr(p: *const i8);
2043 #[link_name = "llvm.prefetch"]
2043 #[link_name = "llvm.prefetch.p0"]
20442044 fn prefetch(p: *const i8, rw: i32, loc: i32, ty: i32);
20452045 #[link_name = "llvm.x86.sse.cmp.ss"]
20462046 fn cmpss(a: __m128, b: __m128, imm8: i8) -> __m128;
library/stdarch/crates/core_arch/src/x86/sse2.rs+1-1
......@@ -3242,7 +3242,7 @@ pub const fn _mm_unpacklo_pd(a: __m128d, b: __m128d) -> __m128d {
32423242}
32433243
32443244#[allow(improper_ctypes)]
3245unsafe extern "C" {
3245unsafe extern "unadjusted" {
32463246 #[link_name = "llvm.x86.sse2.pause"]
32473247 fn pause();
32483248 #[link_name = "llvm.x86.sse2.clflush"]
library/stdarch/crates/core_arch/src/x86/sse3.rs+1-1
......@@ -178,7 +178,7 @@ pub const fn _mm_moveldup_ps(a: __m128) -> __m128 {
178178}
179179
180180#[allow(improper_ctypes)]
181unsafe extern "C" {
181unsafe extern "unadjusted" {
182182 #[link_name = "llvm.x86.sse3.ldu.dq"]
183183 fn lddqu(mem_addr: *const i8) -> i8x16;
184184}
library/stdarch/crates/core_arch/src/x86/sse41.rs+1-1
......@@ -1181,7 +1181,7 @@ pub unsafe fn _mm_stream_load_si128(mem_addr: *const __m128i) -> __m128i {
11811181}
11821182
11831183#[allow(improper_ctypes)]
1184unsafe extern "C" {
1184unsafe extern "unadjusted" {
11851185 #[link_name = "llvm.x86.sse41.insertps"]
11861186 fn insertps(a: __m128, b: __m128, imm8: u8) -> __m128;
11871187 #[link_name = "llvm.x86.sse41.dppd"]
library/stdarch/crates/core_arch/src/x86/sse42.rs+1-1
......@@ -569,7 +569,7 @@ pub const fn _mm_cmpgt_epi64(a: __m128i, b: __m128i) -> __m128i {
569569}
570570
571571#[allow(improper_ctypes)]
572unsafe extern "C" {
572unsafe extern "unadjusted" {
573573 // SSE 4.2 string and text comparison ops
574574 #[link_name = "llvm.x86.sse42.pcmpestrm128"]
575575 fn pcmpestrm128(a: i8x16, la: i32, b: i8x16, lb: i32, imm8: i8) -> u8x16;
library/stdarch/crates/core_arch/src/x86/sse4a.rs+1-1
......@@ -6,7 +6,7 @@ use crate::core_arch::{simd::*, x86::*};
66use stdarch_test::assert_instr;
77
88#[allow(improper_ctypes)]
9unsafe extern "C" {
9unsafe extern "unadjusted" {
1010 #[link_name = "llvm.x86.sse4a.extrq"]
1111 fn extrq(x: i64x2, y: i8x16) -> i64x2;
1212 #[link_name = "llvm.x86.sse4a.extrqi"]
library/stdarch/crates/core_arch/src/x86/ssse3.rs+1-1
......@@ -345,7 +345,7 @@ pub fn _mm_sign_epi32(a: __m128i, b: __m128i) -> __m128i {
345345}
346346
347347#[allow(improper_ctypes)]
348unsafe extern "C" {
348unsafe extern "unadjusted" {
349349 #[link_name = "llvm.x86.ssse3.pshuf.b.128"]
350350 fn pshufb128(a: u8x16, b: u8x16) -> u8x16;
351351
library/stdarch/crates/core_arch/src/x86/tbm.rs+1-1
......@@ -13,7 +13,7 @@
1313#[cfg(test)]
1414use stdarch_test::assert_instr;
1515
16unsafe extern "C" {
16unsafe extern "unadjusted" {
1717 #[link_name = "llvm.x86.tbm.bextri.u32"]
1818 fn bextri_u32(a: u32, control: u32) -> u32;
1919}
library/stdarch/crates/core_arch/src/x86/vaes.rs+1-1
......@@ -14,7 +14,7 @@ use crate::core_arch::x86::__m512i;
1414use stdarch_test::assert_instr;
1515
1616#[allow(improper_ctypes)]
17unsafe extern "C" {
17unsafe extern "unadjusted" {
1818 #[link_name = "llvm.x86.aesni.aesenc.256"]
1919 fn aesenc_256(a: __m256i, round_key: __m256i) -> __m256i;
2020 #[link_name = "llvm.x86.aesni.aesenclast.256"]
library/stdarch/crates/core_arch/src/x86/vpclmulqdq.rs+1-1
......@@ -12,7 +12,7 @@ use crate::core_arch::x86::__m512i;
1212use stdarch_test::assert_instr;
1313
1414#[allow(improper_ctypes)]
15unsafe extern "C" {
15unsafe extern "unadjusted" {
1616 #[link_name = "llvm.x86.pclmulqdq.256"]
1717 fn pclmulqdq_256(a: __m256i, round_key: __m256i, imm8: u8) -> __m256i;
1818 #[link_name = "llvm.x86.pclmulqdq.512"]
library/stdarch/crates/core_arch/src/x86/xsave.rs+1-1
......@@ -5,7 +5,7 @@
55use stdarch_test::assert_instr;
66
77#[allow(improper_ctypes)]
8unsafe extern "C" {
8unsafe extern "unadjusted" {
99 #[link_name = "llvm.x86.xsave"]
1010 fn xsave(p: *mut u8, hi: u32, lo: u32);
1111 #[link_name = "llvm.x86.xrstor"]
library/stdarch/crates/core_arch/src/x86_64/avx512f.rs+1-1
......@@ -527,7 +527,7 @@ pub fn _mm_cvtt_roundss_u64<const SAE: i32>(a: __m128) -> u64 {
527527}
528528
529529#[allow(improper_ctypes)]
530unsafe extern "C" {
530unsafe extern "unadjusted" {
531531 #[link_name = "llvm.x86.avx512.vcvtss2si64"]
532532 fn vcvtss2si64(a: f32x4, rounding: i32) -> i64;
533533 #[link_name = "llvm.x86.avx512.vcvtss2usi64"]
library/stdarch/crates/core_arch/src/x86_64/avx512fp16.rs+1-1
......@@ -211,7 +211,7 @@ pub fn _mm_cvtt_roundsh_u64<const SAE: i32>(a: __m128h) -> u64 {
211211}
212212
213213#[allow(improper_ctypes)]
214unsafe extern "C" {
214unsafe extern "unadjusted" {
215215 #[link_name = "llvm.x86.avx512fp16.vcvtsi642sh"]
216216 fn vcvtsi642sh(a: __m128h, b: i64, rounding: i32) -> __m128h;
217217 #[link_name = "llvm.x86.avx512fp16.vcvtusi642sh"]
library/stdarch/crates/core_arch/src/x86_64/bmi.rs+1-1
......@@ -122,7 +122,7 @@ pub const fn _mm_tzcnt_64(x: u64) -> i64 {
122122 x.trailing_zeros() as i64
123123}
124124
125unsafe extern "C" {
125unsafe extern "unadjusted" {
126126 #[link_name = "llvm.x86.bmi.bextr.64"]
127127 fn x86_bmi_bextr_64(x: u64, y: u64) -> u64;
128128}
library/stdarch/crates/core_arch/src/x86_64/bmi2.rs+1-1
......@@ -69,7 +69,7 @@ pub fn _pext_u64(a: u64, mask: u64) -> u64 {
6969 unsafe { x86_bmi2_pext_64(a, mask) }
7070}
7171
72unsafe extern "C" {
72unsafe extern "unadjusted" {
7373 #[link_name = "llvm.x86.bmi.bzhi.64"]
7474 fn x86_bmi2_bzhi_64(x: u64, y: u64) -> u64;
7575 #[link_name = "llvm.x86.bmi.pdep.64"]
library/stdarch/crates/core_arch/src/x86_64/fxsr.rs+1-1
......@@ -4,7 +4,7 @@
44use stdarch_test::assert_instr;
55
66#[allow(improper_ctypes)]
7unsafe extern "C" {
7unsafe extern "unadjusted" {
88 #[link_name = "llvm.x86.fxsave64"]
99 fn fxsave64(p: *mut u8);
1010 #[link_name = "llvm.x86.fxrstor64"]
library/stdarch/crates/core_arch/src/x86_64/sse.rs+1-1
......@@ -6,7 +6,7 @@ use crate::core_arch::x86::*;
66use stdarch_test::assert_instr;
77
88#[allow(improper_ctypes)]
9unsafe extern "C" {
9unsafe extern "unadjusted" {
1010 #[link_name = "llvm.x86.sse.cvtss2si64"]
1111 fn cvtss2si64(a: __m128) -> i64;
1212 #[link_name = "llvm.x86.sse.cvttss2si64"]
library/stdarch/crates/core_arch/src/x86_64/sse2.rs+1-1
......@@ -6,7 +6,7 @@ use crate::core_arch::x86::*;
66use stdarch_test::assert_instr;
77
88#[allow(improper_ctypes)]
9unsafe extern "C" {
9unsafe extern "unadjusted" {
1010 #[link_name = "llvm.x86.sse2.cvtsd2si64"]
1111 fn cvtsd2si64(a: __m128d) -> i64;
1212 #[link_name = "llvm.x86.sse2.cvttsd2si64"]
library/stdarch/crates/core_arch/src/x86_64/sse42.rs+1-1
......@@ -4,7 +4,7 @@
44use stdarch_test::assert_instr;
55
66#[allow(improper_ctypes)]
7unsafe extern "C" {
7unsafe extern "unadjusted" {
88 #[link_name = "llvm.x86.sse42.crc32.64.64"]
99 fn crc32_64_64(crc: u64, v: u64) -> u64;
1010}
library/stdarch/crates/core_arch/src/x86_64/tbm.rs+1-1
......@@ -13,7 +13,7 @@
1313#[cfg(test)]
1414use stdarch_test::assert_instr;
1515
16unsafe extern "C" {
16unsafe extern "unadjusted" {
1717 #[link_name = "llvm.x86.tbm.bextri.u64"]
1818 fn bextri_u64(a: u64, control: u64) -> u64;
1919}
library/stdarch/crates/core_arch/src/x86_64/xsave.rs+1-1
......@@ -6,7 +6,7 @@
66use stdarch_test::assert_instr;
77
88#[allow(improper_ctypes)]
9unsafe extern "C" {
9unsafe extern "unadjusted" {
1010 #[link_name = "llvm.x86.xsave64"]
1111 fn xsave64(p: *mut u8, hi: u32, lo: u32);
1212 #[link_name = "llvm.x86.xrstor64"]
library/stdarch/crates/intrinsic-test/src/arm/config.rs deleted-26
......@@ -1,26 +0,0 @@
1pub const NOTICE: &str = "\
2// This is a transient test file, not intended for distribution. Some aspects of the
3// test are derived from a JSON specification, published under the same license as the
4// `intrinsic-test` crate.\n";
5
6pub const PLATFORM_RUST_DEFINITIONS: &str = "";
7
8pub const PLATFORM_RUST_CFGS: &str = r#"
9#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]
10#![cfg_attr(target_arch = "arm", feature(stdarch_aarch32_crc32))]
11#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fcma))]
12#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_dotprod))]
13#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_i8mm))]
14#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_sm4))]
15#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_ftts))]
16#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_feat_lut))]
17#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fp8))]
18#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(faminmax))]
19#![feature(stdarch_neon_f16)]
20
21#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
22use core_arch::arch::aarch64::*;
23
24#[cfg(target_arch = "arm")]
25use core_arch::arch::arm::*;
26"#;
library/stdarch/crates/intrinsic-test/src/arm/intrinsic.rs+3-3
......@@ -2,9 +2,9 @@ use crate::common::intrinsic_helpers::IntrinsicType;
22use std::ops::{Deref, DerefMut};
33
44#[derive(Debug, Clone, PartialEq)]
5pub struct ArmIntrinsicType(pub IntrinsicType);
5pub struct ArmType(pub IntrinsicType);
66
7impl Deref for ArmIntrinsicType {
7impl Deref for ArmType {
88 type Target = IntrinsicType;
99
1010 fn deref(&self) -> &Self::Target {
......@@ -12,7 +12,7 @@ impl Deref for ArmIntrinsicType {
1212 }
1313}
1414
15impl DerefMut for ArmIntrinsicType {
15impl DerefMut for ArmType {
1616 fn deref_mut(&mut self) -> &mut Self::Target {
1717 &mut self.0
1818 }
library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs+9-11
......@@ -1,4 +1,5 @@
1use super::intrinsic::ArmIntrinsicType;
1use super::intrinsic::ArmType;
2use crate::arm::Arm;
23use crate::arm::types::parse_intrinsic_type;
34use crate::common::argument::{Argument, ArgumentList};
45use crate::common::constraint::Constraint;
......@@ -59,7 +60,7 @@ struct JsonIntrinsic {
5960
6061pub fn get_neon_intrinsics(
6162 filename: &Path,
62) -> Result<Vec<Intrinsic<ArmIntrinsicType>>, Box<dyn std::error::Error>> {
63) -> Result<Vec<Intrinsic<Arm>>, Box<dyn std::error::Error>> {
6364 let file = std::fs::File::open(filename)?;
6465 let reader = std::io::BufReader::new(file);
6566 let json: Vec<JsonIntrinsic> = serde_json::from_reader(reader).expect("Couldn't parse JSON");
......@@ -79,10 +80,10 @@ pub fn get_neon_intrinsics(
7980
8081fn json_to_intrinsic(
8182 mut intr: JsonIntrinsic,
82) -> Result<Intrinsic<ArmIntrinsicType>, Box<dyn std::error::Error>> {
83) -> Result<Intrinsic<Arm>, Box<dyn std::error::Error>> {
8384 let name = intr.name.replace(['[', ']'], "");
8485
85 let result_ty = ArmIntrinsicType(parse_intrinsic_type(&intr.return_type.value)?);
86 let result_ty = ArmType(parse_intrinsic_type(&intr.return_type.value)?);
8687
8788 let args = intr
8889 .arguments
......@@ -120,12 +121,8 @@ fn json_to_intrinsic(
120121 }
121122 });
122123
123 let mut arg = Argument::<ArmIntrinsicType>::new(
124 i,
125 String::from(arg_name),
126 ArmIntrinsicType(arg_ty),
127 constraint,
128 );
124 let mut arg =
125 Argument::<Arm>::new(i, String::from(arg_name), ArmType(arg_ty), constraint);
129126
130127 // The JSON doesn't list immediates as const
131128 let IntrinsicType {
......@@ -138,13 +135,14 @@ fn json_to_intrinsic(
138135 })
139136 .collect();
140137
141 let arguments = ArgumentList::<ArmIntrinsicType> { args };
138 let arguments = ArgumentList::<Arm> { args };
142139
143140 Ok(Intrinsic {
144141 name,
145142 arguments,
146143 results: result_ty,
147144 arch_tags: intr.architectures,
145 extension: intr.simd_isa,
148146 })
149147}
150148
library/stdarch/crates/intrinsic-test/src/arm/mod.rs+98-18
......@@ -1,42 +1,48 @@
1mod config;
21mod intrinsic;
32mod json_parser;
43mod types;
54
6use crate::common::SupportedArchitectureTest;
5use crate::common::SupportedArchitecture;
76use crate::common::cli::{CcArgStyle, ProcessedCli};
87use crate::common::intrinsic::Intrinsic;
9use crate::common::intrinsic_helpers::TypeKind;
10use intrinsic::ArmIntrinsicType;
8use crate::common::intrinsic_helpers::{SimdLen, TypeKind};
9use intrinsic::ArmType;
1110use json_parser::get_neon_intrinsics;
1211
13pub struct ArmArchitectureTest {
14 intrinsics: Vec<Intrinsic<ArmIntrinsicType>>,
15}
12#[derive(PartialEq)]
13pub struct Arm(Vec<Intrinsic<Arm>>);
1614
17impl SupportedArchitectureTest for ArmArchitectureTest {
18 type IntrinsicImpl = ArmIntrinsicType;
15impl SupportedArchitecture for Arm {
16 type Type = ArmType;
1917
20 fn intrinsics(&self) -> &[Intrinsic<ArmIntrinsicType>] {
21 &self.intrinsics
18 fn intrinsics(&self) -> &[Intrinsic<Self>] {
19 &self.0
2220 }
2321
24 const NOTICE: &str = config::NOTICE;
25
26 const PLATFORM_C_HEADERS: &[&str] = &["arm_neon.h", "arm_acle.h", "arm_fp16.h"];
22 const NOTICE: &str = r#"
23// This is a transient test file, not intended for distribution. Some aspects of the
24// test are derived from a JSON specification, published under the same license as the
25// `intrinsic-test` crate.
26"#;
2727
28 const PLATFORM_RUST_DEFINITIONS: &str = config::PLATFORM_RUST_DEFINITIONS;
29 const PLATFORM_RUST_CFGS: &str = config::PLATFORM_RUST_CFGS;
28 const C_PRELUDE: &str = r#"
29#include <arm_acle.h>
30#include <arm_fp16.h>
31#include <arm_neon.h>
32"#;
33 const RUST_PRELUDE: &str = RUST_PRELUDE;
3034
31 fn arch_flags(&self, cli_options: &ProcessedCli) -> Vec<&str> {
35 fn c_compiler_flags(&self, cli_options: &ProcessedCli) -> Vec<&str> {
3236 // GCC uses an extra `-` in the arch name
3337 match cli_options.cc_arg_style {
3438 CcArgStyle::Clang => vec!["-march=armv8.6a+crypto+crc+dotprod+fp16"],
39 // SVE tests aren't run under GCC so there are no target features added for SVE
3540 CcArgStyle::Gcc => vec!["-march=armv8.6-a+crypto+crc+dotprod+fp16+sha3+sm4"],
3641 }
3742 }
3843
3944 fn create(cli_options: &ProcessedCli) -> Self {
45 let big_endian = cli_options.target.starts_with("aarch64_be");
4046 let a32 = cli_options.target.starts_with("armv7");
4147 let mut intrinsics =
4248 get_neon_intrinsics(&cli_options.filename).expect("Error parsing input file");
......@@ -54,6 +60,53 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
5460 // Skip bfloat intrinsics - not currently supported
5561 .filter(|i| i.results.kind() != TypeKind::BFloat)
5662 .filter(|i| !i.arguments.iter().any(|a| a.ty.kind() == TypeKind::BFloat))
63 // Skip SVE intrinsics that have `f16` - not yet implemented!
64 .filter(|i| {
65 let has_f16_arg = i
66 .arguments
67 .iter()
68 .any(|a| a.ty.kind() == TypeKind::Float && a.ty.bit_len == Some(16));
69 let has_sve_arg = i
70 .arguments
71 .iter()
72 .any(|a| a.ty.simd_len == Some(SimdLen::Scalable));
73 !(has_f16_arg && has_sve_arg)
74 })
75 .filter(|i| {
76 let has_f16_ret =
77 i.results.kind() == TypeKind::Float && i.results.bit_len == Some(16);
78 let has_sve_ret = i.results.simd_len == Some(SimdLen::Scalable);
79 !(has_f16_ret && has_sve_ret)
80 })
81 // Skip `svqcvtn{u,}n*_x2` intrinsics - not yet implemented!
82 .filter(|i| !(i.name.starts_with("svqcvtn") && i.name.ends_with("_x2")))
83 // Skip `svqrshr{u,}n*_x2` intrinsics - not yet implemented!
84 .filter(|i| !(i.name.starts_with("svqrshrn") && i.name.ends_with("_x2")))
85 .filter(|i| !(i.name.starts_with("svqrshrun") && i.name.ends_with("_x2")))
86 // Skip `svclamp*` intrinsics - not yet implemented!
87 .filter(|i| !i.name.starts_with("svclamp"))
88 // Skip `svdot{_lane,}_{s,u}32_{s,u}16` intrinsics - not yet implemented!
89 .filter(|i| {
90 i.name != "svdot_lane_u32_u16"
91 && i.name != "svdot_lane_s32_s16"
92 && i.name != "svdot_u32_u16"
93 && i.name != "svdot_s32_s16"
94 })
95 // Skip `svrevd*` intrinsics - not yet implemented!
96 .filter(|i| !i.name.starts_with("svrevd"))
97 // Skip `svpsel_lane_b*` intrinsics - not yet implemented!
98 .filter(|i| !i.name.starts_with("svpsel_lane_b"))
99 // Skip `svundef*` intrinsics - to avoid undefined behaviour in Rust, these return
100 // zeroed vectors in Rust, which are inherently going to be different than the
101 // undefined vectors returned by the C intrinsics.
102 .filter(|i| !i.name.starts_with("svundef"))
103 // Skip `sveorv` intrinsics - the code produced by `intrinsic-test` for these
104 // miscompiles and the Rust intrinsic call gets replaced by a constant zero (see
105 // llvm/llvm-project#203921).
106 .filter(|i| !i.name.starts_with("sveorv"))
107 // These load intrinsics expect each element in the scalable vector `bases` argument to
108 // be able to be cast to a pointer, which we don't support generating tests for yet.
109 .filter(|i| !(i.name.starts_with("svld") && i.name.contains("_gather_")))
57110 // Skip pointers for now, we would probably need to look at the return
58111 // type to work out how many elements we need to point to.
59112 .filter(|i| !i.arguments.iter().any(|a| a.is_ptr()))
......@@ -63,9 +116,36 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
63116 .filter(|i| !cli_options.skip.contains(&i.name))
64117 // Skip A64-specific intrinsics on A32
65118 .filter(|i| !(a32 && i.arch_tags == vec!["A64".to_string()]))
119 // Skip SVE intrinsics on big endian
120 .filter(|i| !(big_endian && (i.extension == "SVE" || i.extension == "SVE2")))
121 // Skip SVE intrinsics when testing against GCC as our wrappers run into ICEs
122 // See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125818>
123 .filter(|i| {
124 !(matches!(cli_options.cc_arg_style, CcArgStyle::Gcc)
125 && (i.extension == "SVE" || i.extension == "SVE2"))
126 })
66127 .take(sample_size)
67128 .collect::<Vec<_>>();
68129
69 Self { intrinsics }
130 Self(intrinsics)
70131 }
71132}
133
134const RUST_PRELUDE: &str = r#"
135#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]
136#![cfg_attr(target_arch = "arm", feature(stdarch_aarch32_crc32))]
137#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fcma))]
138#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_i8mm))]
139#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_sm4))]
140#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_ftts))]
141#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_feat_lut))]
142#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fp8))]
143#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(faminmax))]
144#![feature(stdarch_neon_f16)]
145
146#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
147use core_arch::arch::aarch64::*;
148
149#[cfg(target_arch = "arm")]
150use core_arch::arch::arm::*;
151"#;
library/stdarch/crates/intrinsic-test/src/arm/types.rs+57-35
......@@ -1,28 +1,37 @@
1use super::intrinsic::ArmIntrinsicType;
2use crate::common::intrinsic_helpers::{
3 IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind,
4};
1use super::intrinsic::ArmType;
2use crate::common::intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind};
53
6impl IntrinsicTypeDefinition for ArmIntrinsicType {
4impl TypeDefinition for ArmType {
75 /// Gets a string containing the typename for this type in C format.
86 fn c_type(&self) -> String {
97 let prefix = self.kind.c_prefix();
108
11 if let Some(bit_len) = self.bit_len {
12 match (self.simd_len, self.vec_len) {
13 (None, None) => format!("{prefix}{bit_len}_t"),
14 (Some(SimdLen::Fixed(simd)), None) => format!("{prefix}{bit_len}x{simd}_t"),
15 (Some(SimdLen::Fixed(simd)), Some(vec)) => {
16 format!("{prefix}{bit_len}x{simd}x{vec}_t")
17 }
18 (Some(SimdLen::Scalable), None) => format!("sv{prefix}{bit_len}_t"),
19 (Some(SimdLen::Scalable), Some(vec)) => {
20 format!("sv{prefix}{bit_len}x{vec}_t")
21 }
22 (None, Some(_)) => todo!("{self:#?}"), // Likely an invalid case
9 match (self.bit_len, self.simd_len, self.vec_len) {
10 // e.g. `bool`
11 (Some(_), None, None) if matches!(self.kind, TypeKind::Bool) => {
12 format!("{prefix}")
2313 }
24 } else {
25 todo!("{self:#?}")
14 // e.g. `float32_t`, `int64_t`
15 (Some(bit_len), None, None) => format!("{prefix}{bit_len}_t"),
16 // e.g. `float32x2_t`, `int64x2_t`
17 (Some(bit_len), Some(SimdLen::Fixed(simd)), None) => {
18 format!("{prefix}{bit_len}x{simd}_t")
19 }
20 // e.g. `float32x2x3_t`, `int64x2x3_t`
21 (Some(bit_len), Some(SimdLen::Fixed(simd)), Some(vec)) => {
22 format!("{prefix}{bit_len}x{simd}x{vec}_t")
23 }
24 // e.g. `svbool_t`
25 (Some(_), Some(SimdLen::Scalable), None) if matches!(self.kind, TypeKind::Bool) => {
26 format!("sv{prefix}_t")
27 }
28 // e.g. `svfloat32_t`, `svint64_t`
29 (Some(bit_len), Some(SimdLen::Scalable), None) => format!("sv{prefix}{bit_len}_t"),
30 // e.g. `svfloat32x3_t`, `svint64x3_t`
31 (Some(bit_len), Some(SimdLen::Scalable), Some(vec)) => {
32 format!("sv{prefix}{bit_len}x{vec}_t")
33 }
34 _ => todo!("{self:#?}"),
2635 }
2736 }
2837
......@@ -30,26 +39,39 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
3039 let rust_prefix = self.kind.rust_prefix();
3140 let c_prefix = self.kind.c_prefix();
3241
33 if let Some(bit_len) = self.bit_len {
34 match (self.simd_len, self.vec_len) {
35 (None, None) => format!("{rust_prefix}{bit_len}"),
36 (Some(SimdLen::Fixed(simd)), None) => format!("{c_prefix}{bit_len}x{simd}_t"),
37 (Some(SimdLen::Fixed(simd)), Some(vec)) => {
38 format!("{c_prefix}{bit_len}x{simd}x{vec}_t")
39 }
40 (Some(SimdLen::Scalable), None) => format!("sv{c_prefix}{bit_len}_t"),
41 (Some(SimdLen::Scalable), Some(vec)) => {
42 format!("sv{c_prefix}{bit_len}x{vec}_t")
43 }
44 (None, Some(_)) => todo!("{self:#?}"), // Likely an invalid case
42 match (self.bit_len, self.simd_len, self.vec_len) {
43 // e.g. `svpattern`
44 (None, _, _) => format!("{rust_prefix}"),
45 // e.g. `bool`
46 (Some(_), None, None) if matches!(self.kind, TypeKind::Bool) => {
47 format!("{rust_prefix}")
4548 }
46 } else {
47 todo!("{self:#?}")
49 // e.g. `i32`
50 (Some(bit_len), None, None) => format!("{rust_prefix}{bit_len}"),
51 // e.g. `int32x2_t`
52 (Some(bit_len), Some(SimdLen::Fixed(simd)), None) => {
53 format!("{c_prefix}{bit_len}x{simd}_t")
54 }
55 // e.g. `int32x2x3_t`
56 (Some(bit_len), Some(SimdLen::Fixed(simd)), Some(vec)) => {
57 format!("{c_prefix}{bit_len}x{simd}x{vec}_t")
58 }
59 // e.g. `svbool_t`
60 (Some(_), Some(SimdLen::Scalable), None) if matches!(self.kind, TypeKind::Bool) => {
61 format!("sv{c_prefix}_t")
62 }
63 // e.g. `svint32_t`
64 (Some(bit_len), Some(SimdLen::Scalable), None) => format!("sv{c_prefix}{bit_len}_t"),
65 // e.g. `svint32x3_t`
66 (Some(bit_len), Some(SimdLen::Scalable), Some(vec)) => {
67 format!("sv{c_prefix}{bit_len}x{vec}_t")
68 }
69 (Some(_), None, Some(_)) => todo!("{self:#?}"),
4870 }
4971 }
5072
5173 /// Determines the load function for this type.
52 fn get_load_function(&self) -> String {
74 fn load_function(&self) -> String {
5375 if let IntrinsicType {
5476 kind: k,
5577 bit_len: Some(bl),
......@@ -73,7 +95,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType {
7395 len = vec_len.unwrap_or(1),
7496 )
7597 } else {
76 todo!("get_load_function IntrinsicType: {self:#?}")
98 todo!("load_function IntrinsicType: {self:#?}")
7799 }
78100 }
79101}
library/stdarch/crates/intrinsic-test/src/common/argument.rs+15-14
......@@ -1,30 +1,31 @@
11use itertools::Itertools;
22
3use crate::common::SupportedArchitecture;
34use crate::common::intrinsic_helpers::TypeKind;
45use crate::common::values::test_values_array_name;
56
67use super::PASSES;
78use super::constraint::Constraint;
8use super::intrinsic_helpers::IntrinsicTypeDefinition;
9use super::intrinsic_helpers::TypeDefinition;
910
1011/// An argument for the intrinsic.
1112#[derive(Debug, PartialEq, Clone)]
12pub struct Argument<T: IntrinsicTypeDefinition> {
13pub struct Argument<A: SupportedArchitecture> {
1314 /// The argument's index in the intrinsic function call.
1415 pub pos: usize,
1516 /// The argument name.
1617 pub name: String,
1718 /// The type of the argument.
18 pub ty: T,
19 pub ty: A::Type,
1920 /// Any constraints that are on this argument
2021 pub constraint: Option<Constraint>,
2122}
2223
23impl<T> Argument<T>
24impl<A> Argument<A>
2425where
25 T: IntrinsicTypeDefinition,
26 A: SupportedArchitecture,
2627{
27 pub fn new(pos: usize, name: String, ty: T, constraint: Option<Constraint>) -> Self {
28 pub fn new(pos: usize, name: String, ty: A::Type, constraint: Option<Constraint>) -> Self {
2829 Argument {
2930 pos,
3031 name,
......@@ -63,13 +64,13 @@ where
6364
6465/// Arguments of an intrinsic - including parameters that end up being const generics.
6566#[derive(Debug, PartialEq, Clone)]
66pub struct ArgumentList<T: IntrinsicTypeDefinition> {
67 pub args: Vec<Argument<T>>,
67pub struct ArgumentList<A: SupportedArchitecture> {
68 pub args: Vec<Argument<A>>,
6869}
6970
70impl<T> ArgumentList<T>
71impl<A> ArgumentList<A>
7172where
72 T: IntrinsicTypeDefinition,
73 A: SupportedArchitecture,
7374{
7475 /// Returns a string with the arguments in `self` as a parameter list for a wrapper fn
7576 /// definition in C (e.g. `$ty1 $arg1, $ty2 $arg2`).
......@@ -179,14 +180,14 @@ where
179180 .map(|(idx, arg)| {
180181 if arg.is_simd() {
181182 format!(
182 "let {name} = {load}({vals_name}.as_ptr().add((i+{idx}) % {PASSES}) as _);\n",
183 "let {name} = {load}({vals_name}.as_ptr().add((i+{idx}) % {PASSES}) as _);",
183184 name = arg.generate_name(),
184185 vals_name = test_values_array_name(&arg.ty),
185 load = arg.ty.get_load_function(),
186 load = arg.ty.load_function(),
186187 )
187188 } else {
188189 format!(
189 "let {name} = {vals_name}[(i+{idx}) % {PASSES}];\n",
190 "let {name} = {vals_name}[(i+{idx}) % {PASSES}];",
190191 name = arg.generate_name(),
191192 vals_name = test_values_array_name(&arg.ty),
192193 )
......@@ -196,7 +197,7 @@ where
196197 }
197198
198199 /// Returns an iterator over the contained arguments
199 pub fn iter(&self) -> std::slice::Iter<'_, Argument<T>> {
200 pub fn iter(&self) -> std::slice::Iter<'_, Argument<A>> {
200201 self.args.iter()
201202 }
202203}
library/stdarch/crates/intrinsic-test/src/common/gen_c.rs+6-11
......@@ -1,8 +1,8 @@
11use itertools::Itertools;
22
3use crate::common::intrinsic::Intrinsic;
3use crate::common::{SupportedArchitecture, intrinsic::Intrinsic};
44
5use super::intrinsic_helpers::IntrinsicTypeDefinition;
5use super::intrinsic_helpers::TypeDefinition;
66
77/// Generates a C source file containing wrapper functions around each specialisation of each
88/// intrinsic (that is, intrinsics with specific values for the the immediate arguments). Each
......@@ -14,20 +14,15 @@ use super::intrinsic_helpers::IntrinsicTypeDefinition;
1414/// *__dst = __crc32cd(a, b);
1515/// }
1616/// ```
17pub fn write_wrapper_c<T: IntrinsicTypeDefinition>(
17pub fn write_wrapper_c<A: SupportedArchitecture>(
1818 w: &mut impl std::io::Write,
19 notice: &str,
20 platform_headers: &[&str],
21 intrinsics: &[Intrinsic<T>],
19 intrinsics: &[Intrinsic<A>],
2220) -> std::io::Result<()> {
23 write!(w, "{notice}")?;
21 write!(w, "{}", A::NOTICE)?;
2422
2523 writeln!(w, "#include <stdint.h>")?;
2624 writeln!(w, "#include <stddef.h>")?;
27
28 for header in platform_headers {
29 writeln!(w, "#include <{header}>")?;
30 }
25 writeln!(w, "{}", A::C_PRELUDE)?;
3126
3227 for intrinsic in intrinsics {
3328 intrinsic.iter_specializations(|imm_values| {
library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs+95-133
......@@ -2,12 +2,11 @@ use std::process::Command;
22
33use itertools::Itertools;
44
5use super::intrinsic_helpers::IntrinsicTypeDefinition;
6use crate::common::PASSES;
5use super::intrinsic_helpers::TypeDefinition;
76use crate::common::cli::{CcArgStyle, ProcessedCli};
87use crate::common::intrinsic::Intrinsic;
9use crate::common::intrinsic_helpers::TypeKind;
108use crate::common::values::{test_values_array_name, test_values_array_static};
9use crate::common::{PASSES, SupportedArchitecture};
1110
1211/// Rust definitions that are included verbatim in the generated source. In particular, defines
1312/// a wrapper around float types that defines `NaN`s to be equal reflexively to enable
......@@ -32,12 +31,6 @@ macro_rules! wrap_partialeq {
3231wrap_partialeq!(NanEqF16(f16), NanEqF32(f32), NanEqF64(f64));
3332"#;
3433
35macro_rules! concatln {
36 ($($lines:expr),* $(,)?) => {
37 concat!($( $lines, "\n" ),*)
38 };
39}
40
4134/// Run rustfmt on the generated source code
4235pub fn run_rustfmt(source_path: &str) {
4336 let output = Command::new("rustfmt")
......@@ -65,11 +58,14 @@ pub fn write_bin_cargo_toml(
6558 w: &mut impl std::io::Write,
6659 module_count: usize,
6760) -> std::io::Result<()> {
68 write!(w, concatln!("[workspace]", "members = ["))?;
69 for i in 0..module_count {
70 writeln!(w, " \"mod_{i}\",")?;
71 }
72 writeln!(w, "]")
61 write!(
62 w,
63 r#"
64[workspace]
65members = [{members}]
66"#,
67 members = (0..module_count).format_with(",", |i, fmt| fmt(&format_args!("\"mod_{i}\"")))
68 )
7369}
7470
7571/// Writes a `Cargo.toml` for a crate with name `name` to `w` that will contain a single Rust source
......@@ -77,21 +73,20 @@ pub fn write_bin_cargo_toml(
7773pub fn write_lib_cargo_toml(w: &mut impl std::io::Write, name: &str) -> std::io::Result<()> {
7874 write!(
7975 w,
80 concatln!(
81 "[package]",
82 "name = \"{name}\"",
83 "version = \"{version}\"",
84 "authors = [{authors}]",
85 "license = \"{license}\"",
86 "edition = \"2018\"",
87 "",
88 "[dependencies]",
89 "core_arch = {{ path = \"../../crates/core_arch\" }}",
90 "",
91 "[build-dependencies]",
92 "cc = \"1\""
93 ),
94 name = name,
76 r#"
77[package]
78name = "{name}"
79version = "{version}"
80authors = [{authors}]
81license = "{license}"
82edition = "2018"
83
84[dependencies]
85core_arch = {{ path = "../../crates/core_arch" }}
86
87[build-dependencies]
88cc = "1"
89"#,
9590 version = env!("CARGO_PKG_VERSION"),
9691 authors = env!("CARGO_PKG_AUTHORS")
9792 .split(":")
......@@ -102,30 +97,30 @@ pub fn write_lib_cargo_toml(w: &mut impl std::io::Write, name: &str) -> std::io:
10297
10398/// Writes a Rust source file into `w` with common definitions, static arrays with test values,
10499/// declarations of C wrapper functions for FFI and Rust test functions.
105pub fn write_lib_rs<T: IntrinsicTypeDefinition>(
100pub fn write_lib_rs<A: SupportedArchitecture>(
106101 w: &mut impl std::io::Write,
107 notice: &str,
108 cfg: &str,
109 definitions: &str,
110102 i: usize,
111 intrinsics: &[Intrinsic<T>],
103 intrinsics: &[Intrinsic<A>],
112104) -> std::io::Result<()> {
113 write!(w, "{notice}")?;
114
115 writeln!(w, "#![feature(simd_ffi)]")?;
116 writeln!(w, "#![feature(f16)]")?;
117 writeln!(w, "#![allow(unused)]")?;
118
119 // Cargo will spam the logs if these warnings are not silenced.
120 writeln!(w, "#![allow(non_upper_case_globals)]")?;
121 writeln!(w, "#![allow(non_camel_case_types)]")?;
122 writeln!(w, "#![allow(non_snake_case)]")?;
123
124 writeln!(w, "{cfg}")?;
125
126 writeln!(w, "{}", COMMON_RUST_DEFINITIONS)?;
127
128 writeln!(w, "{definitions}")?;
105 writeln!(
106 w,
107 r#"
108{notice}
109#![feature(simd_ffi)]
110#![feature(f16)]
111#![allow(unused)]
112
113// Cargo will spam the logs if these warnings are not silenced.
114#![allow(non_upper_case_globals)]
115#![allow(non_camel_case_types)]
116#![allow(non_snake_case)]
117
118{prelude}
119{COMMON_RUST_DEFINITIONS}
120"#,
121 notice = A::NOTICE,
122 prelude = A::RUST_PRELUDE,
123 )?;
129124
130125 let mut seen = std::collections::HashSet::new();
131126
......@@ -157,9 +152,9 @@ pub fn write_lib_rs<T: IntrinsicTypeDefinition>(
157152/// (first loop) `PASSES` number of times (second loop). For a given iteration of a given
158153/// specialisation, test values are loaded for each argument and passed to the Rust intrinsic
159154/// and the C wrapper function, and the results are compared.
160fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
155fn generate_rust_test_loop<A: SupportedArchitecture>(
161156 w: &mut impl std::io::Write,
162 intrinsic: &Intrinsic<T>,
157 intrinsic: &Intrinsic<A>,
163158) -> std::io::Result<()> {
164159 let intrinsic_name = &intrinsic.name;
165160
......@@ -199,67 +194,45 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
199194 writeln!(w, " ];")?;
200195 }
201196
202 let (cast_prefix, cast_suffix) = if intrinsic.results.is_simd() {
203 (
204 format!(
205 "std::mem::transmute::<_, [{}; {}]>(",
206 intrinsic.results.rust_scalar_type().replace("f", "NanEqF"),
207 intrinsic.results.num_lanes() * intrinsic.results.num_vectors()
208 ),
209 ")",
210 )
211 } else if intrinsic.results.kind == TypeKind::Float {
212 (
213 match intrinsic.results.inner_size() {
214 16 => format!("NanEqF16("),
215 32 => format!("NanEqF32("),
216 64 => format!("NanEqF64("),
217 _ => unimplemented!(),
218 },
219 ")",
220 )
221 } else {
222 ("".to_string(), "")
223 };
224
225197 write!(
226198 w,
227 concatln!(
228 " for (id, rust, c) in specializations {{",
229 " for i in 0..{passes} {{",
230 " unsafe {{",
231 "{loaded_args}",
232 " let __rust_return_value = rust({rust_args});",
233 "",
234 " let mut __c_return_value = std::mem::MaybeUninit::uninit();",
235 " c(__c_return_value.as_mut_ptr(){c_args});",
236 " let __c_return_value = __c_return_value.assume_init();",
237 "",
238 " assert_eq!({cast_prefix}__rust_return_value{cast_suffix}, {cast_prefix}__c_return_value{cast_suffix}, \"{{id}}\");",
239 " }}",
240 " }}",
241 " }}",
242 ),
199 r#"
200for (id, rust, c) in specializations {{
201 for i in 0..{PASSES} {{
202 unsafe {{
203 {loaded_args}
204 let __rust_return_value = rust({rust_args});
205
206 let mut __c_return_value = std::mem::MaybeUninit::uninit();
207 c(__c_return_value.as_mut_ptr(){c_args});
208 let __c_return_value = __c_return_value.assume_init();
209
210 {comparison}
211 }}
212 }}
213}}
214"#,
243215 loaded_args = intrinsic.arguments.load_values_rust(),
244216 rust_args = intrinsic.arguments.as_call_param_rust(),
245217 c_args = intrinsic.arguments.as_c_call_param_rust(),
246 passes = PASSES,
247 cast_prefix = cast_prefix,
248 cast_suffix = cast_suffix,
218 comparison = intrinsic.results.comparison_function(),
249219 )
250220}
251221
252222/// Writes a test function for an given intrinsic to `w`, with a body generated by
253223/// `generate_rust_test_loop`.
254fn create_rust_test<T: IntrinsicTypeDefinition>(
224fn create_rust_test<A: SupportedArchitecture>(
255225 w: &mut impl std::io::Write,
256 intrinsic: &Intrinsic<T>,
226 intrinsic: &Intrinsic<A>,
257227) -> std::io::Result<()> {
258228 trace!("generating `{}`", intrinsic.name);
259229
260230 write!(
261231 w,
262 concatln!("#[test]", "fn test_{intrinsic_name}() {{"),
232 r#"
233#[test]
234fn test_{intrinsic_name}() {{
235"#,
263236 intrinsic_name = intrinsic.name,
264237 )?;
265238
......@@ -272,26 +245,25 @@ fn create_rust_test<T: IntrinsicTypeDefinition>(
272245
273246/// Writes an `extern "C"` block with function declarations for each of the C wrapper functions into
274247/// `w`.
275pub fn write_bindings_rust<T: IntrinsicTypeDefinition>(
248pub fn write_bindings_rust<A: SupportedArchitecture>(
276249 w: &mut impl std::io::Write,
277250 i: usize,
278 intrinsics: &[Intrinsic<T>],
251 intrinsics: &[Intrinsic<A>],
279252) -> std::io::Result<()> {
280253 write!(
281254 w,
282 concatln!(
283 "#[allow(improper_ctypes)]",
284 "#[link(name = \"wrapper_{i}\")]",
285 "unsafe extern \"C\" {{"
286 ),
287 i = i
255 r#"
256#[allow(improper_ctypes)]
257#[link(name = "wrapper_{i}")]
258unsafe extern "C" {{
259"#,
288260 )?;
289261
290262 for intrinsic in intrinsics {
291263 intrinsic.iter_specializations(|imm_values| {
292264 writeln!(
293265 w,
294 " fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});",
266 "fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});",
295267 return_ty = intrinsic.results.rust_type(),
296268 name = intrinsic.name,
297269 imm_arglist = imm_values
......@@ -326,32 +298,22 @@ pub fn write_build_rs(
326298
327299 write!(
328300 w,
329 concatln!(
330 "fn main() {{",
331 " cc::Build::new()",
332 " .file(\"../../c_programs/wrapper_{i}.c\")",
333 " .opt_level(2)",
334 " .flags(&[",
335 ),
336 i = i
337 )?;
338
339 let compiler_specific_flags = match cli_options.cc_arg_style {
340 CcArgStyle::Gcc => GCC_FLAGS,
341 CcArgStyle::Clang => CLANG_FLAGS,
342 };
343
344 for flag in COMMON_FLAGS
345 .iter()
346 .chain(compiler_specific_flags)
347 .chain(arch_flags)
348 {
349 writeln!(w, "\"{flag}\",")?;
350 }
351
352 write!(
353 w,
354 concatln!(" ])", " .compile(\"wrapper_{i}\");", "}}"),
355 i = i
301 r#"
302fn main() {{
303 cc::Build::new()
304 .file("../../c_programs/wrapper_{i}.c")
305 .opt_level(2)
306 .flags(&[{flags}])
307 .compile("wrapper_{i}");
308}}
309"#,
310 flags = COMMON_FLAGS
311 .iter()
312 .chain(match cli_options.cc_arg_style {
313 CcArgStyle::Gcc => GCC_FLAGS,
314 CcArgStyle::Clang => CLANG_FLAGS,
315 })
316 .chain(arch_flags)
317 .format_with(",", |flag, fmt| fmt(&format_args!("\"{flag}\""))),
356318 )
357319}
library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs+8-7
......@@ -1,22 +1,23 @@
1use crate::common::constraint::Constraint;
2
31use super::argument::ArgumentList;
4use super::intrinsic_helpers::IntrinsicTypeDefinition;
2use crate::common::{SupportedArchitecture, constraint::Constraint};
53
64/// An intrinsic
75#[derive(Debug, PartialEq, Clone)]
8pub struct Intrinsic<T: IntrinsicTypeDefinition> {
6pub struct Intrinsic<A: SupportedArchitecture> {
97 /// The function name of this intrinsic.
108 pub name: String,
119
1210 /// Any arguments for this intrinsic.
13 pub arguments: ArgumentList<T>,
11 pub arguments: ArgumentList<A>,
1412
1513 /// The return type of this intrinsic.
16 pub results: T,
14 pub results: A::Type,
1715
1816 /// Any architecture-specific tags.
1917 pub arch_tags: Vec<String>,
18
19 /// Specific extension that the intrinsic is from
20 pub extension: String,
2021}
2122
2223/// Invokes `f` for each combination of the values in the constraint ranges.
......@@ -40,7 +41,7 @@ fn recurse_specializations<'a, E>(
4041 }
4142}
4243
43impl<T: IntrinsicTypeDefinition> Intrinsic<T> {
44impl<A: SupportedArchitecture> Intrinsic<A> {
4445 /// Invokes `f` for "specialisation" of the intrinsic - a specific instantiation of the
4546 /// constant generics of the intrinsic. `f` takes a slice where the `i`th element corresponds
4647 /// to the value of the `i`th const generic argument of the intrinsic.
library/stdarch/crates/intrinsic-test/src/common/intrinsic_helpers.rs+63-14
......@@ -1,6 +1,6 @@
11use std::cmp;
22use std::fmt;
3use std::ops::Deref;
3use std::ops::DerefMut;
44use std::str::FromStr;
55
66#[derive(Debug, PartialEq, Copy, Clone)]
......@@ -90,9 +90,13 @@ impl TypeKind {
9090 }
9191 }
9292
93 /// Returns the Rust prefix for this type kind i.e. `i`, `u`, or `f`.
93 /// Returns the Rust prefix for this type kind (i.e. `i` for `i16`, or `u` for `u16`). For type
94 /// kinds without any bit length at the end (e.g. `bool`), returns the whole type name.
9495 pub fn rust_prefix(&self) -> &str {
9596 match self {
97 Self::Bool => "bool",
98 Self::SvPattern => "svpattern",
99 Self::SvPrefetchOp => "svprfop",
96100 Self::BFloat => "bf",
97101 Self::Float => "f",
98102 Self::Int(Sign::Signed) => "i",
......@@ -101,7 +105,7 @@ impl TypeKind {
101105 Self::Char(Sign::Unsigned) => "u",
102106 Self::Char(Sign::Signed) => "i",
103107 Self::Mask => "u",
104 _ => unreachable!("Unused type kind: {self:#?}"),
108 _ => unreachable!("type kind without Rust prefix: {self:#?}"),
105109 }
106110 }
107111}
......@@ -195,9 +199,19 @@ impl IntrinsicType {
195199 }
196200}
197201
198pub trait IntrinsicTypeDefinition: Deref<Target = IntrinsicType> {
202pub trait TypeDefinition: Clone + DerefMut<Target = IntrinsicType> {
199203 /// Determines the load function for this type.
200 fn get_load_function(&self) -> String;
204 fn load_function(&self) -> String;
205
206 /// Determines the comparison function for this type.
207 fn comparison_function(&self) -> String {
208 match self.simd_len {
209 Some(SimdLen::Scalable) => unimplemented!("architecture-specific"),
210 Some(SimdLen::Fixed(_)) | None => {
211 default_fixed_vector_comparison(self, self.num_lanes())
212 }
213 }
214 }
201215
202216 /// Gets a string containing the typename for this type in C.
203217 fn c_type(&self) -> String;
......@@ -208,14 +222,49 @@ pub trait IntrinsicTypeDefinition: Deref<Target = IntrinsicType> {
208222 /// Gets a string containing the name of the scalar type corresponding to this type if it is a
209223 /// vector.
210224 fn rust_scalar_type(&self) -> String {
211 if self.is_simd() {
212 format!(
213 "{prefix}{bits}",
214 prefix = self.kind().rust_prefix(),
215 bits = self.inner_size()
216 )
217 } else {
218 self.rust_type()
219 }
225 let mut ty = self.clone();
226 ty.simd_len = None;
227 ty.vec_len = None;
228 ty.rust_type()
220229 }
221230}
231
232/// Returns the default comparison between results of an intrinsic - casting the vectors to arrays
233/// and using `assert_eq` - using `NanEqF*` where required for floats.
234pub(crate) fn default_fixed_vector_comparison<Ty: TypeDefinition>(
235 ty: &Ty,
236 num_lanes: u32,
237) -> String {
238 let (cast_prefix, cast_suffix) = if ty.is_simd() {
239 (
240 format!(
241 "std::mem::transmute::<_, [{}; {}]>(",
242 ty.rust_scalar_type().replace("f", "NanEqF"),
243 num_lanes * ty.num_vectors()
244 ),
245 ")",
246 )
247 } else if ty.kind == TypeKind::Float {
248 (
249 match ty.inner_size() {
250 16 => format!("NanEqF16("),
251 32 => format!("NanEqF32("),
252 64 => format!("NanEqF64("),
253 _ => unimplemented!(),
254 },
255 ")",
256 )
257 } else {
258 ("".to_string(), "")
259 };
260
261 format!(
262 r#"
263assert_eq!(
264 {cast_prefix}__rust_return_value{cast_suffix},
265 {cast_prefix}__c_return_value{cast_suffix},
266 "{{id}}"
267);
268"#,
269 )
270}
library/stdarch/crates/intrinsic-test/src/common/mod.rs+10-19
......@@ -10,7 +10,7 @@ use crate::common::{
1010 run_rustfmt, write_bin_cargo_toml, write_build_rs, write_lib_cargo_toml, write_lib_rs,
1111 },
1212 intrinsic::Intrinsic,
13 intrinsic_helpers::IntrinsicTypeDefinition,
13 intrinsic_helpers::TypeDefinition,
1414};
1515
1616pub mod argument;
......@@ -29,21 +29,19 @@ pub(crate) const PASSES: u32 = 20;
2929
3030/// Architectures must support this trait
3131/// to be successfully tested.
32pub trait SupportedArchitectureTest {
33 type IntrinsicImpl: IntrinsicTypeDefinition + Sync;
32pub trait SupportedArchitecture: Sized {
33 type Type: TypeDefinition + std::fmt::Debug + PartialEq + Sync;
3434
35 fn intrinsics(&self) -> &[Intrinsic<Self::IntrinsicImpl>];
35 fn intrinsics(&self) -> &[Intrinsic<Self>];
3636
3737 fn create(cli_options: &ProcessedCli) -> Self;
3838
3939 const NOTICE: &str;
4040
41 const PLATFORM_C_HEADERS: &[&str];
41 const C_PRELUDE: &str;
42 const RUST_PRELUDE: &str;
4243
43 const PLATFORM_RUST_CFGS: &str;
44 const PLATFORM_RUST_DEFINITIONS: &str;
45
46 fn arch_flags(&self, cli_options: &ProcessedCli) -> Vec<&str>;
44 fn c_compiler_flags(&self, cli_options: &ProcessedCli) -> Vec<&str>;
4745
4846 fn generate_c_file(&self) {
4947 let (max_chunk_size, _chunk_count) = manual_chunk(self.intrinsics().len());
......@@ -55,14 +53,14 @@ pub trait SupportedArchitectureTest {
5553 .map(|(i, chunk)| {
5654 let c_filename = format!("c_programs/wrapper_{i}.c");
5755 let mut file = File::create(&c_filename).unwrap();
58 write_wrapper_c(&mut file, Self::NOTICE, Self::PLATFORM_C_HEADERS, chunk)
56 write_wrapper_c(&mut file, chunk)
5957 })
6058 .collect::<io::Result<()>>()
6159 .unwrap();
6260 }
6361
6462 fn generate_rust_file(&self, cli_options: &ProcessedCli) {
65 let arch_flags = self.arch_flags(cli_options);
63 let arch_flags = self.c_compiler_flags(cli_options);
6664
6765 std::fs::create_dir_all("rust_programs").unwrap();
6866
......@@ -81,14 +79,7 @@ pub trait SupportedArchitectureTest {
8179 trace!("generating `{rust_filename}`");
8280 let mut file = File::create(&rust_filename)?;
8381
84 write_lib_rs(
85 &mut file,
86 Self::NOTICE,
87 Self::PLATFORM_RUST_CFGS,
88 Self::PLATFORM_RUST_DEFINITIONS,
89 i,
90 chunk,
91 )?;
82 write_lib_rs(&mut file, i, chunk)?;
9283 run_rustfmt(&rust_filename);
9384
9485 let toml_filename = format!("rust_programs/mod_{i}/Cargo.toml");
library/stdarch/crates/intrinsic-test/src/common/values.rs+4-4
......@@ -2,7 +2,7 @@ use itertools::Itertools as _;
22
33use crate::common::{
44 PASSES,
5 intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind},
5 intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind},
66};
77
88/// Maximum size of a SVE vector
......@@ -18,13 +18,13 @@ pub const MAX_SVE_BITS: u32 = 2048;
1818/// 0x80, 0x3b, 0xff,
1919/// ];
2020/// ```
21pub fn test_values_array_static<T: IntrinsicTypeDefinition>(
21pub fn test_values_array_static<T: TypeDefinition>(
2222 w: &mut impl std::io::Write,
2323 ty: &T,
2424) -> std::io::Result<()> {
2525 writeln!(
2626 w,
27 "static {name}: [{ty}; {load_size}] = {values};\n",
27 "static {name}: [{ty}; {load_size}] = {values};",
2828 name = test_values_array_name(ty),
2929 ty = ty.rust_scalar_type(),
3030 load_size = test_values_array_length(&ty),
......@@ -34,7 +34,7 @@ pub fn test_values_array_static<T: IntrinsicTypeDefinition>(
3434
3535/// Returns a string with the name of the static variable containing test values for intrinsic
3636/// arguments of this type.
37pub fn test_values_array_name<T: IntrinsicTypeDefinition>(ty: &T) -> String {
37pub fn test_values_array_name<T: TypeDefinition>(ty: &T) -> String {
3838 format!(
3939 "{ty}_{load_size}",
4040 ty = ty.rust_scalar_type().to_uppercase(),
library/stdarch/crates/intrinsic-test/src/main.rs+6-12
......@@ -5,10 +5,10 @@ mod arm;
55mod common;
66mod x86;
77
8use arm::ArmArchitectureTest;
9use common::SupportedArchitectureTest;
8use arm::Arm;
9use common::SupportedArchitecture;
1010use common::cli::{Cli, ProcessedCli};
11use x86::X86ArchitectureTest;
11use x86::X86;
1212
1313fn main() {
1414 pretty_env_logger::init();
......@@ -18,21 +18,15 @@ fn main() {
1818 if processed_cli_options.target.starts_with("arm")
1919 | processed_cli_options.target.starts_with("aarch64")
2020 {
21 run(
22 ArmArchitectureTest::create(&processed_cli_options),
23 processed_cli_options,
24 )
21 run(Arm::create(&processed_cli_options), processed_cli_options)
2522 } else if processed_cli_options.target.starts_with("x86") {
26 run(
27 X86ArchitectureTest::create(&processed_cli_options),
28 processed_cli_options,
29 )
23 run(X86::create(&processed_cli_options), processed_cli_options)
3024 } else {
3125 unimplemented!("Unsupported target {}", processed_cli_options.target)
3226 }
3327}
3428
35fn run(test_environment: impl SupportedArchitectureTest, processed_cli_options: ProcessedCli) {
29fn run(test_environment: impl SupportedArchitecture, processed_cli_options: ProcessedCli) {
3630 info!("building C binaries");
3731 test_environment.generate_c_file();
3832
library/stdarch/crates/intrinsic-test/src/x86/config.rs deleted-138
......@@ -1,138 +0,0 @@
1pub const NOTICE: &str = "\
2// This is a transient test file, not intended for distribution. Some aspects of the
3// test are derived from an XML specification, published under the same license as the
4// `intrinsic-test` crate.\n";
5
6pub const PLATFORM_RUST_DEFINITIONS: &str = r#"
7use core_arch::arch::x86_64::*;
8
9#[inline]
10unsafe fn _mm_loadu_ph_to___m128i(mem_addr: *const f16) -> __m128i {
11 _mm_castph_si128(_mm_loadu_ph(mem_addr))
12}
13
14#[inline]
15unsafe fn _mm256_loadu_ph_to___m256i(mem_addr: *const f16) -> __m256i {
16 _mm256_castph_si256(_mm256_loadu_ph(mem_addr))
17}
18
19#[inline]
20unsafe fn _mm512_loadu_ph_to___mm512i(mem_addr: *const f16) -> __m512i {
21 _mm512_castph_si512(_mm512_loadu_ph(mem_addr))
22}
23
24
25#[inline]
26unsafe fn _mm_loadu_ps_to___m128h(mem_addr: *const f32) -> __m128h {
27 _mm_castps_ph(_mm_loadu_ps(mem_addr))
28}
29
30#[inline]
31unsafe fn _mm256_loadu_ps_to___m256h(mem_addr: *const f32) -> __m256h {
32 _mm256_castps_ph(_mm256_loadu_ps(mem_addr))
33}
34
35#[inline]
36unsafe fn _mm512_loadu_ps_to___m512h(mem_addr: *const f32) -> __m512h {
37 _mm512_castps_ph(_mm512_loadu_ps(mem_addr))
38}
39
40#[inline]
41unsafe fn _mm_loadu_epi16_to___m128d(mem_addr: *const i16) -> __m128d {
42 _mm_castsi128_pd(_mm_loadu_epi16(mem_addr))
43}
44
45#[inline]
46unsafe fn _mm256_loadu_epi16_to___m256d(mem_addr: *const i16) -> __m256d {
47 _mm256_castsi256_pd(_mm256_loadu_epi16(mem_addr))
48}
49
50#[inline]
51unsafe fn _mm512_loadu_epi16_to___m512d(mem_addr: *const i16) -> __m512d {
52 _mm512_castsi512_pd(_mm512_loadu_epi16(mem_addr))
53}
54
55#[inline]
56unsafe fn _mm_loadu_epi32_to___m128d(mem_addr: *const i32) -> __m128d {
57 _mm_castsi128_pd(_mm_loadu_epi32(mem_addr))
58}
59
60#[inline]
61unsafe fn _mm256_loadu_epi32_to___m256d(mem_addr: *const i32) -> __m256d {
62 _mm256_castsi256_pd(_mm256_loadu_epi32(mem_addr))
63}
64
65#[inline]
66unsafe fn _mm512_loadu_epi32_to___m512d(mem_addr: *const i32) -> __m512d {
67 _mm512_castsi512_pd(_mm512_loadu_epi32(mem_addr))
68}
69
70#[inline]
71unsafe fn _mm_loadu_epi64_to___m128d(mem_addr: *const i64) -> __m128d {
72 _mm_castsi128_pd(_mm_loadu_epi64(mem_addr))
73}
74
75#[inline]
76unsafe fn _mm256_loadu_epi64_to___m256d(mem_addr: *const i64) -> __m256d {
77 _mm256_castsi256_pd(_mm256_loadu_epi64(mem_addr))
78}
79
80#[inline]
81unsafe fn _mm512_loadu_epi64_to___m512d(mem_addr: *const i64) -> __m512d {
82 _mm512_castsi512_pd(_mm512_loadu_epi64(mem_addr))
83}
84
85// ===
86#[inline]
87unsafe fn _mm_loadu_epi16_to___m128(mem_addr: *const i16) -> __m128 {
88 _mm_castsi128_ps(_mm_loadu_epi16(mem_addr))
89}
90
91#[inline]
92unsafe fn _mm256_loadu_epi16_to___m256(mem_addr: *const i16) -> __m256 {
93 _mm256_castsi256_ps(_mm256_loadu_epi16(mem_addr))
94}
95
96#[inline]
97unsafe fn _mm512_loadu_epi16_to___m512(mem_addr: *const i16) -> __m512 {
98 _mm512_castsi512_ps(_mm512_loadu_epi16(mem_addr))
99}
100
101#[inline]
102unsafe fn _mm_loadu_epi32_to___m128(mem_addr: *const i32) -> __m128 {
103 _mm_castsi128_ps(_mm_loadu_epi32(mem_addr))
104}
105
106#[inline]
107unsafe fn _mm256_loadu_epi32_to___m256(mem_addr: *const i32) -> __m256 {
108 _mm256_castsi256_ps(_mm256_loadu_epi32(mem_addr))
109}
110
111#[inline]
112unsafe fn _mm512_loadu_epi32_to___m512(mem_addr: *const i32) -> __m512 {
113 _mm512_castsi512_ps(_mm512_loadu_epi32(mem_addr))
114}
115
116#[inline]
117unsafe fn _mm_loadu_epi64_to___m128(mem_addr: *const i64) -> __m128 {
118 _mm_castsi128_ps(_mm_loadu_epi64(mem_addr))
119}
120
121#[inline]
122unsafe fn _mm256_loadu_epi64_to___m256(mem_addr: *const i64) -> __m256 {
123 _mm256_castsi256_ps(_mm256_loadu_epi64(mem_addr))
124}
125
126#[inline]
127unsafe fn _mm512_loadu_epi64_to___m512(mem_addr: *const i64) -> __m512 {
128 _mm512_castsi512_ps(_mm512_loadu_epi64(mem_addr))
129}
130
131"#;
132
133pub const PLATFORM_RUST_CFGS: &str = r#"
134#![feature(stdarch_x86_avx512_bf16)]
135#![feature(stdarch_x86_avx512_f16)]
136#![feature(stdarch_x86_rtm)]
137#![feature(x86_amx_intrinsics)]
138"#;
library/stdarch/crates/intrinsic-test/src/x86/mod.rs+147-13
......@@ -1,35 +1,38 @@
1mod config;
21mod constraint;
32mod intrinsic;
43mod types;
54mod xml_parser;
65
7use crate::common::SupportedArchitectureTest;
6use crate::common::SupportedArchitecture;
87use crate::common::cli::ProcessedCli;
98use crate::common::intrinsic::Intrinsic;
109use crate::common::intrinsic_helpers::TypeKind;
1110use intrinsic::X86IntrinsicType;
1211use xml_parser::get_xml_intrinsics;
1312
14pub struct X86ArchitectureTest {
15 intrinsics: Vec<Intrinsic<X86IntrinsicType>>,
13pub struct X86 {
14 intrinsics: Vec<Intrinsic<X86>>,
1615}
1716
18impl SupportedArchitectureTest for X86ArchitectureTest {
19 type IntrinsicImpl = X86IntrinsicType;
17impl SupportedArchitecture for X86 {
18 type Type = X86IntrinsicType;
2019
21 fn intrinsics(&self) -> &[Intrinsic<X86IntrinsicType>] {
20 fn intrinsics(&self) -> &[Intrinsic<Self>] {
2221 &self.intrinsics
2322 }
2423
25 const NOTICE: &str = config::NOTICE;
24 const NOTICE: &str = r#"
25// This is a transient test file, not intended for distribution. Some aspects of the
26// test are derived from an XML specification, published under the same license as the
27// `intrinsic-test` crate.
28"#;
2629
27 const PLATFORM_C_HEADERS: &[&str] = &["immintrin.h"];
30 const C_PRELUDE: &str = r#"
31#include <immintrin.h>
32"#;
33 const RUST_PRELUDE: &str = RUST_PRELUDE;
2834
29 const PLATFORM_RUST_DEFINITIONS: &str = config::PLATFORM_RUST_DEFINITIONS;
30 const PLATFORM_RUST_CFGS: &str = config::PLATFORM_RUST_CFGS;
31
32 fn arch_flags(&self, _cli_options: &ProcessedCli) -> Vec<&str> {
35 fn c_compiler_flags(&self, _cli_options: &ProcessedCli) -> Vec<&str> {
3336 vec![
3437 "-maes",
3538 "-mf16c",
......@@ -97,3 +100,134 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
97100 Self { intrinsics }
98101 }
99102}
103
104const RUST_PRELUDE: &str = r#"
105#![feature(stdarch_x86_avx512_bf16)]
106#![feature(stdarch_x86_avx512_f16)]
107#![feature(stdarch_x86_rtm)]
108#![feature(x86_amx_intrinsics)]
109
110use core_arch::arch::x86_64::*;
111
112#[inline]
113unsafe fn _mm_loadu_ph_to___m128i(mem_addr: *const f16) -> __m128i {
114 _mm_castph_si128(_mm_loadu_ph(mem_addr))
115}
116
117#[inline]
118unsafe fn _mm256_loadu_ph_to___m256i(mem_addr: *const f16) -> __m256i {
119 _mm256_castph_si256(_mm256_loadu_ph(mem_addr))
120}
121
122#[inline]
123unsafe fn _mm512_loadu_ph_to___mm512i(mem_addr: *const f16) -> __m512i {
124 _mm512_castph_si512(_mm512_loadu_ph(mem_addr))
125}
126
127
128#[inline]
129unsafe fn _mm_loadu_ps_to___m128h(mem_addr: *const f32) -> __m128h {
130 _mm_castps_ph(_mm_loadu_ps(mem_addr))
131}
132
133#[inline]
134unsafe fn _mm256_loadu_ps_to___m256h(mem_addr: *const f32) -> __m256h {
135 _mm256_castps_ph(_mm256_loadu_ps(mem_addr))
136}
137
138#[inline]
139unsafe fn _mm512_loadu_ps_to___m512h(mem_addr: *const f32) -> __m512h {
140 _mm512_castps_ph(_mm512_loadu_ps(mem_addr))
141}
142
143#[inline]
144unsafe fn _mm_loadu_epi16_to___m128d(mem_addr: *const i16) -> __m128d {
145 _mm_castsi128_pd(_mm_loadu_epi16(mem_addr))
146}
147
148#[inline]
149unsafe fn _mm256_loadu_epi16_to___m256d(mem_addr: *const i16) -> __m256d {
150 _mm256_castsi256_pd(_mm256_loadu_epi16(mem_addr))
151}
152
153#[inline]
154unsafe fn _mm512_loadu_epi16_to___m512d(mem_addr: *const i16) -> __m512d {
155 _mm512_castsi512_pd(_mm512_loadu_epi16(mem_addr))
156}
157
158#[inline]
159unsafe fn _mm_loadu_epi32_to___m128d(mem_addr: *const i32) -> __m128d {
160 _mm_castsi128_pd(_mm_loadu_epi32(mem_addr))
161}
162
163#[inline]
164unsafe fn _mm256_loadu_epi32_to___m256d(mem_addr: *const i32) -> __m256d {
165 _mm256_castsi256_pd(_mm256_loadu_epi32(mem_addr))
166}
167
168#[inline]
169unsafe fn _mm512_loadu_epi32_to___m512d(mem_addr: *const i32) -> __m512d {
170 _mm512_castsi512_pd(_mm512_loadu_epi32(mem_addr))
171}
172
173#[inline]
174unsafe fn _mm_loadu_epi64_to___m128d(mem_addr: *const i64) -> __m128d {
175 _mm_castsi128_pd(_mm_loadu_epi64(mem_addr))
176}
177
178#[inline]
179unsafe fn _mm256_loadu_epi64_to___m256d(mem_addr: *const i64) -> __m256d {
180 _mm256_castsi256_pd(_mm256_loadu_epi64(mem_addr))
181}
182
183#[inline]
184unsafe fn _mm512_loadu_epi64_to___m512d(mem_addr: *const i64) -> __m512d {
185 _mm512_castsi512_pd(_mm512_loadu_epi64(mem_addr))
186}
187
188// ===
189#[inline]
190unsafe fn _mm_loadu_epi16_to___m128(mem_addr: *const i16) -> __m128 {
191 _mm_castsi128_ps(_mm_loadu_epi16(mem_addr))
192}
193
194#[inline]
195unsafe fn _mm256_loadu_epi16_to___m256(mem_addr: *const i16) -> __m256 {
196 _mm256_castsi256_ps(_mm256_loadu_epi16(mem_addr))
197}
198
199#[inline]
200unsafe fn _mm512_loadu_epi16_to___m512(mem_addr: *const i16) -> __m512 {
201 _mm512_castsi512_ps(_mm512_loadu_epi16(mem_addr))
202}
203
204#[inline]
205unsafe fn _mm_loadu_epi32_to___m128(mem_addr: *const i32) -> __m128 {
206 _mm_castsi128_ps(_mm_loadu_epi32(mem_addr))
207}
208
209#[inline]
210unsafe fn _mm256_loadu_epi32_to___m256(mem_addr: *const i32) -> __m256 {
211 _mm256_castsi256_ps(_mm256_loadu_epi32(mem_addr))
212}
213
214#[inline]
215unsafe fn _mm512_loadu_epi32_to___m512(mem_addr: *const i32) -> __m512 {
216 _mm512_castsi512_ps(_mm512_loadu_epi32(mem_addr))
217}
218
219#[inline]
220unsafe fn _mm_loadu_epi64_to___m128(mem_addr: *const i64) -> __m128 {
221 _mm_castsi128_ps(_mm_loadu_epi64(mem_addr))
222}
223
224#[inline]
225unsafe fn _mm256_loadu_epi64_to___m256(mem_addr: *const i64) -> __m256 {
226 _mm256_castsi256_ps(_mm256_loadu_epi64(mem_addr))
227}
228
229#[inline]
230unsafe fn _mm512_loadu_epi64_to___m512(mem_addr: *const i64) -> __m512 {
231 _mm512_castsi512_ps(_mm512_loadu_epi64(mem_addr))
232}
233"#;
library/stdarch/crates/intrinsic-test/src/x86/types.rs+3-5
......@@ -3,12 +3,10 @@ use std::str::FromStr;
33use itertools::Itertools;
44
55use super::intrinsic::X86IntrinsicType;
6use crate::common::intrinsic_helpers::{
7 IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind,
8};
6use crate::common::intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind};
97use crate::x86::xml_parser::Parameter;
108
11impl IntrinsicTypeDefinition for X86IntrinsicType {
9impl TypeDefinition for X86IntrinsicType {
1210 /// Gets a string containing the type in C format.
1311 /// This function assumes that this value is present in the metadata hashmap.
1412 fn c_type(&self) -> String {
......@@ -50,7 +48,7 @@ impl IntrinsicTypeDefinition for X86IntrinsicType {
5048 }
5149
5250 /// Determines the load function for this type.
53 fn get_load_function(&self) -> String {
51 fn load_function(&self) -> String {
5452 let type_value = self.param.type_data.clone();
5553 if type_value.len() == 0 {
5654 unimplemented!("the value for key 'type' is not present!");
library/stdarch/crates/intrinsic-test/src/x86/xml_parser.rs+9-14
......@@ -1,6 +1,7 @@
11use crate::common::argument::{Argument, ArgumentList};
22use crate::common::intrinsic::Intrinsic;
33use crate::common::intrinsic_helpers::TypeKind;
4use crate::x86::X86;
45use crate::x86::constraint::map_constraints;
56
67use regex::Regex;
......@@ -56,13 +57,13 @@ pub struct Parameter {
5657
5758pub fn get_xml_intrinsics(
5859 filename: &Path,
59) -> Result<Vec<Intrinsic<X86IntrinsicType>>, Box<dyn std::error::Error>> {
60) -> Result<Vec<Intrinsic<X86>>, Box<dyn std::error::Error>> {
6061 let file = std::fs::File::open(filename)?;
6162 let reader = std::io::BufReader::new(file);
6263 let data: Data =
6364 quick_xml::de::from_reader(reader).expect("failed to deserialize the source XML file");
6465
65 let parsed_intrinsics: Vec<Intrinsic<X86IntrinsicType>> = data
66 let parsed_intrinsics: Vec<Intrinsic<X86>> = data
6667 .intrinsics
6768 .into_iter()
6869 .filter(|intrinsic| {
......@@ -84,9 +85,7 @@ pub fn get_xml_intrinsics(
8485 Ok(parsed_intrinsics)
8586}
8687
87fn xml_to_intrinsic(
88 intr: XMLIntrinsic,
89) -> Result<Intrinsic<X86IntrinsicType>, Box<dyn std::error::Error>> {
88fn xml_to_intrinsic(intr: XMLIntrinsic) -> Result<Intrinsic<X86>, Box<dyn std::error::Error>> {
9089 let name = intr.name;
9190 let result = X86IntrinsicType::from_param(&intr.return_data);
9291 let args_check = intr.parameters.into_iter().enumerate().map(|(i, param)| {
......@@ -100,12 +99,7 @@ fn xml_to_intrinsic(
10099 param.imm_width
101100 };
102101 let constraint = map_constraints(&name, &param.imm_type, effective_imm_width);
103 let arg = Argument::<X86IntrinsicType>::new(
104 i,
105 param.var_name.clone(),
106 ty.unwrap(),
107 constraint,
108 );
102 let arg = Argument::<X86>::new(i, param.var_name.clone(), ty.unwrap(), constraint);
109103 Some(arg)
110104 }
111105 });
......@@ -125,8 +119,8 @@ fn xml_to_intrinsic(
125119 // if one of the args has etype="MASK" and type="__m<int>d",
126120 // then set the bit_len and simd_len accordingly
127121 let re = Regex::new(r"__m\d+").unwrap();
128 let is_mask = |arg: &Argument<X86IntrinsicType>| arg.ty.param.etype.as_str() == "MASK";
129 let is_vector = |arg: &Argument<X86IntrinsicType>| re.is_match(arg.ty.param.type_data.as_str());
122 let is_mask = |arg: &Argument<X86>| arg.ty.param.etype.as_str() == "MASK";
123 let is_vector = |arg: &Argument<X86>| re.is_match(arg.ty.param.type_data.as_str());
130124 let pos = args_test.position(|arg| is_mask(arg) && is_vector(arg));
131125 if let Some(index) = pos {
132126 args[index].ty.bit_len = args[0].ty.bit_len;
......@@ -134,7 +128,7 @@ fn xml_to_intrinsic(
134128
135129 args.iter_mut().for_each(|arg| arg.ty.update_simd_len());
136130
137 let arguments = ArgumentList::<X86IntrinsicType> { args };
131 let arguments = ArgumentList::<X86> { args };
138132
139133 if let Err(message) = result {
140134 return Err(Box::from(message));
......@@ -145,5 +139,6 @@ fn xml_to_intrinsic(
145139 arguments,
146140 results: result.unwrap(),
147141 arch_tags: intr.cpuid,
142 extension: intr.tech,
148143 })
149144}
library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml+2-2
......@@ -13951,7 +13951,7 @@ intrinsics:
1395113951 - 'b: {neon_type[1]}'
1395213952 - 'n: i32'
1395313953 links:
13954 - link: "llvm.aarch64.neon.vluti4q.lane.{neon_type[1]}"
13954 - link: "llvm.aarch64.neon.vluti4q.lane.{neon_type[0]}"
1395513955 arch: aarch64,arm64ec
1395613956 - FnCall: ['_vluti4{neon_type[0].lane_nox}', [a, b, LANE]]
1395713957
......@@ -14002,7 +14002,7 @@ intrinsics:
1400214002 - 'b: {neon_type[1]}'
1400314003 - 'n: i32'
1400414004 links:
14005 - link: "llvm.aarch64.neon.vluti4q.laneq.{neon_type[1]}"
14005 - link: "llvm.aarch64.neon.vluti4q.laneq.{neon_type[0]}"
1400614006 arch: aarch64,arm64ec
1400714007 - FnCall: ['_vluti4{neon_type[0].laneq_nox}', [a, b, LANE]]
1400814008
library/stdarch/crates/stdarch-gen-arm/spec/sve/aarch64.spec.yml+77-27
......@@ -115,7 +115,7 @@ intrinsics:
115115 assert_instr: [[fcmla, "IMM_INDEX = 0, IMM_ROTATION = 90"]]
116116 compose:
117117 - LLVMLink:
118 name: fcmla.lane.x.{sve_type}
118 name: fcmla.lane.{sve_type}
119119 arguments:
120120 - "op1: {sve_type}"
121121 - "op2: {sve_type}"
......@@ -1021,7 +1021,7 @@ intrinsics:
10211021 doc: Interleave elements from low halves of two inputs
10221022 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10231023 return_type: "{sve_type}"
1024 types: [f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
1024 types: [b8, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
10251025 assert_instr: [zip1]
10261026 compose:
10271027 - LLVMLink: { name: "zip1.{sve_type}" }
......@@ -1031,10 +1031,13 @@ intrinsics:
10311031 doc: Interleave elements from low halves of two inputs
10321032 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10331033 return_type: "{sve_type}"
1034 types: [b8, b16, b32, b64]
1034 types: [b16, b32, b64]
10351035 assert_instr: [zip1]
10361036 compose:
1037 - LLVMLink: { name: "zip1.{sve_type}" }
1037 - LLVMLink:
1038 name: "llvm.aarch64.sve.zip1.b{size}"
1039 arguments: ["op1: svbool_t", "op2: svbool_t"]
1040 return_type: "svbool_t"
10381041
10391042 - name: svzip1q[_{type}]
10401043 attr: [*sve-unstable]
......@@ -1052,7 +1055,7 @@ intrinsics:
10521055 doc: Interleave elements from high halves of two inputs
10531056 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10541057 return_type: "{sve_type}"
1055 types: [f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
1058 types: [b8, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
10561059 assert_instr: [zip2]
10571060 compose:
10581061 - LLVMLink: { name: "zip2.{sve_type}" }
......@@ -1062,10 +1065,13 @@ intrinsics:
10621065 doc: Interleave elements from high halves of two inputs
10631066 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10641067 return_type: "{sve_type}"
1065 types: [b8, b16, b32, b64]
1068 types: [b16, b32, b64]
10661069 assert_instr: [zip2]
10671070 compose:
1068 - LLVMLink: { name: "zip2.{sve_type}" }
1071 - LLVMLink:
1072 name: "llvm.aarch64.sve.zip2.b{size}"
1073 arguments: ["op1: svbool_t", "op2: svbool_t"]
1074 return_type: "svbool_t"
10691075
10701076 - name: svzip2q[_{type}]
10711077 attr: [*sve-unstable]
......@@ -1083,7 +1089,7 @@ intrinsics:
10831089 doc: Concatenate even elements from two inputs
10841090 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10851091 return_type: "{sve_type}"
1086 types: [f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
1092 types: [b8, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
10871093 assert_instr: [uzp1]
10881094 compose:
10891095 - LLVMLink: { name: "uzp1.{sve_type}" }
......@@ -1093,10 +1099,13 @@ intrinsics:
10931099 doc: Concatenate even elements from two inputs
10941100 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
10951101 return_type: "{sve_type}"
1096 types: [b8, b16, b32, b64]
1102 types: [b16, b32, b64]
10971103 assert_instr: [uzp1]
10981104 compose:
1099 - LLVMLink: { name: "uzp1.{sve_type}" }
1105 - LLVMLink:
1106 name: "llvm.aarch64.sve.uzp1.b{size}"
1107 arguments: ["op1: svbool_t", "op2: svbool_t"]
1108 return_type: "svbool_t"
11001109
11011110 - name: svuzp1q[_{type}]
11021111 attr: [*sve-unstable]
......@@ -1114,7 +1123,7 @@ intrinsics:
11141123 doc: Concatenate odd elements from two inputs
11151124 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
11161125 return_type: "{sve_type}"
1117 types: [f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
1126 types: [b8, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
11181127 assert_instr: [uzp2]
11191128 compose:
11201129 - LLVMLink: { name: "uzp2.{sve_type}" }
......@@ -1124,10 +1133,13 @@ intrinsics:
11241133 doc: Concatenate odd elements from two inputs
11251134 arguments: ["op1: {sve_type}", "op2: {sve_type}"]
11261135 return_type: "{sve_type}"
1127 types: [b8, b16, b32, b64]
1136 types: [b16, b32, b64]
11281137 assert_instr: [uzp2]
11291138 compose:
1130 - LLVMLink: { name: "uzp2.{sve_type}" }
1139 - LLVMLink:
1140 name: "llvm.aarch64.sve.uzp2.b{size}"
1141 arguments: ["op1: svbool_t", "op2: svbool_t"]
1142 return_type: "svbool_t"
11311143
11321144 - name: svuzp2q[_{type}]
11331145 attr: [*sve-unstable]
......@@ -1207,7 +1219,7 @@ intrinsics:
12071219 doc: Reverse all elements
12081220 arguments: ["op: {sve_type}"]
12091221 return_type: "{sve_type}"
1210 types: [f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
1222 types: [b8, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64]
12111223 assert_instr: [rev]
12121224 compose:
12131225 - LLVMLink: { name: "llvm.vector.reverse.{sve_type}" }
......@@ -1217,10 +1229,13 @@ intrinsics:
12171229 doc: Reverse all elements
12181230 arguments: ["op: {sve_type}"]
12191231 return_type: "{sve_type}"
1220 types: [b8, b16, b32, b64]
1232 types: [b16, b32, b64]
12211233 assert_instr: [rev]
12221234 compose:
1223 - LLVMLink: { name: "llvm.vector.reverse.{sve_type}" }
1235 - LLVMLink:
1236 name: "llvm.aarch64.sve.rev.b{size}"
1237 arguments: ["op: svbool_t"]
1238 return_type: "svbool_t"
12241239
12251240 - name: svrevb[_{type}]{_mxz}
12261241 attr: [*sve-unstable]
......@@ -4179,7 +4194,8 @@ intrinsics:
41794194 ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"]
41804195 return_type: "{sve_type[0]}"
41814196 types:
4182 - [[f32, f64], [i32, u32, i64, u64]]
4197 - [f32, [i64, u64]]
4198 - [f64, [i32, u32]]
41834199 zeroing_method: { drop: inactive }
41844200 substitutions:
41854201 convert_from: { match_kind: "{type[1]}", default: s, unsigned: u }
......@@ -4187,6 +4203,23 @@ intrinsics:
41874203 compose:
41884204 - LLVMLink:
41894205 name: "{convert_from}cvtf.{type[0]}{type[1]}"
4206
4207 - name: svcvt_{type[0]}[_{type[1]}]{_mxz}
4208 attr: [*sve-unstable]
4209 doc: Floating-point convert
4210 arguments:
4211 ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"]
4212 return_type: "{sve_type[0]}"
4213 types:
4214 - [f32, [i32, u32]]
4215 - [f64, [i64, u64]]
4216 zeroing_method: { drop: inactive }
4217 substitutions:
4218 convert_from: { match_kind: "{type[1]}", default: s, unsigned: u }
4219 assert_instr: ["{convert_from}cvtf"]
4220 compose:
4221 - LLVMLink:
4222 name: "{convert_from}cvtf.{sve_type[0]}.{sve_type[1]}"
41904223
41914224 - name: svcvt_{type[0]}[_{type[1]}]{_mxz}
41924225 attr: [*sve-unstable]
......@@ -4195,13 +4228,30 @@ intrinsics:
41954228 ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"]
41964229 return_type: "{sve_type[0]}"
41974230 types:
4198 - [[i32, u32, i64, u64], [f32, f64]]
4231 - [[i32, u32], f64]
4232 - [[i64, u64], f32]
41994233 zeroing_method: { drop: inactive }
42004234 substitutions:
42014235 convert_to: { match_kind: "{type[0]}", default: s, unsigned: u }
42024236 assert_instr: ["fcvtz{convert_to}"]
42034237 compose:
42044238 - LLVMLink: { name: "fcvtz{convert_to}.{type[0]}{type[1]}" }
4239
4240 - name: svcvt_{type[0]}[_{type[1]}]{_mxz}
4241 attr: [*sve-unstable]
4242 doc: Floating-point convert
4243 arguments:
4244 ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"]
4245 return_type: "{sve_type[0]}"
4246 types:
4247 - [[i32, u32], f32]
4248 - [[i64, u64], f64]
4249 zeroing_method: { drop: inactive }
4250 substitutions:
4251 convert_to: { match_kind: "{type[0]}", default: s, unsigned: u }
4252 assert_instr: ["fcvtz{convert_to}"]
4253 compose:
4254 - LLVMLink: { name: "fcvtz{convert_to}.{sve_type[0]}.{sve_type[1]}" }
42054255
42064256 - name: svcvt_{type[0]}[_{type[1]}]{_mxz}
42074257 attr: [*sve-unstable]
......@@ -4356,7 +4406,7 @@ intrinsics:
43564406 return_type: svbool_t
43574407 assert_instr: [and]
43584408 compose:
4359 - LLVMLink: { name: "and.z.nvx16i1" }
4409 - LLVMLink: { name: "and.z.nxv16i1" }
43604410
43614411 - name: svmov[_b]_z
43624412 attr: [*sve-unstable]
......@@ -4386,7 +4436,7 @@ intrinsics:
43864436 return_type: svbool_t
43874437 assert_instr: [bic]
43884438 compose:
4389 - LLVMLink: { name: "bic.z.nvx16i1" }
4439 - LLVMLink: { name: "bic.z.nxv16i1" }
43904440
43914441 - name: sveor[{_n}_{type}]{_mxz}
43924442 attr: [*sve-unstable]
......@@ -4417,7 +4467,7 @@ intrinsics:
44174467 return_type: svbool_t
44184468 assert_instr: [eor]
44194469 compose:
4420 - LLVMLink: { name: "eor.z.nvx16i1" }
4470 - LLVMLink: { name: "eor.z.nxv16i1" }
44214471
44224472 - name: svnot[_{type}]{_mxz}
44234473 attr: [*sve-unstable]
......@@ -4497,7 +4547,7 @@ intrinsics:
44974547 return_type: svbool_t
44984548 assert_instr: [orr]
44994549 compose:
4500 - LLVMLink: { name: "orr.z.nvx16i1" }
4550 - LLVMLink: { name: "orr.z.nxv16i1" }
45014551
45024552 - name: svorn[_b]_z
45034553 attr: [*sve-unstable]
......@@ -4506,7 +4556,7 @@ intrinsics:
45064556 return_type: svbool_t
45074557 assert_instr: [orn]
45084558 compose:
4509 - LLVMLink: { name: "orn.z.nvx16i1" }
4559 - LLVMLink: { name: "orn.z.nxv16i1" }
45104560
45114561 - name: svlsl[{_n}_{type[0]}]{_mxz}
45124562 attr: [*sve-unstable]
......@@ -4749,7 +4799,7 @@ intrinsics:
47494799 assert_instr: [frecpx]
47504800 zeroing_method: { drop: inactive }
47514801 compose:
4752 - LLVMLink: { name: "frecpx.x.{sve_type}" }
4802 - LLVMLink: { name: "frecpx.{sve_type}" }
47534803
47544804 - name: svrsqrte[_{type}]
47554805 attr: [*sve-unstable]
......@@ -5115,7 +5165,7 @@ intrinsics:
51155165 types: [[f32, u32], [f64, u64]]
51165166 assert_instr: [fexpa]
51175167 compose:
5118 - LLVMLink: { name: "fexpa.x.{sve_type[0]} " }
5168 - LLVMLink: { name: "fexpa.x.{sve_type[0]}" }
51195169
51205170 - name: svscale[{_n}_{type[0]}]{_mxz}
51215171 attr: [*sve-unstable]
......@@ -5139,7 +5189,7 @@ intrinsics:
51395189 types: [f32]
51405190 assert_instr: [fmmla]
51415191 compose:
5142 - LLVMLink: { name: "fmmla.{sve_type}" }
5192 - LLVMLink: { name: "fmmla.{sve_type}.{sve_type}" }
51435193
51445194 - name: svmmla[_{type}]
51455195 attr: [*sve-unstable]
......@@ -5150,7 +5200,7 @@ intrinsics:
51505200 types: [f64]
51515201 assert_instr: [fmmla]
51525202 compose:
5153 - LLVMLink: { name: "fmmla.{sve_type}" }
5203 - LLVMLink: { name: "fmmla.{sve_type}.{sve_type}" }
51545204
51555205 - name: svmmla[_{type[0]}]
51565206 attr: [*sve-unstable]
library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs+1
......@@ -1604,6 +1604,7 @@ impl Intrinsic {
16041604 (Some(BaseTypeKind::Float), Some(BaseTypeKind::Float)) => ex,
16051605 (Some(BaseTypeKind::UInt), Some(BaseTypeKind::UInt)) => ex,
16061606 (Some(BaseTypeKind::Poly), Some(BaseTypeKind::Poly)) => ex,
1607 (Some(BaseTypeKind::Bool), Some(BaseTypeKind::Bool)) => ex,
16071608
16081609 (None, None) => ex,
16091610 _ => unreachable!(
library/stdarch/crates/stdarch-gen-common/Cargo.toml created+7
......@@ -0,0 +1,7 @@
1[package]
2name = "stdarch-gen-common"
3version = "0.1.0"
4edition = "2024"
5
6[dependencies]
7tempfile = "3"
\ No newline at end of file
library/stdarch/crates/stdarch-gen-common/src/lib.rs created+352
......@@ -0,0 +1,352 @@
1//! Shared check/bless harness for stdarch generators.
2
3use std::error::Error as StdError;
4use std::fmt;
5use std::fs;
6use std::io;
7use std::io::Read;
8use std::path::{Path, PathBuf};
9
10/// First-line marker identifying an auto-generated file. Generators emit this
11/// as the first line of every file they produce; the harness uses it to
12/// discover which files in `committed` are owned by the generator.
13pub const GENERATED_MARKER: &str = "// This code is automatically generated. DO NOT MODIFY.";
14
15/// Controls what `run_generator` does with the generator's output.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum Mode {
18 /// Verify that the `committed` matches the generator's output for owned files.
19 ///
20 /// Runs the generator into a temp directory, then compares each produced
21 /// file against the committed copy. Returns an error on the first mismatch.
22 Check,
23 /// Update the `committed` to match the generator's output for owned files.
24 ///
25 /// Runs the generator into a temp directory and copies each produced file
26 /// into `committed`. If the generator no longer produces an owned file, the
27 /// committed copy is deleted. Files in `committed` that are not owned
28 /// are left untouched.
29 Bless,
30}
31
32impl Mode {
33 /// Read the mode from the `STDARCH_GEN_MODE` environment variable.
34 ///
35 /// Recognized values:
36 /// - `"check"` → [`Mode::Check`]
37 /// - `"bless"` → [`Mode::Bless`]
38 /// - unset → [`Mode::Bless`]
39 /// - any other value → panic
40 pub fn from_env() -> Self {
41 match std::env::var("STDARCH_GEN_MODE").as_deref() {
42 Ok("check") => Mode::Check,
43 Ok("bless") => Mode::Bless,
44 Ok(other) => panic!("unknown STDARCH_GEN_MODE value: {other:?}"),
45 Err(_) => Mode::Bless,
46 }
47 }
48}
49
50#[derive(Debug)]
51pub enum Error {
52 Io(io::Error),
53 Mismatch { path: PathBuf, kind: MismatchKind },
54 Generator(Box<dyn StdError + Send + Sync>),
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum MismatchKind {
59 /// Owned file produced by the generator but absent from the `committed`.
60 /// Means the `committed` needs to be regenerated.
61 MissingInCommitted,
62 /// Owned file present in the `committed` but the generator no longer
63 /// produces it. The file must be removed from the `committed` .
64 ExtraInCommitted,
65 /// Owned file exists on both sides but contents differ.
66 ContentsDiffer,
67}
68
69impl fmt::Display for Error {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match self {
72 Error::Io(e) => write!(f, "I/O error: {e}"),
73 Error::Mismatch { path, kind } => match kind {
74 MismatchKind::MissingInCommitted => {
75 write!(f, "{}: generated but not committed", path.display())
76 }
77 MismatchKind::ExtraInCommitted => {
78 write!(f, "{}: committed but no longer generated", path.display())
79 }
80 MismatchKind::ContentsDiffer => write!(f, "{}: contents differ", path.display()),
81 },
82 Error::Generator(e) => write!(f, "generator failed: {e}"),
83 }
84 }
85}
86
87impl StdError for Error {
88 fn source(&self) -> Option<&(dyn StdError + 'static)> {
89 match self {
90 Error::Io(e) => Some(e),
91 Error::Generator(e) => Some(&**e),
92 _ => None,
93 }
94 }
95}
96
97impl From<io::Error> for Error {
98 fn from(e: io::Error) -> Self {
99 Error::Io(e)
100 }
101}
102
103pub type Result<T> = std::result::Result<T, Error>;
104
105/// Run a generator under the chosen `mode`, reconciling its output with `committed`.
106///
107/// Arguments:
108/// - `committed` — the directory holding the in-tree (committed) source files.
109/// Files inside `committed` whose first line begins with [`GENERATED_MARKER`]
110/// are treated as owned by the generator. Anything else is treated as
111/// hand-written and is left untouched by `Bless` and ignored by `Check`.
112/// So generated files coexist with hand-written files in the same directory.
113/// - `mode` — what to do with the generator's output.
114/// - `generate` — closure that writes the generator's output into the
115/// directory it is given. Its error is wrapped in [`Error::Generator`].
116///
117/// Behavior per mode:
118/// - [`Mode::Check`]: runs the generator into a temp dir and compares owned
119/// files against the committed copies. Mismatch returns [`Error::Mismatch`].
120/// - [`Mode::Bless`]: runs the generator into a temp dir and copies owned
121/// files into `committed`, or removes `committed`'s copy if the generator no
122/// longer produces them.
123pub fn run_generator<F, E>(committed: &Path, mode: Mode, generate: F) -> Result<()>
124where
125 F: FnOnce(&Path) -> std::result::Result<(), E>,
126 E: Into<Box<dyn StdError + Send + Sync>>,
127{
128 let scratch = tempfile::tempdir()?;
129 generate(scratch.path()).map_err(|e| Error::Generator(e.into()))?;
130
131 let owned = discover_owned(committed)?;
132 let produced = discover_all(scratch.path())?;
133
134 let mut names: Vec<&String> = owned.iter().chain(produced.iter()).collect();
135 names.sort();
136 names.dedup();
137
138 for name in names {
139 match mode {
140 Mode::Check => compare(scratch.path(), committed, name)?,
141 Mode::Bless => apply_bless(scratch.path(), committed, name)?,
142 }
143 }
144 Ok(())
145}
146
147/// Returns the names of files in `dir` whose first line begins with
148/// [`GENERATED_MARKER`]. Files without the marker are skipped.
149fn discover_owned(dir: &Path) -> Result<Vec<String>> {
150 let mut out = Vec::new();
151 for entry in fs::read_dir(dir)? {
152 let entry = entry?;
153 if !entry.file_type()?.is_file() {
154 continue;
155 }
156 let Ok(mut file) = fs::File::open(entry.path()) else {
157 continue;
158 };
159 let mut buf = [0u8; GENERATED_MARKER.len()];
160 if file.read_exact(&mut buf).is_err() {
161 continue;
162 }
163 if buf == *GENERATED_MARKER.as_bytes()
164 && let Some(name) = entry.file_name().to_str()
165 {
166 out.push(name.to_owned());
167 }
168 }
169 out.sort();
170 Ok(out)
171}
172
173/// Returns every file name in `dir` (scratch dir — all files are generator output).
174fn discover_all(dir: &Path) -> Result<Vec<String>> {
175 let mut out = Vec::new();
176 for entry in fs::read_dir(dir)? {
177 let entry = entry?;
178 if entry.file_type()?.is_file()
179 && let Some(name) = entry.file_name().to_str()
180 {
181 out.push(name.to_string());
182 }
183 }
184 Ok(out)
185}
186
187fn compare(generated_dir: &Path, committed_dir: &Path, filename: &str) -> Result<()> {
188 let rel_path = PathBuf::from(filename);
189 let gen_path = generated_dir.join(&rel_path);
190 let comm_path = committed_dir.join(&rel_path);
191 match (gen_path.exists(), comm_path.exists()) {
192 (true, false) => Err(Error::Mismatch {
193 path: rel_path,
194 kind: MismatchKind::MissingInCommitted,
195 }),
196 (false, true) => Err(Error::Mismatch {
197 path: rel_path,
198 kind: MismatchKind::ExtraInCommitted,
199 }),
200 (false, false) => Ok(()),
201 (true, true) => {
202 if fs::read(&gen_path)? != fs::read(&comm_path)? {
203 Err(Error::Mismatch {
204 path: rel_path,
205 kind: MismatchKind::ContentsDiffer,
206 })
207 } else {
208 Ok(())
209 }
210 }
211 }
212}
213
214fn apply_bless(generated_dir: &Path, committed_dir: &Path, filename: &str) -> Result<()> {
215 fs::create_dir_all(committed_dir)?;
216 let rel_path = PathBuf::from(filename);
217 let from = generated_dir.join(&rel_path);
218 let to = committed_dir.join(&rel_path);
219 if from.exists() {
220 if let Some(parent) = to.parent() {
221 fs::create_dir_all(parent)?;
222 }
223 fs::copy(&from, &to)?;
224 } else if to.exists() {
225 fs::remove_file(&to)?;
226 }
227 Ok(())
228}
229
230// Skipped on iOS because these tests fail on the `x86_64-apple-ios-macabi` CI runner
231// with `Os { code: 17, kind: AlreadyExists, message: "File exists" }`.
232#[cfg(all(test, not(target_os = "ios")))]
233mod tests {
234 use super::*;
235
236 fn write_marker(p: &Path, body: &[u8]) {
237 if let Some(d) = p.parent() {
238 fs::create_dir_all(d).unwrap();
239 }
240 let mut bytes = Vec::new();
241 bytes.extend_from_slice(GENERATED_MARKER.as_bytes());
242 bytes.push(b'\n');
243 bytes.extend_from_slice(body);
244 fs::write(p, bytes).unwrap();
245 }
246
247 #[test]
248 fn check_fails_on_byte_diff() {
249 let tmp = tempfile::tempdir().unwrap();
250 let committed = tmp.path().join("c");
251 write_marker(&committed.join("a.txt"), b"hi");
252 let e = run_generator(
253 &committed,
254 Mode::Check,
255 |out| -> std::result::Result<(), io::Error> {
256 write_marker(&out.join("a.txt"), b"HI");
257 Ok(())
258 },
259 )
260 .unwrap_err();
261 assert!(matches!(
262 e,
263 Error::Mismatch {
264 kind: MismatchKind::ContentsDiffer,
265 ..
266 }
267 ));
268 }
269
270 #[test]
271 fn check_fails_when_owned_file_missing_from_generated() {
272 let tmp = tempfile::tempdir().unwrap();
273 let committed = tmp.path().join("c");
274 write_marker(&committed.join("a.txt"), b"hi");
275 let e = run_generator(
276 &committed,
277 Mode::Check,
278 |_| -> std::result::Result<(), io::Error> { Ok(()) },
279 )
280 .unwrap_err();
281 assert!(matches!(
282 e,
283 Error::Mismatch {
284 kind: MismatchKind::ExtraInCommitted,
285 ..
286 }
287 ));
288 }
289
290 #[test]
291 fn check_fails_when_owned_file_missing_from_committed() {
292 let tmp = tempfile::tempdir().unwrap();
293 let committed = tmp.path().join("c");
294 fs::create_dir_all(&committed).unwrap();
295 let e = run_generator(
296 &committed,
297 Mode::Check,
298 |out| -> std::result::Result<(), io::Error> {
299 write_marker(&out.join("a.txt"), b"hi");
300 Ok(())
301 },
302 )
303 .unwrap_err();
304 assert!(matches!(
305 e,
306 Error::Mismatch {
307 kind: MismatchKind::MissingInCommitted,
308 ..
309 }
310 ));
311 }
312
313 #[test]
314 fn bless_deletes_files_no_longer_produced() {
315 let tmp = tempfile::tempdir().unwrap();
316 let committed = tmp.path().join("c");
317 write_marker(&committed.join("keep.txt"), b"");
318 write_marker(&committed.join("stale.txt"), b"");
319 run_generator(
320 &committed,
321 Mode::Bless,
322 |out| -> std::result::Result<(), io::Error> {
323 write_marker(&out.join("keep.txt"), b"");
324 Ok(())
325 },
326 )
327 .unwrap();
328 assert!(committed.join("keep.txt").exists());
329 assert!(!committed.join("stale.txt").exists());
330 }
331
332 #[test]
333 fn bless_preserves_unowned_files() {
334 let tmp = tempfile::tempdir().unwrap();
335 let committed = tmp.path().join("c");
336 fs::create_dir_all(&committed).unwrap();
337 fs::write(committed.join("mod.rs"), b"hand-written").unwrap();
338 fs::write(committed.join("old.txt"), b"old").unwrap();
339 run_generator(
340 &committed,
341 Mode::Bless,
342 |out| -> std::result::Result<(), io::Error> {
343 write_marker(&out.join("new.txt"), b"new");
344 Ok(())
345 },
346 )
347 .unwrap();
348 assert_eq!(fs::read(committed.join("mod.rs")).unwrap(), b"hand-written");
349 assert_eq!(fs::read(committed.join("old.txt")).unwrap(), b"old");
350 assert!(committed.join("new.txt").exists());
351 }
352}
library/stdarch/crates/stdarch-gen-hexagon/Cargo.toml+1
......@@ -7,3 +7,4 @@ edition = "2021"
77
88[dependencies]
99regex = "1.10"
10stdarch-gen-common = { path = "../stdarch-gen-common" }
library/stdarch/crates/stdarch-gen-hexagon/src/main.rs+17-17
......@@ -21,6 +21,7 @@ use std::collections::{HashMap, HashSet};
2121use std::fs::File;
2222use std::io::Write;
2323use std::path::Path;
24use stdarch_gen_common::{run_generator, Mode, GENERATED_MARKER};
2425
2526/// Mappings from HVX intrinsics to architecture-independent SIMD intrinsics.
2627/// These intrinsics have equivalent semantics and can be lowered to the generic form.
......@@ -1609,6 +1610,7 @@ fn generate_module_file(
16091610 let mut output =
16101611 File::create(output_path).map_err(|e| format!("Failed to create output: {}", e))?;
16111612
1613 writeln!(output, "{}", GENERATED_MARKER).map_err(|e| e.to_string())?;
16121614 writeln!(output, "{}", generate_module_doc(mode)).map_err(|e| e.to_string())?;
16131615 writeln!(output, "{}", generate_types(mode)).map_err(|e| e.to_string())?;
16141616 writeln!(output, "{}", generate_extern_block(intrinsics, mode)).map_err(|e| e.to_string())?;
......@@ -1691,23 +1693,21 @@ fn main() -> Result<(), String> {
16911693 }
16921694
16931695 // Generate output files
1694 let hexagon_dir = std::env::args()
1695 .nth(1)
1696 .map(std::path::PathBuf::from)
1697 .unwrap_or_else(|| crate_dir.join("../core_arch/src/hexagon"));
1698 std::fs::create_dir_all(&hexagon_dir).map_err(|e| e.to_string())?;
1699
1700 // Generate v64.rs (64-byte vector mode)
1701 let v64_path = hexagon_dir.join("v64.rs");
1702 println!("\nStep 3: Generating v64.rs (64-byte mode)...");
1703 generate_module_file(&intrinsics, &v64_path, VectorMode::V64)?;
1704 println!(" Output: {}", v64_path.display());
1705
1706 // Generate v128.rs (128-byte vector mode)
1707 let v128_path = hexagon_dir.join("v128.rs");
1708 println!("\nStep 4: Generating v128.rs (128-byte mode)...");
1709 generate_module_file(&intrinsics, &v128_path, VectorMode::V128)?;
1710 println!(" Output: {}", v128_path.display());
1696 let hexagon_dir = crate_dir.join("../core_arch/src/hexagon");
1697
1698 // Either "check" to check the output versus the committed output, or "bless"
1699 // to update the output.
1700 let mode = Mode::from_env();
1701 println!("\nStep 3: Generating v64.rs and v128.rs (mode: {mode:?})...");
1702 run_generator(&hexagon_dir, mode, |out_dir| -> Result<(), String> {
1703 for (filename, vmode) in [("v64.rs", VectorMode::V64), ("v128.rs", VectorMode::V128)] {
1704 let path = out_dir.join(filename);
1705 generate_module_file(&intrinsics, &path, vmode)?;
1706 println!(" Output: {}", hexagon_dir.join(filename).display());
1707 }
1708 Ok(())
1709 })
1710 .map_err(|e| e.to_string())?;
17111711
17121712 println!("\n=== Results ===");
17131713 println!(
library/stdarch/crates/stdarch-gen-loongarch/Cargo.toml+1-1
......@@ -7,4 +7,4 @@ edition = "2024"
77# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88
99[dependencies]
10rand = "0.8.5"
10rand = "0.9.3"
library/stdarch/examples/Cargo.toml+1-1
......@@ -13,7 +13,7 @@ default-run = "hex"
1313[dependencies]
1414core_arch = { path = "../crates/core_arch" }
1515quickcheck = "1.0"
16rand = "0.8"
16rand = "0.9.3"
1717
1818[[bin]]
1919name = "hex"
library/stdarch/examples/connect5.rs+2-2
......@@ -33,8 +33,8 @@
3333#![cfg_attr(target_arch = "x86_64", feature(stdarch_internal))]
3434#![feature(stmt_expr_attributes)]
3535
36use rand::rng;
3637use rand::seq::SliceRandom;
37use rand::thread_rng;
3838
3939use std::cmp;
4040use std::time::Instant;
......@@ -374,7 +374,7 @@ impl List {
374374 }
375375
376376 pub fn shuffle(&mut self) {
377 let mut rng = thread_rng();
377 let mut rng = rng();
378378 let num = self.p_size as usize;
379379
380380 self.p_move[..num].shuffle(&mut rng);
library/stdarch/examples/hex.rs+2-2
......@@ -354,9 +354,9 @@ mod benches {
354354 len: usize,
355355 f: for<'a> unsafe fn(&[u8], &'a mut [u8]) -> Result<&'a str, usize>,
356356 ) {
357 let mut rng = rand::thread_rng();
357 let mut rng = rand::rng();
358358 let input = std::iter::repeat(())
359 .map(|()| rng.r#gen::<u8>())
359 .map(|()| rng.r#random::<u8>())
360360 .take(len)
361361 .collect::<Vec<_>>();
362362 let mut dst = vec![0; input.len() * 2];
library/stdarch/intrinsics_data/arm_intrinsics.json+396
......@@ -51174,6 +51174,12 @@
5117451174 "svfloat16x2_t tuple",
5117551175 "uint64_t imm_index"
5117651176 ],
51177 "Arguments_Preparation": {
51178 "imm_index": {
51179 "minimum": 0,
51180 "maximum": 1
51181 }
51182 },
5117751183 "return_type": {
5117851184 "value": "svfloat16_t"
5117951185 },
......@@ -51188,6 +51194,12 @@
5118851194 "svfloat32x2_t tuple",
5118951195 "uint64_t imm_index"
5119051196 ],
51197 "Arguments_Preparation": {
51198 "imm_index": {
51199 "minimum": 0,
51200 "maximum": 1
51201 }
51202 },
5119151203 "return_type": {
5119251204 "value": "svfloat32_t"
5119351205 },
......@@ -51202,6 +51214,12 @@
5120251214 "svfloat64x2_t tuple",
5120351215 "uint64_t imm_index"
5120451216 ],
51217 "Arguments_Preparation": {
51218 "imm_index": {
51219 "minimum": 0,
51220 "maximum": 1
51221 }
51222 },
5120551223 "return_type": {
5120651224 "value": "svfloat64_t"
5120751225 },
......@@ -51216,6 +51234,12 @@
5121651234 "svint16x2_t tuple",
5121751235 "uint64_t imm_index"
5121851236 ],
51237 "Arguments_Preparation": {
51238 "imm_index": {
51239 "minimum": 0,
51240 "maximum": 1
51241 }
51242 },
5121951243 "return_type": {
5122051244 "value": "svint16_t"
5122151245 },
......@@ -51230,6 +51254,12 @@
5123051254 "svint32x2_t tuple",
5123151255 "uint64_t imm_index"
5123251256 ],
51257 "Arguments_Preparation": {
51258 "imm_index": {
51259 "minimum": 0,
51260 "maximum": 1
51261 }
51262 },
5123351263 "return_type": {
5123451264 "value": "svint32_t"
5123551265 },
......@@ -51244,6 +51274,12 @@
5124451274 "svint64x2_t tuple",
5124551275 "uint64_t imm_index"
5124651276 ],
51277 "Arguments_Preparation": {
51278 "imm_index": {
51279 "minimum": 0,
51280 "maximum": 1
51281 }
51282 },
5124751283 "return_type": {
5124851284 "value": "svint64_t"
5124951285 },
......@@ -51258,6 +51294,12 @@
5125851294 "svint8x2_t tuple",
5125951295 "uint64_t imm_index"
5126051296 ],
51297 "Arguments_Preparation": {
51298 "imm_index": {
51299 "minimum": 0,
51300 "maximum": 1
51301 }
51302 },
5126151303 "return_type": {
5126251304 "value": "svint8_t"
5126351305 },
......@@ -51272,6 +51314,12 @@
5127251314 "svuint16x2_t tuple",
5127351315 "uint64_t imm_index"
5127451316 ],
51317 "Arguments_Preparation": {
51318 "imm_index": {
51319 "minimum": 0,
51320 "maximum": 1
51321 }
51322 },
5127551323 "return_type": {
5127651324 "value": "svuint16_t"
5127751325 },
......@@ -51286,6 +51334,12 @@
5128651334 "svuint32x2_t tuple",
5128751335 "uint64_t imm_index"
5128851336 ],
51337 "Arguments_Preparation": {
51338 "imm_index": {
51339 "minimum": 0,
51340 "maximum": 1
51341 }
51342 },
5128951343 "return_type": {
5129051344 "value": "svuint32_t"
5129151345 },
......@@ -51300,6 +51354,12 @@
5130051354 "svuint64x2_t tuple",
5130151355 "uint64_t imm_index"
5130251356 ],
51357 "Arguments_Preparation": {
51358 "imm_index": {
51359 "minimum": 0,
51360 "maximum": 1
51361 }
51362 },
5130351363 "return_type": {
5130451364 "value": "svuint64_t"
5130551365 },
......@@ -51314,6 +51374,12 @@
5131451374 "svuint8x2_t tuple",
5131551375 "uint64_t imm_index"
5131651376 ],
51377 "Arguments_Preparation": {
51378 "imm_index": {
51379 "minimum": 0,
51380 "maximum": 1
51381 }
51382 },
5131751383 "return_type": {
5131851384 "value": "svuint8_t"
5131951385 },
......@@ -51328,6 +51394,12 @@
5132851394 "svfloat16x3_t tuple",
5132951395 "uint64_t imm_index"
5133051396 ],
51397 "Arguments_Preparation": {
51398 "imm_index": {
51399 "minimum": 0,
51400 "maximum": 2
51401 }
51402 },
5133151403 "return_type": {
5133251404 "value": "svfloat16_t"
5133351405 },
......@@ -51342,6 +51414,12 @@
5134251414 "svfloat32x3_t tuple",
5134351415 "uint64_t imm_index"
5134451416 ],
51417 "Arguments_Preparation": {
51418 "imm_index": {
51419 "minimum": 0,
51420 "maximum": 2
51421 }
51422 },
5134551423 "return_type": {
5134651424 "value": "svfloat32_t"
5134751425 },
......@@ -51356,6 +51434,12 @@
5135651434 "svfloat64x3_t tuple",
5135751435 "uint64_t imm_index"
5135851436 ],
51437 "Arguments_Preparation": {
51438 "imm_index": {
51439 "minimum": 0,
51440 "maximum": 2
51441 }
51442 },
5135951443 "return_type": {
5136051444 "value": "svfloat64_t"
5136151445 },
......@@ -51370,6 +51454,12 @@
5137051454 "svint16x3_t tuple",
5137151455 "uint64_t imm_index"
5137251456 ],
51457 "Arguments_Preparation": {
51458 "imm_index": {
51459 "minimum": 0,
51460 "maximum": 2
51461 }
51462 },
5137351463 "return_type": {
5137451464 "value": "svint16_t"
5137551465 },
......@@ -51384,6 +51474,12 @@
5138451474 "svint32x3_t tuple",
5138551475 "uint64_t imm_index"
5138651476 ],
51477 "Arguments_Preparation": {
51478 "imm_index": {
51479 "minimum": 0,
51480 "maximum": 2
51481 }
51482 },
5138751483 "return_type": {
5138851484 "value": "svint32_t"
5138951485 },
......@@ -51398,6 +51494,12 @@
5139851494 "svint64x3_t tuple",
5139951495 "uint64_t imm_index"
5140051496 ],
51497 "Arguments_Preparation": {
51498 "imm_index": {
51499 "minimum": 0,
51500 "maximum": 2
51501 }
51502 },
5140151503 "return_type": {
5140251504 "value": "svint64_t"
5140351505 },
......@@ -51412,6 +51514,12 @@
5141251514 "svint8x3_t tuple",
5141351515 "uint64_t imm_index"
5141451516 ],
51517 "Arguments_Preparation": {
51518 "imm_index": {
51519 "minimum": 0,
51520 "maximum": 2
51521 }
51522 },
5141551523 "return_type": {
5141651524 "value": "svint8_t"
5141751525 },
......@@ -51426,6 +51534,12 @@
5142651534 "svuint16x3_t tuple",
5142751535 "uint64_t imm_index"
5142851536 ],
51537 "Arguments_Preparation": {
51538 "imm_index": {
51539 "minimum": 0,
51540 "maximum": 2
51541 }
51542 },
5142951543 "return_type": {
5143051544 "value": "svuint16_t"
5143151545 },
......@@ -51440,6 +51554,12 @@
5144051554 "svuint32x3_t tuple",
5144151555 "uint64_t imm_index"
5144251556 ],
51557 "Arguments_Preparation": {
51558 "imm_index": {
51559 "minimum": 0,
51560 "maximum": 2
51561 }
51562 },
5144351563 "return_type": {
5144451564 "value": "svuint32_t"
5144551565 },
......@@ -51454,6 +51574,12 @@
5145451574 "svuint64x3_t tuple",
5145551575 "uint64_t imm_index"
5145651576 ],
51577 "Arguments_Preparation": {
51578 "imm_index": {
51579 "minimum": 0,
51580 "maximum": 2
51581 }
51582 },
5145751583 "return_type": {
5145851584 "value": "svuint64_t"
5145951585 },
......@@ -51468,6 +51594,12 @@
5146851594 "svuint8x3_t tuple",
5146951595 "uint64_t imm_index"
5147051596 ],
51597 "Arguments_Preparation": {
51598 "imm_index": {
51599 "minimum": 0,
51600 "maximum": 2
51601 }
51602 },
5147151603 "return_type": {
5147251604 "value": "svuint8_t"
5147351605 },
......@@ -51482,6 +51614,12 @@
5148251614 "svfloat16x4_t tuple",
5148351615 "uint64_t imm_index"
5148451616 ],
51617 "Arguments_Preparation": {
51618 "imm_index": {
51619 "minimum": 0,
51620 "maximum": 3
51621 }
51622 },
5148551623 "return_type": {
5148651624 "value": "svfloat16_t"
5148751625 },
......@@ -51496,6 +51634,12 @@
5149651634 "svfloat32x4_t tuple",
5149751635 "uint64_t imm_index"
5149851636 ],
51637 "Arguments_Preparation": {
51638 "imm_index": {
51639 "minimum": 0,
51640 "maximum": 3
51641 }
51642 },
5149951643 "return_type": {
5150051644 "value": "svfloat32_t"
5150151645 },
......@@ -51510,6 +51654,12 @@
5151051654 "svfloat64x4_t tuple",
5151151655 "uint64_t imm_index"
5151251656 ],
51657 "Arguments_Preparation": {
51658 "imm_index": {
51659 "minimum": 0,
51660 "maximum": 3
51661 }
51662 },
5151351663 "return_type": {
5151451664 "value": "svfloat64_t"
5151551665 },
......@@ -51524,6 +51674,12 @@
5152451674 "svint16x4_t tuple",
5152551675 "uint64_t imm_index"
5152651676 ],
51677 "Arguments_Preparation": {
51678 "imm_index": {
51679 "minimum": 0,
51680 "maximum": 3
51681 }
51682 },
5152751683 "return_type": {
5152851684 "value": "svint16_t"
5152951685 },
......@@ -51538,6 +51694,12 @@
5153851694 "svint32x4_t tuple",
5153951695 "uint64_t imm_index"
5154051696 ],
51697 "Arguments_Preparation": {
51698 "imm_index": {
51699 "minimum": 0,
51700 "maximum": 3
51701 }
51702 },
5154151703 "return_type": {
5154251704 "value": "svint32_t"
5154351705 },
......@@ -51552,6 +51714,12 @@
5155251714 "svint64x4_t tuple",
5155351715 "uint64_t imm_index"
5155451716 ],
51717 "Arguments_Preparation": {
51718 "imm_index": {
51719 "minimum": 0,
51720 "maximum": 3
51721 }
51722 },
5155551723 "return_type": {
5155651724 "value": "svint64_t"
5155751725 },
......@@ -51566,6 +51734,12 @@
5156651734 "svint8x4_t tuple",
5156751735 "uint64_t imm_index"
5156851736 ],
51737 "Arguments_Preparation": {
51738 "imm_index": {
51739 "minimum": 0,
51740 "maximum": 3
51741 }
51742 },
5156951743 "return_type": {
5157051744 "value": "svint8_t"
5157151745 },
......@@ -51580,6 +51754,12 @@
5158051754 "svuint16x4_t tuple",
5158151755 "uint64_t imm_index"
5158251756 ],
51757 "Arguments_Preparation": {
51758 "imm_index": {
51759 "minimum": 0,
51760 "maximum": 3
51761 }
51762 },
5158351763 "return_type": {
5158451764 "value": "svuint16_t"
5158551765 },
......@@ -51594,6 +51774,12 @@
5159451774 "svuint32x4_t tuple",
5159551775 "uint64_t imm_index"
5159651776 ],
51777 "Arguments_Preparation": {
51778 "imm_index": {
51779 "minimum": 0,
51780 "maximum": 3
51781 }
51782 },
5159751783 "return_type": {
5159851784 "value": "svuint32_t"
5159951785 },
......@@ -51608,6 +51794,12 @@
5160851794 "svuint64x4_t tuple",
5160951795 "uint64_t imm_index"
5161051796 ],
51797 "Arguments_Preparation": {
51798 "imm_index": {
51799 "minimum": 0,
51800 "maximum": 3
51801 }
51802 },
5161151803 "return_type": {
5161251804 "value": "svuint64_t"
5161351805 },
......@@ -51622,6 +51814,12 @@
5162251814 "svuint8x4_t tuple",
5162351815 "uint64_t imm_index"
5162451816 ],
51817 "Arguments_Preparation": {
51818 "imm_index": {
51819 "minimum": 0,
51820 "maximum": 3
51821 }
51822 },
5162551823 "return_type": {
5162651824 "value": "svuint8_t"
5162751825 },
......@@ -162999,6 +163197,12 @@
162999163197 "uint64_t imm_index",
163000163198 "svfloat16_t x"
163001163199 ],
163200 "Arguments_Preparation": {
163201 "imm_index": {
163202 "minimum": 0,
163203 "maximum": 1
163204 }
163205 },
163002163206 "return_type": {
163003163207 "value": "svfloat16x2_t"
163004163208 },
......@@ -163014,6 +163218,12 @@
163014163218 "uint64_t imm_index",
163015163219 "svfloat32_t x"
163016163220 ],
163221 "Arguments_Preparation": {
163222 "imm_index": {
163223 "minimum": 0,
163224 "maximum": 1
163225 }
163226 },
163017163227 "return_type": {
163018163228 "value": "svfloat32x2_t"
163019163229 },
......@@ -163029,6 +163239,12 @@
163029163239 "uint64_t imm_index",
163030163240 "svfloat64_t x"
163031163241 ],
163242 "Arguments_Preparation": {
163243 "imm_index": {
163244 "minimum": 0,
163245 "maximum": 1
163246 }
163247 },
163032163248 "return_type": {
163033163249 "value": "svfloat64x2_t"
163034163250 },
......@@ -163044,6 +163260,12 @@
163044163260 "uint64_t imm_index",
163045163261 "svint16_t x"
163046163262 ],
163263 "Arguments_Preparation": {
163264 "imm_index": {
163265 "minimum": 0,
163266 "maximum": 1
163267 }
163268 },
163047163269 "return_type": {
163048163270 "value": "svint16x2_t"
163049163271 },
......@@ -163059,6 +163281,12 @@
163059163281 "uint64_t imm_index",
163060163282 "svint32_t x"
163061163283 ],
163284 "Arguments_Preparation": {
163285 "imm_index": {
163286 "minimum": 0,
163287 "maximum": 1
163288 }
163289 },
163062163290 "return_type": {
163063163291 "value": "svint32x2_t"
163064163292 },
......@@ -163074,6 +163302,12 @@
163074163302 "uint64_t imm_index",
163075163303 "svint64_t x"
163076163304 ],
163305 "Arguments_Preparation": {
163306 "imm_index": {
163307 "minimum": 0,
163308 "maximum": 1
163309 }
163310 },
163077163311 "return_type": {
163078163312 "value": "svint64x2_t"
163079163313 },
......@@ -163089,6 +163323,12 @@
163089163323 "uint64_t imm_index",
163090163324 "svint8_t x"
163091163325 ],
163326 "Arguments_Preparation": {
163327 "imm_index": {
163328 "minimum": 0,
163329 "maximum": 1
163330 }
163331 },
163092163332 "return_type": {
163093163333 "value": "svint8x2_t"
163094163334 },
......@@ -163104,6 +163344,12 @@
163104163344 "uint64_t imm_index",
163105163345 "svuint16_t x"
163106163346 ],
163347 "Arguments_Preparation": {
163348 "imm_index": {
163349 "minimum": 0,
163350 "maximum": 1
163351 }
163352 },
163107163353 "return_type": {
163108163354 "value": "svuint16x2_t"
163109163355 },
......@@ -163119,6 +163365,12 @@
163119163365 "uint64_t imm_index",
163120163366 "svuint32_t x"
163121163367 ],
163368 "Arguments_Preparation": {
163369 "imm_index": {
163370 "minimum": 0,
163371 "maximum": 1
163372 }
163373 },
163122163374 "return_type": {
163123163375 "value": "svuint32x2_t"
163124163376 },
......@@ -163134,6 +163386,12 @@
163134163386 "uint64_t imm_index",
163135163387 "svuint64_t x"
163136163388 ],
163389 "Arguments_Preparation": {
163390 "imm_index": {
163391 "minimum": 0,
163392 "maximum": 1
163393 }
163394 },
163137163395 "return_type": {
163138163396 "value": "svuint64x2_t"
163139163397 },
......@@ -163149,6 +163407,12 @@
163149163407 "uint64_t imm_index",
163150163408 "svuint8_t x"
163151163409 ],
163410 "Arguments_Preparation": {
163411 "imm_index": {
163412 "minimum": 0,
163413 "maximum": 1
163414 }
163415 },
163152163416 "return_type": {
163153163417 "value": "svuint8x2_t"
163154163418 },
......@@ -163164,6 +163428,12 @@
163164163428 "uint64_t imm_index",
163165163429 "svfloat16_t x"
163166163430 ],
163431 "Arguments_Preparation": {
163432 "imm_index": {
163433 "minimum": 0,
163434 "maximum": 2
163435 }
163436 },
163167163437 "return_type": {
163168163438 "value": "svfloat16x3_t"
163169163439 },
......@@ -163179,6 +163449,12 @@
163179163449 "uint64_t imm_index",
163180163450 "svfloat32_t x"
163181163451 ],
163452 "Arguments_Preparation": {
163453 "imm_index": {
163454 "minimum": 0,
163455 "maximum": 2
163456 }
163457 },
163182163458 "return_type": {
163183163459 "value": "svfloat32x3_t"
163184163460 },
......@@ -163194,6 +163470,12 @@
163194163470 "uint64_t imm_index",
163195163471 "svfloat64_t x"
163196163472 ],
163473 "Arguments_Preparation": {
163474 "imm_index": {
163475 "minimum": 0,
163476 "maximum": 2
163477 }
163478 },
163197163479 "return_type": {
163198163480 "value": "svfloat64x3_t"
163199163481 },
......@@ -163209,6 +163491,12 @@
163209163491 "uint64_t imm_index",
163210163492 "svint16_t x"
163211163493 ],
163494 "Arguments_Preparation": {
163495 "imm_index": {
163496 "minimum": 0,
163497 "maximum": 2
163498 }
163499 },
163212163500 "return_type": {
163213163501 "value": "svint16x3_t"
163214163502 },
......@@ -163224,6 +163512,12 @@
163224163512 "uint64_t imm_index",
163225163513 "svint32_t x"
163226163514 ],
163515 "Arguments_Preparation": {
163516 "imm_index": {
163517 "minimum": 0,
163518 "maximum": 2
163519 }
163520 },
163227163521 "return_type": {
163228163522 "value": "svint32x3_t"
163229163523 },
......@@ -163239,6 +163533,12 @@
163239163533 "uint64_t imm_index",
163240163534 "svint64_t x"
163241163535 ],
163536 "Arguments_Preparation": {
163537 "imm_index": {
163538 "minimum": 0,
163539 "maximum": 2
163540 }
163541 },
163242163542 "return_type": {
163243163543 "value": "svint64x3_t"
163244163544 },
......@@ -163254,6 +163554,12 @@
163254163554 "uint64_t imm_index",
163255163555 "svint8_t x"
163256163556 ],
163557 "Arguments_Preparation": {
163558 "imm_index": {
163559 "minimum": 0,
163560 "maximum": 2
163561 }
163562 },
163257163563 "return_type": {
163258163564 "value": "svint8x3_t"
163259163565 },
......@@ -163269,6 +163575,12 @@
163269163575 "uint64_t imm_index",
163270163576 "svuint16_t x"
163271163577 ],
163578 "Arguments_Preparation": {
163579 "imm_index": {
163580 "minimum": 0,
163581 "maximum": 2
163582 }
163583 },
163272163584 "return_type": {
163273163585 "value": "svuint16x3_t"
163274163586 },
......@@ -163284,6 +163596,12 @@
163284163596 "uint64_t imm_index",
163285163597 "svuint32_t x"
163286163598 ],
163599 "Arguments_Preparation": {
163600 "imm_index": {
163601 "minimum": 0,
163602 "maximum": 2
163603 }
163604 },
163287163605 "return_type": {
163288163606 "value": "svuint32x3_t"
163289163607 },
......@@ -163299,6 +163617,12 @@
163299163617 "uint64_t imm_index",
163300163618 "svuint64_t x"
163301163619 ],
163620 "Arguments_Preparation": {
163621 "imm_index": {
163622 "minimum": 0,
163623 "maximum": 2
163624 }
163625 },
163302163626 "return_type": {
163303163627 "value": "svuint64x3_t"
163304163628 },
......@@ -163314,6 +163638,12 @@
163314163638 "uint64_t imm_index",
163315163639 "svuint8_t x"
163316163640 ],
163641 "Arguments_Preparation": {
163642 "imm_index": {
163643 "minimum": 0,
163644 "maximum": 2
163645 }
163646 },
163317163647 "return_type": {
163318163648 "value": "svuint8x3_t"
163319163649 },
......@@ -163329,6 +163659,12 @@
163329163659 "uint64_t imm_index",
163330163660 "svfloat16_t x"
163331163661 ],
163662 "Arguments_Preparation": {
163663 "imm_index": {
163664 "minimum": 0,
163665 "maximum": 3
163666 }
163667 },
163332163668 "return_type": {
163333163669 "value": "svfloat16x4_t"
163334163670 },
......@@ -163344,6 +163680,12 @@
163344163680 "uint64_t imm_index",
163345163681 "svfloat32_t x"
163346163682 ],
163683 "Arguments_Preparation": {
163684 "imm_index": {
163685 "minimum": 0,
163686 "maximum": 3
163687 }
163688 },
163347163689 "return_type": {
163348163690 "value": "svfloat32x4_t"
163349163691 },
......@@ -163359,6 +163701,12 @@
163359163701 "uint64_t imm_index",
163360163702 "svfloat64_t x"
163361163703 ],
163704 "Arguments_Preparation": {
163705 "imm_index": {
163706 "minimum": 0,
163707 "maximum": 3
163708 }
163709 },
163362163710 "return_type": {
163363163711 "value": "svfloat64x4_t"
163364163712 },
......@@ -163374,6 +163722,12 @@
163374163722 "uint64_t imm_index",
163375163723 "svint16_t x"
163376163724 ],
163725 "Arguments_Preparation": {
163726 "imm_index": {
163727 "minimum": 0,
163728 "maximum": 3
163729 }
163730 },
163377163731 "return_type": {
163378163732 "value": "svint16x4_t"
163379163733 },
......@@ -163389,6 +163743,12 @@
163389163743 "uint64_t imm_index",
163390163744 "svint32_t x"
163391163745 ],
163746 "Arguments_Preparation": {
163747 "imm_index": {
163748 "minimum": 0,
163749 "maximum": 3
163750 }
163751 },
163392163752 "return_type": {
163393163753 "value": "svint32x4_t"
163394163754 },
......@@ -163404,6 +163764,12 @@
163404163764 "uint64_t imm_index",
163405163765 "svint64_t x"
163406163766 ],
163767 "Arguments_Preparation": {
163768 "imm_index": {
163769 "minimum": 0,
163770 "maximum": 3
163771 }
163772 },
163407163773 "return_type": {
163408163774 "value": "svint64x4_t"
163409163775 },
......@@ -163419,6 +163785,12 @@
163419163785 "uint64_t imm_index",
163420163786 "svint8_t x"
163421163787 ],
163788 "Arguments_Preparation": {
163789 "imm_index": {
163790 "minimum": 0,
163791 "maximum": 3
163792 }
163793 },
163422163794 "return_type": {
163423163795 "value": "svint8x4_t"
163424163796 },
......@@ -163434,6 +163806,12 @@
163434163806 "uint64_t imm_index",
163435163807 "svuint16_t x"
163436163808 ],
163809 "Arguments_Preparation": {
163810 "imm_index": {
163811 "minimum": 0,
163812 "maximum": 3
163813 }
163814 },
163437163815 "return_type": {
163438163816 "value": "svuint16x4_t"
163439163817 },
......@@ -163449,6 +163827,12 @@
163449163827 "uint64_t imm_index",
163450163828 "svuint32_t x"
163451163829 ],
163830 "Arguments_Preparation": {
163831 "imm_index": {
163832 "minimum": 0,
163833 "maximum": 3
163834 }
163835 },
163452163836 "return_type": {
163453163837 "value": "svuint32x4_t"
163454163838 },
......@@ -163464,6 +163848,12 @@
163464163848 "uint64_t imm_index",
163465163849 "svuint64_t x"
163466163850 ],
163851 "Arguments_Preparation": {
163852 "imm_index": {
163853 "minimum": 0,
163854 "maximum": 3
163855 }
163856 },
163467163857 "return_type": {
163468163858 "value": "svuint64x4_t"
163469163859 },
......@@ -163479,6 +163869,12 @@
163479163869 "uint64_t imm_index",
163480163870 "svuint8_t x"
163481163871 ],
163872 "Arguments_Preparation": {
163873 "imm_index": {
163874 "minimum": 0,
163875 "maximum": 3
163876 }
163877 },
163482163878 "return_type": {
163483163879 "value": "svuint8x4_t"
163484163880 },
library/stdarch/rust-version+1-1
......@@ -1 +1 @@
1045b17737dab5fcc28e4cbee0cfe2ce4ed363b32
18e150217bafcaaaa0c45bf685c55fd56cec48598
src/librustdoc/formats/cache.rs+28-17
......@@ -233,6 +233,30 @@ impl Cache {
233233 }
234234}
235235
236impl CacheBuilder<'_, '_> {
237 /// Extends `dids` with ones that an impl should be associated with for a type appearing in its
238 /// `Self` type or trait generic arguments, accounting for references and `#[fundamental]`
239 /// wrappers.
240 ///
241 /// This ensures that impls like `impl Trait<Box<Local>> for Foreign`, `impl Trait for
242 /// Box<Local>`, and other variations of these, are documented on `Local`'s page.
243 fn extend_with_fundamental_dids(&self, ty: &clean::Type, dids: &mut FxIndexSet<DefId>) {
244 dids.extend(ty.def_id(self.cache));
245 // without_borrowed_ref allows cases like `impl Trait<&Box<Local>> for Foreign` to be
246 // handled by this function. (This is rare in practice, but easy to handle here.)
247 if let clean::Type::Path { path } = ty.without_borrowed_ref()
248 && let Some(generics) = path.generics()
249 && let ty::Adt(adt, _) =
250 self.tcx.type_of(path.def_id()).instantiate_identity().skip_norm_wip().kind()
251 && adt.is_fundamental()
252 {
253 for inner in generics {
254 self.extend_with_fundamental_dids(inner, dids);
255 }
256 }
257 }
258}
259
236260impl DocFolder for CacheBuilder<'_, '_> {
237261 fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
238262 if item.item_id.is_local() {
......@@ -418,22 +442,9 @@ impl DocFolder for CacheBuilder<'_, '_> {
418442 // Note: matching twice to restrict the lifetime of the `i` borrow.
419443 let mut dids = FxIndexSet::default();
420444 match i.for_ {
421 clean::Type::Path { ref path }
422 | clean::BorrowedRef { type_: clean::Type::Path { ref path }, .. } => {
423 dids.insert(path.def_id());
424 if let Some(generics) = path.generics()
425 && let ty::Adt(adt, _) = self
426 .tcx
427 .type_of(path.def_id())
428 .instantiate_identity()
429 .skip_norm_wip()
430 .kind()
431 && adt.is_fundamental()
432 {
433 for ty in generics {
434 dids.extend(ty.def_id(self.cache));
435 }
436 }
445 clean::Type::Path { .. }
446 | clean::BorrowedRef { type_: clean::Type::Path { .. }, .. } => {
447 self.extend_with_fundamental_dids(&i.for_, &mut dids);
437448 }
438449 clean::DynTrait(ref bounds, _)
439450 | clean::BorrowedRef { type_: clean::DynTrait(ref bounds, _), .. } => {
......@@ -452,7 +463,7 @@ impl DocFolder for CacheBuilder<'_, '_> {
452463 && let Some(generics) = trait_.generics()
453464 {
454465 for bound in generics {
455 dids.extend(bound.def_id(self.cache));
466 self.extend_with_fundamental_dids(bound, &mut dids);
456467 }
457468 }
458469 let impl_item = Impl { impl_item: item };
src/rustdoc-json-types/Cargo.toml+1-1
......@@ -1,7 +1,7 @@
11[package]
22name = "rustdoc-json-types"
33version = "0.1.0"
4edition = "2021"
4edition = "2024"
55
66[lib]
77path = "lib.rs"
src/tools/jsondocck/Cargo.toml+1-1
......@@ -1,7 +1,7 @@
11[package]
22name = "jsondocck"
33version = "0.1.0"
4edition = "2021"
4edition = "2024"
55
66[dependencies]
77jsonpath-rust = "1.0.0"
src/tools/jsondoclint/Cargo.toml+1-1
......@@ -1,7 +1,7 @@
11[package]
22name = "jsondoclint"
33version = "0.1.0"
4edition = "2021"
4edition = "2024"
55
66# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77
src/tools/miri/README.md+33-20
......@@ -171,6 +171,38 @@ available (which affects `cfg(target_feature)`), and it tells Miri to consider t
171171that the interpreted program runs on as having the feature available (meaning the code is allowed to
172172invoke the corresponding intrinsics).
173173
174### Nextest integration
175
176Miri can be combined with [`cargo-nextest`](https://nexte.st):
177
178```
179cargo install --locked cargo-nextest
180cargo miri nextest run
181```
182
183Nextest spawns a separate instance of Miri for each test, which has several advantages:
184- Tests can run in parallel. Miri itself only uses a single thread per interpreter so this can
185 give a massive speedup (but see the caveat below).
186- Tests do not stop when a single problem is found. Miri aborts execution when it encounters
187 Undefined Behavior or an unsupported operation (there is often not really any way to continue),
188 so once a single test fails, the remaining tests cannot be executed. Nextest's process-per-test
189 model means that you end up with a full list of which tests worked in Miri and which tests had a
190 problem.
191
192However, there is also a big caveat: Miri will [re-compile the test crate every time it is
193invoked](https://github.com/rust-lang/miri/issues/5013), which means a crate with N tests will be
194compiled N+1 times. If the test crate takes a long time to build, this can outweigh the benefits of
195parallelization.
196
197For more information about nextest, see the [`cargo-nextest` Miri
198documentation](https://nexte.st/book/miri.html).
199
200Note: Nextest's one-test-per-process model means that `cargo miri test` is able to detect data
201races where two tests race on a shared resource, but `cargo miri nextest run` will not detect
202such races.
203
204Note: `cargo-nextest` [does not support doctests](https://github.com/nextest-rs/nextest/issues/16).
205
174206### Testing multiple different executions
175207
176208Certain parts of the execution are picked randomly by Miri, such as the exact base address
......@@ -184,6 +216,7 @@ MIRIFLAGS="-Zmiri-many-seeds" cargo miri test # tries the seeds in 0..64
184216MIRIFLAGS="-Zmiri-many-seeds=0..16" cargo miri test
185217```
186218
219Miri will test the given range of seeds with parallel interpreter instances.
187220The default of 64 different seeds can be quite slow, so you often want to specify a smaller range.
188221
189222### Running Miri on CI
......@@ -243,26 +276,6 @@ However, even for targets that we do support, the degree of support for accessin
243276(such as the file system) differs between targets: generally, Linux targets have the best support,
244277and macOS targets are usually on par. Windows is supported less well.
245278
246### Running tests in parallel
247
248Though it implements Rust threading, Miri itself is a single-threaded interpreter
249(it works like a multi-threaded OS on a single-core CPU).
250This means that when running `cargo miri test`, you will probably see a dramatic
251increase in the amount of time it takes to run your whole test suite due to the
252inherent interpreter slowdown and a loss of parallelism.
253
254You can get your test suite's parallelism back by running `cargo miri nextest run -jN`
255(note that you will need [`cargo-nextest`](https://nexte.st) installed).
256This works because `cargo-nextest` collects a list of all tests then launches a
257separate `cargo miri run` for each test. For more information about nextest, see the
258[`cargo-nextest` Miri documentation](https://nexte.st/book/miri.html).
259
260Note: This one-test-per-process model means that `cargo miri test` is able to detect data
261races where two tests race on a shared resource, but `cargo miri nextest run` will not detect
262such races.
263
264Note: `cargo-nextest` does not support doctests, see https://github.com/nextest-rs/nextest/issues/16
265
266279### Directly invoking the `miri` driver
267280
268281The recommended way to invoke Miri is via `cargo miri`. Directly invoking the underlying `miri`
src/tools/miri/cargo-miri/src/phases.rs+3
......@@ -36,6 +36,9 @@ Examples:
3636 This will print the path to the generated sysroot (and nothing else) on stdout.
3737 stderr will still contain progress information about how the build is doing.
3838
39For documentation on `-Zmiri-...` flags, see Miri's README.md, available at:
40- $(rustc --print sysroot)/share/doc/miri/README.md
41- https://github.com/rust-lang/miri/blob/master/README.md
3942";
4043
4144fn show_help() {
src/tools/miri/ci/ci.sh+1
......@@ -168,6 +168,7 @@ case $HOST_TARGET in
168168 MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-freebsd run_tests
169169 MANY_SEEDS=16 TEST_TARGET=i686-unknown-freebsd run_tests
170170 MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-illumos run_tests
171 MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-netbsd run_tests_minimal hello
171172 ;;
172173 armv7-unknown-linux-gnueabihf)
173174 # Host
src/tools/miri/priroda/src/main.rs+62-11
......@@ -6,6 +6,7 @@ extern crate rustc_data_structures;
66extern crate rustc_driver;
77extern crate rustc_hir;
88extern crate rustc_hir_analysis;
9extern crate rustc_index;
910extern crate rustc_interface;
1011extern crate rustc_log;
1112extern crate rustc_middle;
......@@ -19,13 +20,15 @@ use std::path::PathBuf;
1920use miri::*;
2021use rustc_driver::Compilation;
2122use rustc_hir::attrs::CrateType;
23use rustc_index::IndexVec;
2224use rustc_interface::interface;
2325use rustc_middle::mir;
26use rustc_middle::mir::{Local, VarDebugInfoContents};
2427use rustc_middle::ty::TyCtxt;
2528use rustc_session::EarlyDiagCtxt;
2629use rustc_session::config::ErrorOutputType;
27use rustc_span::Span;
2830use rustc_span::source_map::SourceMap;
31use rustc_span::{Span, Symbol};
2932
3033fn find_sysroot() -> String {
3134 std::env::var("MIRI_SYSROOT")
......@@ -129,6 +132,11 @@ struct PrirodaContext<'tcx> {
129132 last_location: Option<SourceLocation>,
130133}
131134
135struct LocalDesc {
136 name: Option<Symbol>,
137 local: Local,
138 ty: String,
139}
132140/// Controls when execution returns to the frontend.
133141enum ResumeMode {
134142 /// Stop at the next visible MIR instruction.
......@@ -336,15 +344,49 @@ impl<'tcx> PrirodaContext<'tcx> {
336344 }
337345 }
338346
339 /// Returns the names of all user-visible locals in the innermost stack frame.
347 /// Returns structured descriptions for locals in the innermost stack frame.
340348 ///
341 /// Uses `var_debug_info` from the MIR body, which is the same source that
342 /// DWARF debug info is built from, so the names match what the user wrote.
343 fn list_locals(&self) -> Vec<String> {
349 /// Starts from all MIR locals, then enriches them with source names from
350 /// `var_debug_info` when a debug entry maps directly to a whole local.
351 fn list_locals(&self) -> Vec<LocalDesc> {
344352 let Some(frame) = self.ecx.active_thread_stack().last() else {
345353 return Vec::new();
346354 };
347 frame.body().var_debug_info.iter().map(|info| info.name.to_string()).collect()
355
356 self.local_desc_map(frame).into_iter().collect()
357 }
358
359 fn local_desc_map(
360 &self,
361 frame: &Frame<'tcx, Provenance, FrameExtra<'tcx>>,
362 ) -> IndexVec<Local, LocalDesc> {
363 // Initialize one description per MIR local so the table can be indexed by Local.
364 let mut locals: IndexVec<Local, LocalDesc> = frame
365 .body()
366 .local_decls
367 .iter_enumerated()
368 .map(|(id, local_decl)| {
369 LocalDesc { name: None, local: id, ty: local_decl.ty.to_string() }
370 })
371 .collect();
372
373 // FIXME: Some debug-info entries do not have a backing MIR local, for example
374 // because the source variable was optimized out or is represented as a
375 // projection. This local-indexed table cannot represent those entries yet;
376 // the final locals list should become a `Vec<LocalDesc>` with `id : Option<Local>`, `id`
377 // could be renamed to `local`.
378
379 // Attach source names from debug info when the debug entry maps directly to a whole MIR local.
380 for var_debug_info in &frame.body().var_debug_info {
381 if let VarDebugInfoContents::Place(place) = var_debug_info.value
382 && let Some(local) = place.as_local()
383 && locals[local].name.is_none()
384 {
385 locals[local].name = Some(var_debug_info.name);
386 }
387 }
388
389 locals
348390 }
349391}
350392
......@@ -366,7 +408,7 @@ enum BreakpointSetResult {
366408enum CommandResult {
367409 ExecutionStopped(StepResult),
368410 BreakpointResult(BreakpointSetResult),
369 Locals(Vec<String>),
411 Locals(Vec<LocalDesc>),
370412 // FIXME: distinguish terminating the debugger session from disconnecting a
371413 // frontend and terminating the interpreted program once multiple frontends exist.
372414 TerminateSession,
......@@ -403,12 +445,21 @@ impl Cli {
403445
404446 BreakpointSetResult::Duplicate => println!("Duplicate breakpoint"),
405447 },
406 CommandResult::Locals(names) =>
407 if names.is_empty() {
448 CommandResult::Locals(locals_desc) =>
449 if locals_desc.is_empty() {
408450 println!("no locals");
409451 } else {
410 for name in &names {
411 println!("{name}");
452 for local_desc in &locals_desc {
453 let mut name_str = "None".to_string();
454 if let Some(name) = local_desc.name {
455 name_str = name.to_string();
456 }
457 println!(
458 "Name: {}, Id: _{}, Ty: {}",
459 name_str,
460 local_desc.local.index(),
461 local_desc.ty,
462 );
412463 }
413464 },
414465 CommandResult::TerminateSession => {
src/tools/miri/priroda/tests/ui/locals_in_function.stdout+6-2
......@@ -1,6 +1,10 @@
11(priroda) breakpoint added: {MANIFEST_DIR}/tests/ui/locals_in_function.rs:5
22(priroda) Hit breakpoint
33{MANIFEST_DIR}/tests/ui/locals_in_function.rs:5
4(priroda) x
5y
4(priroda) Name: None, Id: _0, Ty: ()
5Name: x, Id: _1, Ty: i32
6Name: y, Id: _2, Ty: bool
7Name: None, Id: _3, Ty: (i32, bool)
8Name: None, Id: _4, Ty: i32
9Name: None, Id: _5, Ty: bool
610(priroda) quitting
src/tools/miri/rust-version+1-1
......@@ -1 +1 @@
101f54e80e888b66d6486a3a95d481b87353016df
116761606d606b6ec4d0c88fc9251670742ad9fd2
src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs+3-1
......@@ -574,7 +574,9 @@ impl<'tcx> Tree {
574574 // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`).
575575 // Related to https://github.com/rust-lang/rust/issues/55005.
576576 && !perm.permission.is_cell()
577 // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579.
577 // Only trigger UB if the accessed bit is set, i.e. if the protector
578 // is actually protecting this offset. See #4579. Note that this
579 // takes into account the access we just did above!
578580 && perm.accessed
579581 {
580582 Err(TbError {
src/tools/miri/src/helpers.rs+7-1
......@@ -129,7 +129,13 @@ pub fn iter_exported_symbols<'tcx>(
129129 || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)
130130 || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
131131 };
132 if exported {
132 // FIXME: `#[no_mangle]` makes no sense on a generic item, but still causes it to be
133 // considered "extern". Remove this once `no_mangle_generic_items` is a hard error.
134 let exported_mono = exported && {
135 let generics = tcx.generics_of(def_id);
136 !generics.requires_monomorphization(tcx)
137 };
138 if exported_mono {
133139 f(LOCAL_CRATE, def_id.into())?;
134140 }
135141 }
src/tools/miri/src/shims/aarch64.rs+39
......@@ -146,6 +146,45 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
146146 }
147147 }
148148
149 // Signed saturating doubling multiply returning the high half.
150 //
151 // Used by the `vqdmulh*` functions.
152 //
153 // This LLVM intrinsic multiplies the values of corresponding elements of the two source
154 // vector registers (which are signed integers), doubles the results, places the most significant half of the
155 // final results (using a saturating cast to fit the element type) into a vector, and writes the vector to the destination register.
156 //
157 // https://developer.arm.com/architectures/instruction-sets/intrinsics#f:@navigationhierarchiessimdisa=[Neon]&q=vqdmulh
158 name if name.starts_with("neon.sqdmulh.") => {
159 let [left, right] =
160 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
161
162 let (left, left_len) = this.project_to_simd(left)?;
163 let (right, right_len) = this.project_to_simd(right)?;
164 let (dest, dest_len) = this.project_to_simd(dest)?;
165 assert_eq!(left_len, right_len);
166 assert_eq!(left_len, dest_len);
167
168 let elem_size = dest.layout.field(this, 0).size;
169 let bits = elem_size.bits();
170 let min = elem_size.signed_int_min();
171 let max = elem_size.signed_int_max();
172
173 for i in 0..dest_len {
174 let a = this.read_scalar(&this.project_index(&left, i)?)?.to_int(elem_size)?;
175 let b = this.read_scalar(&this.project_index(&right, i)?)?.to_int(elem_size)?;
176
177 // Uses i128 arithmetic, which cannot overflow because the intrinsic takes at most i32.
178 let doubled = a.strict_mul(b).strict_mul(2);
179 let res = (doubled >> bits).clamp(min, max);
180
181 this.write_scalar(
182 Scalar::from_int(res, elem_size),
183 &this.project_index(&dest, i)?,
184 )?;
185 }
186 }
187
149188 // Vector table lookup: each index selects a byte from the 16-byte table, out-of-range -> 0.
150189 // Used to implement vtbl1_u8 function.
151190 // LLVM does not have a portable shuffle that takes non-const indices
src/tools/miri/src/shims/foreign_items.rs+1-1
......@@ -789,7 +789,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
789789 }
790790
791791 // LLVM intrinsics
792 "llvm.prefetch" => {
792 "llvm.prefetch.p0" => {
793793 let [p, rw, loc, ty] =
794794 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
795795
src/tools/miri/src/shims/unix/foreign_items.rs+33-5
......@@ -840,18 +840,46 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
840840 }
841841
842842 "mmap" => {
843 let [addr, length, prot, flags, fd, offset] =
844 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
843 let [addr, length, prot, flags, fd, offset] = this.check_shim_sig(
844 shim_sig!(extern "C" fn(*mut _, usize, i32, i32, i32, libc::off_t) -> *mut _),
845 link_name,
846 abi,
847 args,
848 )?;
845849 let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
846850 let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
847851 this.write_scalar(ptr, dest)?;
848852 }
849853 "munmap" => {
850 let [addr, length] =
851 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
854 let [addr, length] = this.check_shim_sig(
855 shim_sig!(extern "C" fn(*mut _, usize) -> i32),
856 link_name,
857 abi,
858 args,
859 )?;
852860 let result = this.munmap(addr, length)?;
853861 this.write_scalar(result, dest)?;
854862 }
863 "mprotect" => {
864 let [addr, length, prot] = this.check_shim_sig(
865 shim_sig!(extern "C" fn(*mut _, usize, i32) -> i32),
866 link_name,
867 abi,
868 args,
869 )?;
870 let result = this.mprotect(addr, length, prot)?;
871 this.write_scalar(result, dest)?;
872 }
873 "madvise" => {
874 let [addr, length, advice] = this.check_shim_sig(
875 shim_sig!(extern "C" fn(*mut _, usize, i32) -> i32),
876 link_name,
877 abi,
878 args,
879 )?;
880 let result = this.madvise(addr, length, advice)?;
881 this.write_scalar(result, dest)?;
882 }
855883
856884 "reallocarray" => {
857885 // Currently this function does not exist on all Unixes, e.g. on macOS.
......@@ -1410,7 +1438,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14101438 let [_, _] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
14111439 this.write_null(dest)?;
14121440 }
1413 "sigaction" | "mprotect" if this.frame_in_std() => {
1441 "sigaction" if this.frame_in_std() => {
14141442 let [_, _, _] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
14151443 this.write_null(dest)?;
14161444 }
src/tools/miri/src/shims/unix/mem.rs+105-20
......@@ -53,9 +53,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
5353 return interp_ok(Scalar::from_maybe_pointer(Pointer::without_provenance(addr), this));
5454 }
5555
56 let prot_read = this.eval_libc_i32("PROT_READ");
57 let prot_write = this.eval_libc_i32("PROT_WRITE");
58
5956 // First, we do some basic argument validation as required by mmap
6057 if (flags & (map_private | map_shared)).count_ones() != 1 {
6158 this.set_last_error(LibcError("EINVAL"))?;
......@@ -80,13 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
8077 );
8178 }
8279
83 // Miri doesn't support protections other than PROT_READ|PROT_WRITE.
84 if prot != prot_read | prot_write {
85 throw_unsup_format!(
86 "Miri does not support calls to mmap with protections other than \
87 PROT_READ|PROT_WRITE",
88 );
89 }
80 verify_prot(this, prot)?;
9081
9182 // Miri does not support shared mappings, or any of the other extensions that for example
9283 // Linux has added to the flags arguments.
......@@ -103,14 +94,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10394 }
10495
10596 let align = this.machine.page_align();
106 let Some(map_length) = length.checked_next_multiple_of(this.machine.page_size) else {
97 let Some(map_length) = round_up_to_page_size(this, length) else {
10798 this.set_last_error(LibcError("EINVAL"))?;
10899 return interp_ok(this.eval_libc("MAP_FAILED"));
109100 };
110 if map_length > this.target_usize_max() {
111 this.set_last_error(LibcError("EINVAL"))?;
112 return interp_ok(this.eval_libc("MAP_FAILED"));
113 }
114101
115102 let ptr = this.allocate_ptr(
116103 Size::from_bytes(map_length),
......@@ -135,13 +122,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
135122 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
136123 }
137124
138 let Some(length) = length.checked_next_multiple_of(this.machine.page_size) else {
125 let Some(length) = round_up_to_page_size(this, length) else {
139126 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
140127 };
141 if length > this.target_usize_max() {
142 this.set_last_error(LibcError("EINVAL"))?;
143 return interp_ok(this.eval_libc("MAP_FAILED"));
144 }
145128
146129 let length = Size::from_bytes(length);
147130 this.deallocate_ptr(
......@@ -152,4 +135,106 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152135
153136 interp_ok(Scalar::from_i32(0))
154137 }
138
139 fn mprotect(
140 &mut self,
141 addr: &OpTy<'tcx>,
142 length: &OpTy<'tcx>,
143 prot: &OpTy<'tcx>,
144 ) -> InterpResult<'tcx, Scalar> {
145 let this = self.eval_context_mut();
146
147 let addr = this.read_pointer(addr)?;
148 let length = this.read_target_usize(length)?;
149 let prot = this.read_scalar(prot)?.to_i32()?;
150
151 // addr must be a multiple of the page size.
152 if !addr.addr().bytes().is_multiple_of(this.machine.page_size) {
153 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
154 }
155
156 verify_prot(this, prot)?;
157
158 // The pages from `[addr, addr + length)` must be mapped, so length definitely must not overflow.
159 let Some(length) = round_up_to_page_size(this, length) else {
160 return this.set_errno_and_return_neg1_i32(LibcError("ENOMEM"));
161 };
162 // Ensure this is actually allocated memory we can access.
163 this.check_ptr_access(addr, Size::from_bytes(length), CheckInAllocMsg::MemoryAccess)
164 .map_err_kind(|_| err_ub_format!("`mprotect` called on out-of-bounds memory"))?;
165
166 // If the memory comes from memory the Rust program has allocated with mmap, we only support
167 // `PROT_READ|PROT_WRITE`, so this `mprotect` is a no-op. If the memory was mmaped by the
168 // runtime (e.g. if it's the stack, executable memory, or static memory), POSIX also allows
169 // us to remap it. In those cases, such a call to `PROT_READ|PROT_WRITE` might actually change the permissions,
170 // but treating them as the new permissions is still UB. Therefore, we just pretend that we
171 // did the permission change by returning success, and will still reject if you try to use
172 // it with the "new" permissions.
173 interp_ok(Scalar::from_i32(0))
174 }
175
176 fn madvise(
177 &mut self,
178 addr: &OpTy<'tcx>,
179 length: &OpTy<'tcx>,
180 advice: &OpTy<'tcx>,
181 ) -> InterpResult<'tcx, Scalar> {
182 let this = self.eval_context_mut();
183
184 let addr = this.read_pointer(addr)?;
185 let length = this.read_target_usize(length)?;
186 let advise = this.read_scalar(advice)?.to_i32()?;
187
188 // addr must be a multiple of the page size.
189 if !addr.addr().bytes().is_multiple_of(this.machine.page_size) {
190 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
191 }
192
193 // advise must be supported.
194 let madv_normal = this.eval_libc_i32("MADV_NORMAL");
195 let madv_random = this.eval_libc_i32("MADV_RANDOM");
196 let madv_sequential = this.eval_libc_i32("MADV_SEQUENTIAL");
197 let madv_willneed = this.eval_libc_i32("MADV_WILLNEED");
198 if advise != madv_normal
199 && advise != madv_random
200 && advise != madv_sequential
201 && advise != madv_willneed
202 {
203 throw_unsup_format!(
204 "Miri does not support calls to madvise with advice other than MADV_NORMAL, MADV_RANDOM, MADV_SEQUENTIAL, or MADV_WILLNEED",
205 );
206 }
207
208 // The pages from `[addr, addr + length)` must be mapped, so length definitely must not overflow.
209 let Some(length) = round_up_to_page_size(this, length) else {
210 return this.set_errno_and_return_neg1_i32(LibcError("ENOMEM"));
211 };
212 // Ensure this is actually allocated memory we can access.
213 this.check_ptr_access(addr, Size::from_bytes(length), CheckInAllocMsg::MemoryAccess)
214 .map_err_kind(|_| err_ub_format!("`madvise` called on out-of-bounds memory"))?;
215
216 // All advises we support are no-ops.
217 interp_ok(Scalar::from_i32(0))
218 }
219}
220
221fn round_up_to_page_size(this: &MiriInterpCx<'_>, length: u64) -> Option<u64> {
222 length
223 .checked_next_multiple_of(this.machine.page_size)
224 .filter(|length| *length <= this.target_isize_max().try_into().unwrap())
225}
226
227fn verify_prot<'tcx>(this: &mut MiriInterpCx<'tcx>, prot: i32) -> InterpResult<'tcx> {
228 let prot_read = this.eval_libc_i32("PROT_READ");
229 let prot_write = this.eval_libc_i32("PROT_WRITE");
230
231 // Miri doesn't support protections other than PROT_READ|PROT_WRITE.
232 if prot != prot_read | prot_write {
233 throw_unsup_format!(
234 "Miri does not support calls to mmap/mprotect with protections other than \
235 PROT_READ|PROT_WRITE",
236 );
237 }
238
239 interp_ok(())
155240}
src/tools/miri/src/shims/unix/socket.rs+28-8
......@@ -1487,9 +1487,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14871487 // Only shutting down the write end doesn't cause an EPOLLHUP event
14881488 // and thus we won't set the `write_closed` readiness for it here.
14891489 readiness.write_closed |= is_read_write_shutdown;
1490 // The Linux kernel also sets EPOLLIN when both ends of a socket are closed:
1490 // The Linux kernel also sets EPOLLIN when the read end of a socket is closed:
14911491 // <https://github.com/torvalds/linux/blob/HEAD/net/ipv4/tcp.c#L584-L588>
1492 readiness.readable |= is_read_write_shutdown;
1492 readiness.readable |= is_read_shutdown || is_read_write_shutdown;
14931493
14941494 drop(readiness);
14951495
......@@ -1697,12 +1697,16 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
16971697 ) -> InterpResult<'tcx, Result<usize, IoError>> {
16981698 let this = self.eval_context_mut();
16991699
1700 let SocketState::Connected(stream) = &mut *socket.state.borrow_mut() else {
1700 let mut state = socket.state.borrow_mut();
1701 let SocketState::Connected(stream) = &mut *state else {
17011702 panic!("try_non_block_send must only be called when the socket is connected")
17021703 };
17031704
17041705 // This is a *non-blocking* write.
17051706 let result = this.write_to_host(stream, length, buffer_ptr)?;
1707
1708 drop(state);
1709
17061710 match result {
17071711 Err(IoError::HostError(e))
17081712 if matches!(e.kind(), io::ErrorKind::NotConnected | io::ErrorKind::WouldBlock) =>
......@@ -1715,8 +1719,13 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
17151719 // would be returned on UNIX-like systems. We thus remap this error to an EWOULDBLOCK.
17161720 interp_ok(Err(IoError::HostError(io::ErrorKind::WouldBlock.into())))
17171721 }
1718 Ok(bytes_written) if bytes_written < length => {
1719 // We had a short write. On Unix hosts using the `epoll` and `kqueue` backends, a
1722 Ok(bytes_written)
1723 if bytes_written < length && !socket.io_readiness.borrow().write_closed =>
1724 {
1725 // We had a short write. (Note that we don't want to clear the writable readiness for
1726 // sockets whose write end has already been closed as those never block a write, i.e.,
1727 // they are always write-ready.)
1728 // On Unix hosts using the `epoll` and `kqueue` backends, a
17201729 // short write means that the write buffer is full. We update the readiness
17211730 // accordingly, which means that next time we see "writable" we will report an epoll
17221731 // edge. Some applications (e.g. tokio) rely on this behavior; see
......@@ -1820,7 +1829,8 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
18201829 ) -> InterpResult<'tcx, Result<usize, IoError>> {
18211830 let this = self.eval_context_mut();
18221831
1823 let SocketState::Connected(stream) = &mut *socket.state.borrow_mut() else {
1832 let mut state = socket.state.borrow_mut();
1833 let SocketState::Connected(stream) = &mut *state else {
18241834 panic!("try_non_block_recv must only be called when the socket is connected")
18251835 };
18261836
......@@ -1832,6 +1842,9 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
18321842 length,
18331843 buffer_ptr,
18341844 )?;
1845
1846 drop(state);
1847
18351848 match result {
18361849 Err(IoError::HostError(e))
18371850 if matches!(e.kind(), io::ErrorKind::NotConnected | io::ErrorKind::WouldBlock) =>
......@@ -1844,9 +1857,16 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
18441857 // would be returned on UNIX-like systems. We thus remap this error to an EWOULDBLOCK.
18451858 interp_ok(Err(IoError::HostError(io::ErrorKind::WouldBlock.into())))
18461859 }
1847 Ok(bytes_read) if !should_peek && bytes_read < length && bytes_read > 0 => {
1860 Ok(bytes_read)
1861 if !should_peek
1862 && bytes_read < length
1863 && bytes_read > 0
1864 && !socket.io_readiness.borrow().read_closed =>
1865 {
18481866 // We had a short read (and were not peeking). (Note that reading 0 bytes is guaranteed
1849 // to indicate EOF, and can never happen spuriously, so we have to exclude that case.)
1867 // to indicate EOF, and can never happen spuriously, so we have to exclude that case.
1868 // We also don't want to clear the readable readiness for sockets whose read end has
1869 // already been closed as those never block a read, i.e., they are always read-ready.)
18501870 // On Unix hosts using the `epoll` and `kqueue` backends, a short read means that the
18511871 // read buffer is empty. We update the readiness accordingly, which means that next time
18521872 // we see "readable" we will report an epoll edge. Some applications (e.g. tokio) rely on
src/tools/miri/src/shims/unix/sync.rs+10-4
......@@ -35,7 +35,13 @@ const PTHREAD_INIT: u8 = 1;
3535#[inline]
3636fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
3737 interp_ok(match &ecx.tcx.sess.target.os {
38 Os::Linux | Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android => 0,
38 Os::Linux
39 | Os::Illumos
40 | Os::Solaris
41 | Os::MacOs
42 | Os::FreeBsd
43 | Os::Android
44 | Os::NetBsd => 0,
3945 os => throw_unsup_format!("`pthread_mutexattr` is not supported on {os}"),
4046 })
4147}
......@@ -135,8 +141,8 @@ impl SyncObj for PthreadMutex {
135141fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> {
136142 let offset = match &ecx.tcx.sess.target.os {
137143 Os::Linux | Os::Illumos | Os::Solaris | Os::FreeBsd | Os::Android => 0,
138 // macOS stores a signature in the first bytes, so we move to offset 4.
139 Os::MacOs => 4,
144 // macOS and NetBSD store a signature in the first bytes, so we move to offset 4.
145 Os::MacOs | Os::NetBsd => 4,
140146 os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"),
141147 };
142148 let offset = Size::from_bytes(offset);
......@@ -163,7 +169,7 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size>
163169 check_static_initializer("PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP");
164170 check_static_initializer("PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP");
165171 }
166 Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android => {
172 Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android | Os::NetBsd => {
167173 // No non-standard initializers.
168174 }
169175 os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"),
src/tools/miri/src/shims/x86/mod.rs+14-8
......@@ -879,33 +879,39 @@ fn mpsadbw<'tcx>(
879879 assert_eq!(left.layout.size, dest.layout.size);
880880
881881 let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?;
882 assert!(num_chunks <= 2);
883
882884 let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?;
883885 let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(ecx, dest)?;
884886
885887 assert_eq!(op_items_per_chunk, dest_items_per_chunk.strict_mul(2));
886888
887889 let imm = ecx.read_scalar(imm)?.to_uint(imm.layout.size)?;
888 // Bit 2 of `imm` specifies the offset for indices of `left`.
889 // The offset is 0 when the bit is 0 or 4 when the bit is 1.
890 let left_offset = u64::try_from((imm >> 2) & 1).unwrap().strict_mul(4);
891 // Bits 0..=1 of `imm` specify the offset for indices of
892 // `right` in blocks of 4 elements.
893 let right_offset = u64::try_from(imm & 0b11).unwrap().strict_mul(4);
894890
895891 for i in 0..num_chunks {
896892 let left = ecx.project_index(&left, i)?;
897893 let right = ecx.project_index(&right, i)?;
898894 let dest = ecx.project_index(&dest, i)?;
899895
896 // The first 128-bit chunk uses the low 3 bits of IMM, the second chunk uses bits 3..6.
897 let lane_imm = imm.strict_shr(i.strict_mul(3).try_into().unwrap());
898
899 // Bit 2 of `lane_imm` specifies the offset for indices of `left`.
900 // The offset is 0 when the bit is 0 or 4 when the bit is 1.
901 let left_base = u64::try_from((lane_imm >> 2) & 1).unwrap().strict_mul(4);
902 // Bits 0..=1 of `lane_imm` specify the offset for indices of
903 // `right` in blocks of 4 elements.
904 let right_base = u64::try_from(lane_imm & 0b11).unwrap().strict_mul(4);
905
900906 for j in 0..dest_items_per_chunk {
901 let left_offset = left_offset.strict_add(j);
907 let left_offset = left_base.strict_add(j);
902908 let mut res: u16 = 0;
903909 for k in 0..4 {
904910 let left = ecx
905911 .read_scalar(&ecx.project_index(&left, left_offset.strict_add(k))?)?
906912 .to_u8()?;
907913 let right = ecx
908 .read_scalar(&ecx.project_index(&right, right_offset.strict_add(k))?)?
914 .read_scalar(&ecx.project_index(&right, right_base.strict_add(k))?)?
909915 .to_u8()?;
910916 res = res.strict_add(left.abs_diff(right).into());
911917 }
src/tools/miri/test-cargo-miri/run-test.py+4-3
......@@ -170,9 +170,10 @@ def test_cargo_miri_test():
170170 "test.empty.ref",
171171 env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
172172 )
173 test("`cargo miri test` (proc-macro crate)",
174 cargo_miri("test") + ["-p", "proc_macro_crate"],
175 "test.proc-macro.stdout.ref", "test.proc-macro.stderr.ref",
173 test("`cargo miri test` (entire workspace, no isolation)",
174 cargo_miri("test") + ["--workspace"],
175 "test.workspace.stdout.ref", "test.workspace.stderr.ref",
176 env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
176177 )
177178 test("`cargo miri test` (custom target dir)",
178179 cargo_miri("test") + ["--target-dir=custom-test"],
src/tools/miri/test-cargo-miri/test.proc-macro.stderr.ref deleted-2
......@@ -1,2 +0,0 @@
1warning: unit tests of `proc-macro` crates are executed outside Miri
2warning: doc tests of `proc-macro` crates are not supported by Miri
src/tools/miri/test-cargo-miri/test.proc-macro.stdout.ref deleted-5
......@@ -1,5 +0,0 @@
1
2running 0 tests
3
4test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
5
src/tools/miri/test-cargo-miri/test.workspace.stderr.ref created+2
......@@ -0,0 +1,2 @@
1warning: unit tests of `proc-macro` crates are executed outside Miri
2warning: doc tests of `proc-macro` crates are not supported by Miri
src/tools/miri/test-cargo-miri/test.workspace.stdout.ref created+103
......@@ -0,0 +1,103 @@
1
2running 2 tests
3..
4test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
5
6imported main
7
8running 6 tests
9...i..
10test result: ok. 5 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME
11
12
13running 0 tests
14
15test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
16
17
18running 0 tests
19
20test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
21
22
23running 0 tests
24
25test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
26
27
28running 0 tests
29
30test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
31
32
33running 0 tests
34
35test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
36
37
38running 0 tests
39
40test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
41
42
43running 0 tests
44
45test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
46
47
48running 0 tests
49
50test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
51
52
53running 0 tests
54
55test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
56
57subcrate testing
58
59running 0 tests
60
61test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
62
63
64running 5 tests
65.....
66test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
67
68all doctests ran in $TIME; merged doctests compilation took $TIME
69
70running 0 tests
71
72test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
73
74
75running 0 tests
76
77test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
78
79
80running 0 tests
81
82test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
83
84
85running 0 tests
86
87test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
88
89
90running 0 tests
91
92test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
93
94
95running 0 tests
96
97test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
98
99
100running 1 test
101.
102test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
103
src/tools/miri/tests/deps/Cargo.lock-1
......@@ -290,7 +290,6 @@ dependencies = [
290290name = "miri-test-deps"
291291version = "0.1.0"
292292dependencies = [
293 "cfg-if",
294293 "futures",
295294 "getrandom 0.1.16",
296295 "getrandom 0.2.17",
src/tools/miri/tests/deps/Cargo.toml-1
......@@ -10,7 +10,6 @@ edition = "2021"
1010# all dependencies (and their transitive ones) listed here can be used in `tests/*-dep`.
1111libc = "0.2"
1212num_cpus = "1.10.1"
13cfg-if = "1"
1413
1514getrandom_01 = { package = "getrandom", version = "0.1" }
1615getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] }
src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.rs+5-1
......@@ -4,6 +4,10 @@
44
55use std::thread;
66
7#[path = "../../utils/libc.rs"]
8mod libc_utils;
9use libc_utils::*;
10
711// Test the behaviour of a thread being blocked on an eventfd read, get unblocked, and then
812// get blocked again.
913
......@@ -18,7 +22,7 @@ fn main() {
1822 // eventfd write will block when EFD_NONBLOCK flag is clear
1923 // and the addition caused counter to exceed u64::MAX - 1.
2024 let flags = libc::EFD_CLOEXEC;
21 let fd = unsafe { libc::eventfd(0, flags) };
25 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
2226
2327 let thread1 = thread::spawn(move || {
2428 let mut buf: [u8; 8] = [0; 8];
src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.rs+5-1
......@@ -4,6 +4,10 @@
44
55use std::thread;
66
7#[path = "../../utils/libc.rs"]
8mod libc_utils;
9use libc_utils::*;
10
711// Test the behaviour of a thread being blocked on an eventfd `write`, get unblocked, and then
812// get blocked again.
913
......@@ -17,7 +21,7 @@ fn main() {
1721 // eventfd write will block when EFD_NONBLOCK flag is clear
1822 // and the addition caused counter to exceed u64::MAX - 1.
1923 let flags = libc::EFD_CLOEXEC;
20 let fd = unsafe { libc::eventfd(0, flags) };
24 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
2125 // Write u64 - 1, so the all subsequent write will block.
2226 let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes();
2327 let res: i64 = unsafe {
src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs+1-2
......@@ -16,8 +16,7 @@ use libc_utils::*;
1616
1717fn main() {
1818 // Create an epoll instance.
19 let epfd = unsafe { libc::epoll_create1(0) };
20 assert_ne!(epfd, -1);
19 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
2120
2221 // Create two socketpair instances.
2322 let mut fds_a = [-1, -1];
src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs+4-4
......@@ -7,6 +7,7 @@ use std::thread;
77#[path = "../../utils/libc.rs"]
88mod libc_utils;
99use libc_utils::epoll::*;
10use libc_utils::*;
1011
1112// Test if only one thread is unblocked if multiple threads blocked on same epfd.
1213// Expected execution:
......@@ -16,14 +17,13 @@ use libc_utils::epoll::*;
1617// 4. Thread 1 deadlocks.
1718fn main() {
1819 // Create an epoll instance.
19 let epfd = unsafe { libc::epoll_create1(0) };
20 assert_ne!(epfd, -1);
20 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
2121
2222 // Create an eventfd instance.
2323 let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
24 let fd1 = unsafe { libc::eventfd(0, flags) };
24 let fd1 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
2525 // Make a duplicate so that we have two file descriptors for the same file description.
26 let fd2 = unsafe { libc::dup(fd1) };
26 let fd2 = errno_result(unsafe { libc::dup(fd1) }).unwrap();
2727
2828 // Register both with epoll.
2929 epoll_ctl_add(epfd, fd1, EPOLLIN | EPOLLOUT | EPOLLET).unwrap();
src/tools/miri/tests/fail-dep/libc/libc_epoll_unsupported_fd.rs+6-4
......@@ -1,13 +1,15 @@
11//@only-target: linux android illumos
22
3#[path = "../../utils/libc.rs"]
4mod libc_utils;
5use libc_utils::*;
6
37// This is a test for registering unsupported fd with epoll.
48// Register epoll fd with epoll is allowed in real system, but we do not support this.
59fn main() {
610 // Create two epoll instance.
7 let epfd0 = unsafe { libc::epoll_create1(0) };
8 assert_ne!(epfd0, -1);
9 let epfd1 = unsafe { libc::epoll_create1(0) };
10 assert_ne!(epfd1, -1);
11 let epfd0 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
12 let epfd1 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
1113
1214 // Register epoll with epoll.
1315 let mut ev =
src/tools/miri/tests/fail-dep/libc/madvise_out_of_bounds.rs created+20
......@@ -0,0 +1,20 @@
1//@compile-flags: -Zmiri-disable-isolation
2//@ignore-target: windows # No mmap on Windows
3//@normalize-stderr-test: "only .*? bytes" -> "only SIZE bytes"
4
5fn main() {
6 unsafe {
7 let page_size = page_size::get();
8 let ptr = libc::mmap(
9 std::ptr::null_mut(),
10 page_size,
11 libc::PROT_READ | libc::PROT_WRITE,
12 libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
13 -1,
14 0,
15 );
16 assert!(!ptr.is_null());
17
18 libc::madvise(ptr, page_size + 1, libc::MADV_NORMAL); //~ ERROR: `madvise` called on out-of-bounds memory
19 }
20}
src/tools/miri/tests/fail-dep/libc/madvise_out_of_bounds.stderr created+13
......@@ -0,0 +1,13 @@
1error: Undefined Behavior: `madvise` called on out-of-bounds memory
2 --> tests/fail-dep/libc/madvise_out_of_bounds.rs:LL:CC
3 |
4LL | libc::madvise(ptr, page_size + 1, libc::MADV_NORMAL);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8 = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9
10note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
11
12error: aborting due to 1 previous error
13
src/tools/miri/tests/fail-dep/libc/mprotect_out_of_bounds.rs created+20
......@@ -0,0 +1,20 @@
1//@compile-flags: -Zmiri-disable-isolation
2//@ignore-target: windows # No mmap on Windows
3//@normalize-stderr-test: "only .*? bytes" -> "only SIZE bytes"
4
5fn main() {
6 unsafe {
7 let page_size = page_size::get();
8 let ptr = libc::mmap(
9 std::ptr::null_mut(),
10 page_size,
11 libc::PROT_READ | libc::PROT_WRITE,
12 libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
13 -1,
14 0,
15 );
16 assert!(!ptr.is_null());
17
18 libc::mprotect(ptr, page_size + 1, libc::PROT_READ | libc::PROT_WRITE); //~ ERROR: `mprotect` called on out-of-bounds memory
19 }
20}
src/tools/miri/tests/fail-dep/libc/mprotect_out_of_bounds.stderr created+13
......@@ -0,0 +1,13 @@
1error: Undefined Behavior: `mprotect` called on out-of-bounds memory
2 --> tests/fail-dep/libc/mprotect_out_of_bounds.rs:LL:CC
3 |
4LL | libc::mprotect(ptr, page_size + 1, libc::PROT_READ | libc::PROT_WRITE);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8 = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9
10note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
11
12error: aborting due to 1 previous error
13
src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs-1
......@@ -1,5 +1,4 @@
11//@ignore-target: windows # No libc socketpair on Windows
2// test_race depends on a deterministic schedule.
32//@compile-flags: -Zmiri-deterministic-concurrency
43//@error-in-other-file: deadlock
54//@require-annotations-for-level: error
src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs-1
......@@ -1,5 +1,4 @@
11//@ignore-target: windows # No libc socketpair on Windows
2// test_race depends on a deterministic schedule.
32//@compile-flags: -Zmiri-deterministic-concurrency
43//@error-in-other-file: deadlock
54//@require-annotations-for-level: error
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector1.rs created+17
......@@ -0,0 +1,17 @@
1//@revisions: stack tree
2//@[tree]compile-flags: -Zmiri-tree-borrows
3
4//@[stack]error-in-other-file: /deallocating while item \[Unique for .*\] is strongly protected/
5//@[tree]error-in-other-file: /deallocation through .* is forbidden/
6
7fn inner(x: &mut i32, f: fn(&mut i32)) {
8 // `f` may mutate, but it may not deallocate!
9 f(x)
10}
11
12fn main() {
13 inner(Box::leak(Box::new(0)), |x| {
14 let raw = x as *mut _;
15 drop(unsafe { Box::from_raw(raw) });
16 });
17}
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector1.stack.stderr created+28
......@@ -0,0 +1,28 @@
1error: Undefined Behavior: deallocating while item [Unique for <TAG>] is strongly protected
2 --> RUSTLIB/alloc/src/boxed.rs:LL:CC
3 |
4LL | self.1.deallocate(From::from(ptr.cast()), layout);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
9 = note: stack backtrace:
10 0: <std::boxed::Box<i32> as std::ops::Drop>::drop
11 at RUSTLIB/alloc/src/boxed.rs:LL:CC
12 1: std::ptr::drop_glue::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))
13 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
14 2: std::mem::drop::<std::boxed::Box<i32>>
15 at RUSTLIB/core/src/mem/mod.rs:LL:CC
16 3: main::{closure#0}
17 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
18 4: <{closure@tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim
19 at RUSTLIB/core/src/ops/function.rs:LL:CC
20 5: inner
21 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
22 6: main
23 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
24
25note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
26
27error: aborting due to 1 previous error
28
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector1.tree.stderr created+40
......@@ -0,0 +1,40 @@
1error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden
2 --> RUSTLIB/alloc/src/boxed.rs:LL:CC
3 |
4LL | self.1.deallocate(From::from(ptr.cast()), layout);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
9 = help: the allocation of the accessed tag <TAG> also contains the strongly protected tag <TAG>
10 = help: the strongly protected tag <TAG> disallows deallocations
11help: the accessed tag <TAG> was created here
12 --> tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
13 |
14LL | drop(unsafe { Box::from_raw(raw) });
15 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16help: the strongly protected tag <TAG> was created here, in the initial state Reserved
17 --> tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
18 |
19LL | inner(Box::leak(Box::new(0)), |x| {
20 | ^
21 = note: stack backtrace:
22 0: <std::boxed::Box<i32> as std::ops::Drop>::drop
23 at RUSTLIB/alloc/src/boxed.rs:LL:CC
24 1: std::ptr::drop_glue::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))
25 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
26 2: std::mem::drop::<std::boxed::Box<i32>>
27 at RUSTLIB/core/src/mem/mod.rs:LL:CC
28 3: main::{closure#0}
29 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
30 4: <{closure@tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim
31 at RUSTLIB/core/src/ops/function.rs:LL:CC
32 5: inner
33 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
34 6: main
35 at tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC
36
37note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
38
39error: aborting due to 1 previous error
40
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector2.rs created+23
......@@ -0,0 +1,23 @@
1//@revisions: stack tree
2//@[tree]compile-flags: -Zmiri-tree-borrows
3
4// Ensure that even a ZST prevents the reference from being used for deallocation.
5// The `nofree` attributes we add in LLVM IR rely on this.
6
7use std::alloc::Layout;
8
9fn inner(x: &mut (), f: fn(&mut ())) {
10 // `f` may mutate, but it may not deallocate!
11 f(x)
12}
13
14fn main() {
15 let ptr = Box::leak(Box::new(0i32)) as *mut i32;
16 inner(unsafe { &mut *(ptr as *mut ()) }, |x| unsafe {
17 let raw = x as *mut _ as *mut i32;
18 // Avoid ever creating a `Box`, we don't want any implicit accesses.
19 std::alloc::dealloc(raw.cast(), Layout::new::<i32>());
20 //~[tree]^ERROR: /deallocation through .* is forbidden/
21 //~[stack]|ERROR: tag does not exist in the borrow stack for this location
22 });
23}
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector2.stack.stderr created+27
......@@ -0,0 +1,27 @@
1error: Undefined Behavior: attempting deallocation using <TAG> at ALLOC, but that tag does not exist in the borrow stack for this location
2 --> tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
3 |
4LL | std::alloc::dealloc(raw.cast(), Layout::new::<i32>());
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
9help: <TAG> would have been created here, but this is a zero-size retag ([0x0..0x0]) so the tag in question does not exist anywhere
10 --> tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
11 |
12LL | let raw = x as *mut _ as *mut i32;
13 | ^
14 = note: stack backtrace:
15 0: main::{closure#0}
16 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
17 1: <{closure@tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC} as std::ops::FnOnce<(&mut (),)>>::call_once - shim
18 at RUSTLIB/core/src/ops/function.rs:LL:CC
19 2: inner
20 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
21 3: main
22 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
23
24note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
25
26error: aborting due to 1 previous error
27
src/tools/miri/tests/fail/both_borrows/deallocate_against_protector2.tree.stderr created+29
......@@ -0,0 +1,29 @@
1error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden
2 --> tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
3 |
4LL | std::alloc::dealloc(raw.cast(), Layout::new::<i32>());
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
9 = help: the allocation of the accessed tag <TAG> also contains the strongly protected tag <TAG>
10 = help: the strongly protected tag <TAG> disallows deallocations
11help: the strongly protected tag <TAG> was created here, in the initial state Reserved
12 --> tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
13 |
14LL | inner(unsafe { &mut *(ptr as *mut ()) }, |x| unsafe {
15 | ^
16 = note: stack backtrace:
17 0: main::{closure#0}
18 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
19 1: <{closure@tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC} as std::ops::FnOnce<(&mut (),)>>::call_once - shim
20 at RUSTLIB/core/src/ops/function.rs:LL:CC
21 2: inner
22 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
23 3: main
24 at tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC
25
26note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
27
28error: aborting due to 1 previous error
29
src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs deleted-13
......@@ -1,13 +0,0 @@
1//@error-in-other-file: /deallocating while item \[Unique for .*\] is strongly protected/
2
3fn inner(x: &mut i32, f: fn(&mut i32)) {
4 // `f` may mutate, but it may not deallocate!
5 f(x)
6}
7
8fn main() {
9 inner(Box::leak(Box::new(0)), |x| {
10 let raw = x as *mut _;
11 drop(unsafe { Box::from_raw(raw) });
12 });
13}
src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr deleted-28
......@@ -1,28 +0,0 @@
1error: Undefined Behavior: deallocating while item [Unique for <TAG>] is strongly protected
2 --> RUSTLIB/alloc/src/boxed.rs:LL:CC
3 |
4LL | self.1.deallocate(From::from(ptr.cast()), layout);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
9 = note: stack backtrace:
10 0: <std::boxed::Box<i32> as std::ops::Drop>::drop
11 at RUSTLIB/alloc/src/boxed.rs:LL:CC
12 1: std::ptr::drop_glue::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))
13 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
14 2: std::mem::drop::<std::boxed::Box<i32>>
15 at RUSTLIB/core/src/mem/mod.rs:LL:CC
16 3: main::{closure#0}
17 at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC
18 4: <{closure@tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC} as std::ops::FnOnce<(&mut i32,)>>::call_once - shim
19 at RUSTLIB/core/src/ops/function.rs:LL:CC
20 5: inner
21 at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC
22 6: main
23 at tests/fail/stacked_borrows/deallocate_against_protector1.rs:LL:CC
24
25note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
26
27error: aborting due to 1 previous error
28
src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs+7-13
......@@ -146,7 +146,7 @@ fn test_epoll_ctl_del() {
146146 events: (EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO) as u32,
147147 u64: u64::try_from(fds[1]).unwrap(),
148148 };
149 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
149 let res = unsafe { libc::epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &mut ev) };
150150 assert_eq!(res, 0);
151151
152152 // Test EPOLL_CTL_DEL.
......@@ -158,10 +158,8 @@ fn test_epoll_ctl_del() {
158158// This test is for one fd registered under two different epoll instance.
159159fn test_two_epoll_instance() {
160160 // Create two epoll instance.
161 let epfd1 = unsafe { libc::epoll_create1(0) };
162 assert_ne!(epfd1, -1);
163 let epfd2 = unsafe { libc::epoll_create1(0) };
164 assert_ne!(epfd2, -1);
161 let epfd1 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
162 let epfd2 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
165163
166164 // Create a socketpair instance.
167165 let mut fds = [-1, -1];
......@@ -570,8 +568,7 @@ fn test_epoll_ctl_epfd_equal_fd() {
570568// epfd that shouldn't receive a notification in edge-triggered mode.
571569fn test_epoll_ctl_notification() {
572570 // Create an epoll instance.
573 let epfd0 = unsafe { libc::epoll_create1(0) };
574 assert_ne!(epfd0, -1);
571 let epfd0 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
575572
576573 // Create a socketpair instance.
577574 let mut fds = [-1, -1];
......@@ -584,8 +581,7 @@ fn test_epoll_ctl_notification() {
584581 check_epoll_wait_noblock(epfd0, &[Ev { events: EPOLLOUT, data: fds[0] }]);
585582
586583 // Create another epoll instance.
587 let epfd1 = unsafe { libc::epoll_create1(0) };
588 assert_ne!(epfd1, -1);
584 let epfd1 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
589585
590586 // Register the same file description for epfd1.
591587 epoll_ctl_add(epfd1, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
......@@ -692,8 +688,7 @@ fn test_issue_3858() {
692688/// Ensure that if a socket becomes un-writable, we don't see it any more.
693689fn test_issue_4374() {
694690 // Create an epoll instance.
695 let epfd0 = unsafe { libc::epoll_create1(0) };
696 assert_ne!(epfd0, -1);
691 let epfd0 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
697692
698693 // Create a socketpair instance, make it non-blocking.
699694 let mut fds = [-1, -1];
......@@ -721,8 +716,7 @@ fn test_issue_4374() {
721716/// Same as above, but for becoming un-readable.
722717fn test_issue_4374_reads() {
723718 // Create an epoll instance.
724 let epfd0 = unsafe { libc::epoll_create1(0) };
725 assert_ne!(epfd0, -1);
719 let epfd0 = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
726720
727721 // Create a socketpair instance, make it non-blocking.
728722 let mut fds = [-1, -1];
src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs+15-10
......@@ -1,6 +1,7 @@
11//@only-target: linux android illumos
22// test_race, test_blocking_read and test_blocking_write depend on a deterministic schedule.
33//@compile-flags: -Zmiri-deterministic-concurrency
4//@run-native
45
56// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
67#![allow(static_mut_refs)]
......@@ -9,6 +10,7 @@ use std::{io, thread};
910
1011#[path = "../../utils/libc.rs"]
1112mod libc_utils;
13use libc_utils::*;
1214
1315fn main() {
1416 test_read_write();
......@@ -35,8 +37,8 @@ fn write_bytes<const N: usize>(fd: i32, data: [u8; N]) -> io::Result<usize> {
3537}
3638
3739fn test_read_write() {
38 let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
39 let fd = unsafe { libc::eventfd(0, flags) };
40 let fd =
41 errno_result(unsafe { libc::eventfd(0, libc::EFD_NONBLOCK | libc::EFD_CLOEXEC) }).unwrap();
4042 let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes();
4143 // Write 1 to the counter.
4244 let res = write_bytes(fd, sized_8_data).unwrap();
......@@ -97,9 +99,15 @@ fn test_read_write() {
9799
98100fn test_race() {
99101 static mut VAL: u8 = 0;
100 let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
101 let fd = unsafe { libc::eventfd(0, flags) };
102
103 let fd =
104 errno_result(unsafe { libc::eventfd(0, libc::EFD_NONBLOCK | libc::EFD_CLOEXEC) }).unwrap();
102105 let thread1 = thread::spawn(move || {
106 if !cfg!(miri) {
107 // Make sure the write goes first.
108 thread::sleep(std::time::Duration::from_millis(10));
109 }
110
103111 let mut buf: [u8; 8] = [0; 8];
104112 let res = read_bytes(fd, &mut buf).unwrap();
105113 // read returns number of bytes has been read, which is always 8.
......@@ -130,8 +138,7 @@ fn test_syscall() {
130138// This test will block on eventfd read then get unblocked by `write`.
131139fn test_blocking_read() {
132140 // eventfd read will block when EFD_NONBLOCK flag is clear and counter = 0.
133 let flags = libc::EFD_CLOEXEC;
134 let fd = unsafe { libc::eventfd(0, flags) };
141 let fd = errno_result(unsafe { libc::eventfd(0, libc::EFD_CLOEXEC) }).unwrap();
135142 let thread1 = thread::spawn(move || {
136143 let mut buf: [u8; 8] = [0; 8];
137144 // This will block.
......@@ -154,8 +161,7 @@ fn test_blocking_read() {
154161fn test_blocking_write() {
155162 // eventfd write will block when EFD_NONBLOCK flag is clear
156163 // and the addition caused counter to exceed u64::MAX - 1.
157 let flags = libc::EFD_CLOEXEC;
158 let fd = unsafe { libc::eventfd(0, flags) };
164 let fd = errno_result(unsafe { libc::eventfd(0, libc::EFD_CLOEXEC) }).unwrap();
159165 // Write u64 - 1, so the all subsequent write will block.
160166 let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes();
161167 let res: i64 = unsafe {
......@@ -192,8 +198,7 @@ fn test_blocking_write() {
192198fn test_two_threads_blocked_on_eventfd() {
193199 // eventfd write will block when EFD_NONBLOCK flag is clear
194200 // and the addition caused counter to exceed u64::MAX - 1.
195 let flags = libc::EFD_CLOEXEC;
196 let fd = unsafe { libc::eventfd(0, flags) };
201 let fd = errno_result(unsafe { libc::eventfd(0, libc::EFD_CLOEXEC) }).unwrap();
197202 // Write u64 - 1, so the all subsequent write will block.
198203 let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes();
199204 let res: i64 = unsafe {
src/tools/miri/tests/pass-dep/libc/libc-fs.rs+5-4
......@@ -272,7 +272,7 @@ fn test_dup() {
272272 let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap();
273273
274274 unsafe {
275 let fd = libc::open(name.as_ptr(), libc::O_RDONLY);
275 let fd = errno_result(libc::open(name.as_ptr(), libc::O_RDONLY)).unwrap();
276276 let new_fd = libc::dup(fd);
277277 let new_fd2 = libc::dup2(fd, 8);
278278
......@@ -856,8 +856,8 @@ fn test_readdir() {
856856 assert!(!dirp.is_null());
857857 let mut entries = Vec::new();
858858 loop {
859 cfg_if::cfg_if! {
860 if #[cfg(target_os = "macos")] {
859 cfg_select! {
860 target_os = "macos" => {
861861 // On macos we only support readdir_r as that's what std uses there.
862862 use std::mem::MaybeUninit;
863863 use libc::dirent;
......@@ -866,7 +866,8 @@ fn test_readdir() {
866866 let ret = libc::readdir_r(dirp, entry.as_mut_ptr(), &mut result);
867867 assert_eq!(ret, 0);
868868 let entry_ptr = result;
869 } else {
869 }
870 _ => {
870871 let entry_ptr = libc::readdir(dirp);
871872 }
872873 }
src/tools/miri/tests/pass-dep/libc/libc-pipe.rs+2-1
......@@ -1,6 +1,7 @@
11//@ignore-target: windows # No libc pipe on Windows
22// test_race depends on a deterministic schedule.
33//@compile-flags: -Zmiri-deterministic-concurrency
4//@run-native
45use std::thread;
56
67#[path = "../../utils/libc.rs"]
......@@ -39,7 +40,7 @@ fn test_pipe() {
3940 let data = b"123";
4041 write_all(fds[1], data).unwrap();
4142 let mut buf4: [u8; 5] = [0; 5];
42 let (part1, rest) = read_split_slice(fds[0], &mut buf4).unwrap();
43 let (part1, rest) = read_partial(fds[0], &mut buf4).unwrap();
4344 assert_eq!(part1[..], data[..part1.len()]);
4445 // Write 2 more bytes so we can exactly fill the `rest`.
4546 write_all(fds[1], b"34").unwrap();
src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs+156-14
......@@ -28,6 +28,8 @@ fn main() {
2828 test_readiness_after_short_read();
2929 test_readiness_after_short_peek();
3030 test_readiness_after_short_write();
31 test_readable_after_read_shutdown_and_short_read();
32 test_writable_after_write_shutdown_with_full_buffer();
3133}
3234
3335/// Test that connecting to a server socket works when the client
......@@ -359,7 +361,7 @@ fn test_shutdown_read_write() {
359361 let (server_sockfd, addr) = net::make_listener_ipv4().unwrap();
360362 let client_sockfd =
361363 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
362 let epfd = unsafe { libc::epoll_create1(0) };
364 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
363365
364366 // Spawn the server thread.
365367 let server_thread = thread::spawn(move || net::accept_ipv4(server_sockfd).unwrap());
......@@ -387,7 +389,7 @@ fn test_shutdown_read() {
387389 let (server_sockfd, addr) = net::make_listener_ipv4().unwrap();
388390 let client_sockfd =
389391 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
390 let epfd = unsafe { libc::epoll_create1(0) };
392 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
391393
392394 // Spawn the server thread.
393395 let server_thread = thread::spawn(move || net::accept_ipv4(server_sockfd).unwrap());
......@@ -411,7 +413,7 @@ fn test_shutdown_write() {
411413 let (server_sockfd, addr) = net::make_listener_ipv4().unwrap();
412414 let client_sockfd =
413415 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
414 let epfd = unsafe { libc::epoll_create1(0) };
416 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
415417
416418 // Spawn the server thread.
417419 let server_thread = thread::spawn(move || {
......@@ -562,24 +564,14 @@ fn test_readiness_after_short_write() {
562564 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
563565 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
564566
565 // Spawn the server thread.
566 let server_thread = thread::spawn(move || {
567 let (peerfd, _) = net::accept_ipv4(server_sockfd).unwrap();
568 // Return the peer socket file descriptor such that we can use
569 // it after joining the server thread.
570 peerfd
571 });
572
573567 net::connect_ipv4(client_sockfd, addr).unwrap();
568 let (peerfd, _) = net::accept_ipv4(server_sockfd).unwrap();
574569
575570 unsafe {
576571 // Change client socket to be non-blocking.
577572 errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK));
578573 }
579574
580 // The peer socket is a blocking socket.
581 let peerfd = server_thread.join().unwrap();
582
583575 // Add client socket with writable interest to epoll.
584576 epoll_ctl_add(epfd, client_sockfd, EPOLLET | EPOLLOUT).unwrap();
585577
......@@ -636,3 +628,153 @@ fn test_readiness_after_short_write() {
636628 // We should again be able to write into the socket.
637629 libc_utils::write_all(client_sockfd, &buffer).unwrap();
638630}
631
632/// Test that Miri correctly keeps the readable readiness when the read end of the client
633/// socket has been closed -- even after a short read.
634fn test_readable_after_read_shutdown_and_short_read() {
635 let (server_sockfd, addr) = net::make_listener_ipv4().unwrap();
636 let client_sockfd =
637 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
638 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
639
640 // Spawn the server thread.
641 let server_thread = thread::spawn(move || {
642 let (peerfd, _) = net::accept_ipv4(server_sockfd).unwrap();
643
644 // Write `TEST_BYTES` into the stream.
645 libc_utils::write_all(peerfd, TEST_BYTES).unwrap();
646
647 // Close the write end, so that the reader will get an EOF.
648 // (We could alternatively test this by closing the read end of the client socket,
649 // but Windows has some special behavior when closing a read end while there's still
650 // data coming in, so we avoid that.)
651 unsafe { errno_check(libc::shutdown(peerfd, libc::SHUT_WR)) };
652 });
653
654 net::connect_ipv4(client_sockfd, addr).unwrap();
655
656 // Change client socket to be non-blocking.
657 unsafe { errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK)) };
658
659 server_thread.join().unwrap();
660
661 // Add client socket with "read closed" and "readable" interest to epoll.
662 epoll_ctl_add(epfd, client_sockfd, EPOLLET | EPOLLIN | EPOLLRDHUP).unwrap();
663
664 // Ensure that the socket is readable and that its read end is closed.
665 check_epoll_wait(epfd, &[Ev { events: EPOLLIN | EPOLLRDHUP, data: client_sockfd }], -1);
666
667 let mut buffer = [0u8; 1024];
668
669 // We want to read in chunks of 16 bytes. To ensure we get a short read, `TEST_BYTES.len()`
670 // must not be dividable by 16.
671 assert!(TEST_BYTES.len() % 16 != 0);
672
673 let mut total_bytes_read = 0;
674 // Read everything from the socket until we get a short read.
675 // We don't want to provide `TEST_BYTES.len()` as `count` because then we won't trigger
676 // a short read.
677 loop {
678 let bytes_read = unsafe {
679 errno_result(libc::read(
680 client_sockfd,
681 buffer.as_mut_ptr().byte_add(total_bytes_read).cast(),
682 // Read a chunk of 16 bytes.
683 16,
684 ))
685 .unwrap()
686 };
687
688 total_bytes_read += bytes_read as usize;
689 if bytes_read < 16 {
690 // We had a short read; we thus assume the read buffer is empty.
691 break;
692 }
693 }
694 assert_eq!(total_bytes_read, TEST_BYTES.len());
695
696 // We had a short read because `buffer` is bigger than `TEST_BYTES`.
697 // Because the read end of the socket is closed, we should still be able to
698 // read to detect EOFs.
699
700 // Ensure that the "readable" and "read closed" readiness flags are still set.
701 assert_eq!(
702 current_epoll_readiness::<8>(client_sockfd, EPOLLIN | EPOLLET | EPOLLRDHUP),
703 EPOLLIN | EPOLLRDHUP
704 );
705
706 // A read should not block and return 0, indicating EOF.
707 let mut buffer = [1u8; 16];
708 let bytes_read = unsafe {
709 errno_result(libc::read(client_sockfd, buffer.as_mut_ptr().cast(), buffer.len())).unwrap()
710 };
711 assert_eq!(bytes_read, 0);
712}
713
714/// Test that the writable readiness gets set when the write end of a socket
715/// is closed -- even when the socket write buffer is full.
716fn test_writable_after_write_shutdown_with_full_buffer() {
717 let (server_sockfd, addr) = net::make_listener_ipv4().unwrap();
718 let client_sockfd =
719 unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };
720 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
721
722 net::connect_ipv4(client_sockfd, addr).unwrap();
723 net::accept_ipv4(server_sockfd).unwrap();
724
725 unsafe {
726 // Change client socket to be non-blocking.
727 errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK));
728 }
729
730 // Add client socket with level-triggered "writable" and "write closed" interest to epoll.
731 epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLHUP).unwrap();
732
733 // Wait until the socket becomes writable.
734 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
735
736 // We now want to fill the write buffer of the socket by repeatedly writing
737 // `buffer` into it. The last write should then be a short write.
738 // We assume/hope that the write buffer length is not divisible by 1039.
739 let buffer = [123u8; 1039];
740
741 loop {
742 let result = unsafe {
743 errno_result(libc::write(client_sockfd, buffer.as_ptr().cast(), buffer.len()))
744 };
745
746 match result {
747 Ok(bytes_written) => {
748 if (bytes_written as usize) < buffer.len() {
749 // We had a short write; we thus assume the write buffer is full.
750 break;
751 }
752 }
753 Err(err) if err.kind() == ErrorKind::WouldBlock => {
754 // Windows and Apple hosts behave weirdly when attempting to fill up the write buffer.
755 // Instead of doing a short write to completely fill the buffer, they can return an
756 // EWOULDBLOCK when the next write wouldn't fit into the buffer.
757 // When we get such an error, we also assume the write buffer is full.
758 break;
759 }
760 Err(err) => panic!("unexpected error whilst filling up buffer: {err}"),
761 }
762 }
763
764 // The write buffer is full; because this is a level-triggered interest,
765 // a readiness of 0 means that the socket would now block on writes.
766 check_epoll_wait(epfd, &[], 0);
767
768 // Close the socket write end.
769 unsafe {
770 errno_check(libc::shutdown(client_sockfd, libc::SHUT_WR));
771 }
772
773 // The socket should no longer block on writes after its write end is closed.
774 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
775
776 // A write should not block and return an error.
777 let result =
778 unsafe { errno_result(libc::write(client_sockfd, buffer.as_ptr().cast(), buffer.len())) };
779 assert_eq!(result.unwrap_err().kind(), ErrorKind::BrokenPipe);
780}
src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs+10-4
......@@ -1,6 +1,7 @@
11//@ignore-target: windows # No libc socketpair on Windows
22// test_race depends on a deterministic schedule.
33//@compile-flags: -Zmiri-deterministic-concurrency
4//@run-native
45
56// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
67#![allow(static_mut_refs)]
......@@ -34,7 +35,7 @@ fn test_socketpair() {
3435 let data = b"abc";
3536 write_all(fds[0], data).unwrap();
3637 let mut buf2: [u8; 5] = [0; 5];
37 let (read, rest) = read_split_slice(fds[1], &mut buf2).unwrap();
38 let (read, rest) = read_partial(fds[1], &mut buf2).unwrap();
3839 assert_eq!(read[..], data[..read.len()]);
3940 // Write 2 more bytes so we can exactly fill the `rest`.
4041 write_all(fds[0], b"12").unwrap();
......@@ -52,7 +53,7 @@ fn test_socketpair() {
5253 let data = b"abc";
5354 write_all(fds[1], data).unwrap();
5455 let mut buf4: [u8; 5] = [0; 5];
55 let (read, rest) = read_split_slice(fds[0], &mut buf4).unwrap();
56 let (read, rest) = read_partial(fds[0], &mut buf4).unwrap();
5657 assert_eq!(read[..], data[..read.len()]);
5758 // Write 2 more bytes so we can exactly fill the `rest`.
5859 write_all(fds[1], b"12").unwrap();
......@@ -64,9 +65,9 @@ fn test_socketpair() {
6465 errno_check(unsafe { libc::close(fds[0]) });
6566 // Reading the other end should return that data, then EOF.
6667 let mut buf: [u8; 5] = [0; 5];
67 let (read, _tail) = read_split_slice(fds[1], &mut buf).unwrap();
68 let (read, _tail) = read_partial(fds[1], &mut buf).unwrap();
6869 assert_eq!(read, data);
69 let (read, _tail) = read_split_slice(fds[1], &mut buf).unwrap();
70 let (read, _tail) = read_partial(fds[1], &mut buf).unwrap();
7071 assert_eq!(read, &[]);
7172 // Writing the other end should emit EPIPE.
7273 let err = write_all(fds[1], &mut buf).unwrap_err();
......@@ -132,6 +133,11 @@ fn test_blocking_read() {
132133
133134// Test the behaviour of a socketpair getting blocked on write and subsequently unblocked.
134135fn test_blocking_write() {
136 // The test uses Miri's exact buffer size.
137 if !cfg!(miri) {
138 return;
139 }
140
135141 let mut fds = [-1, -1];
136142 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
137143 let arr1: [u8; 0x34000] = [1; 0x34000];
src/tools/miri/tests/pass-dep/libc/libc-time.rs+67-37
......@@ -1,5 +1,6 @@
11//@ignore-target: windows # no libc time APIs on Windows
22//@compile-flags: -Zmiri-disable-isolation
3//@run-native
34
45#[path = "../../utils/libc.rs"]
56mod libc_utils;
......@@ -9,6 +10,17 @@ use std::{env, mem, ptr};
910
1011use libc_utils::errno_check;
1112
13fn set_tz(name: &str) {
14 extern "C" {
15 fn tzset();
16 }
17
18 env::set_var("TZ", name);
19 if !cfg!(miri) {
20 unsafe { tzset() }; // re-read TZ env var (natively, it may be cached)
21 }
22}
23
1224fn main() {
1325 test_clocks();
1426 test_posix_gettimeofday();
......@@ -66,11 +78,13 @@ fn test_posix_gettimeofday() {
6678 assert!(tv.tv_sec > 0);
6779 assert!(tv.tv_usec >= 0); // Theoretically this could be 0.
6880
69 // Test that non-null tz returns an error (because we don't support it).
70 let mut tz = mem::MaybeUninit::<libc::timezone>::uninit();
71 let tz_ptr = tz.as_mut_ptr();
72 let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz_ptr.cast()) };
73 assert_eq!(is_error, -1);
81 if cfg!(miri) {
82 // Test that non-null tz returns an error (because we don't support it).
83 let mut tz = mem::MaybeUninit::<libc::timezone>::uninit();
84 let tz_ptr = tz.as_mut_ptr();
85 let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz_ptr.cast()) };
86 assert_eq!(is_error, -1);
87 }
7488}
7589
7690/// Helper function to create an empty tm struct.
......@@ -104,9 +118,8 @@ fn create_empty_tm() -> libc::tm {
104118
105119/// Original GMT test
106120fn test_localtime_r_gmt() {
107 // Set timezone to GMT.
108 let key = "TZ";
109 env::set_var(key, "GMT");
121 set_tz("GMT");
122
110123 const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT
111124 let custom_time_ptr = &TIME_SINCE_EPOCH;
112125 let mut tm = create_empty_tm();
......@@ -120,7 +133,9 @@ fn test_localtime_r_gmt() {
120133 assert_eq!(tm.tm_year, 124);
121134 assert_eq!(tm.tm_wday, 0);
122135 assert_eq!(tm.tm_yday, 97);
123 assert_eq!(tm.tm_isdst, -1);
136 if cfg!(miri) {
137 assert_eq!(tm.tm_isdst, -1);
138 }
124139 #[cfg(any(
125140 target_os = "linux",
126141 target_os = "macos",
......@@ -130,21 +145,21 @@ fn test_localtime_r_gmt() {
130145 {
131146 assert_eq!(tm.tm_gmtoff, 0);
132147 unsafe {
133 assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00");
148 assert_eq!(
149 std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(),
150 if cfg!(miri) { "+00" } else { "GMT" }
151 );
134152 }
135153 }
136154
137155 // The returned value is the pointer passed in.
138156 assert!(ptr::eq(res, &mut tm));
139
140 // Remove timezone setting.
141 env::remove_var(key);
142157}
143158
144159/// PST timezone test (testing different timezone handling).
145160fn test_localtime_r_pst() {
146 let key = "TZ";
147 env::set_var(key, "PST8PDT");
161 set_tz("PST8PDT");
162
148163 const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT
149164 let custom_time_ptr = &TIME_SINCE_EPOCH;
150165 let mut tm = create_empty_tm();
......@@ -159,7 +174,9 @@ fn test_localtime_r_pst() {
159174 assert_eq!(tm.tm_year, 124);
160175 assert_eq!(tm.tm_wday, 0);
161176 assert_eq!(tm.tm_yday, 97);
162 assert_eq!(tm.tm_isdst, -1); // DST information unavailable
177 if cfg!(miri) {
178 assert_eq!(tm.tm_isdst, -1); // DST information unavailable
179 }
163180
164181 #[cfg(any(
165182 target_os = "linux",
......@@ -170,18 +187,20 @@ fn test_localtime_r_pst() {
170187 {
171188 assert_eq!(tm.tm_gmtoff, -7 * 3600); // -7 hours in seconds
172189 unsafe {
173 assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "-07");
190 assert_eq!(
191 std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(),
192 if cfg!(miri) { "-07" } else { "PDT" }
193 );
174194 }
175195 }
176196
177197 assert!(ptr::eq(res, &mut tm));
178 env::remove_var(key);
179198}
180199
181200/// Unix epoch test (edge case testing).
182201fn test_localtime_r_epoch() {
183 let key = "TZ";
184 env::set_var(key, "GMT");
202 set_tz("GMT");
203
185204 const TIME_SINCE_EPOCH: libc::time_t = 0; // 1970-01-01 00:00:00
186205 let custom_time_ptr = &TIME_SINCE_EPOCH;
187206 let mut tm = create_empty_tm();
......@@ -196,7 +215,9 @@ fn test_localtime_r_epoch() {
196215 assert_eq!(tm.tm_year, 70);
197216 assert_eq!(tm.tm_wday, 4); // Thursday
198217 assert_eq!(tm.tm_yday, 0);
199 assert_eq!(tm.tm_isdst, -1);
218 if cfg!(miri) {
219 assert_eq!(tm.tm_isdst, -1);
220 }
200221
201222 #[cfg(any(
202223 target_os = "linux",
......@@ -207,19 +228,20 @@ fn test_localtime_r_epoch() {
207228 {
208229 assert_eq!(tm.tm_gmtoff, 0);
209230 unsafe {
210 assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00");
231 assert_eq!(
232 std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(),
233 if cfg!(miri) { "+00" } else { "GMT" }
234 );
211235 }
212236 }
213237
214238 assert!(ptr::eq(res, &mut tm));
215 env::remove_var(key);
216239}
217240
218241/// Future date test (testing large values).
219242#[cfg(target_pointer_width = "64")]
220243fn test_localtime_r_future_64b() {
221 let key = "TZ";
222 env::set_var(key, "GMT");
244 set_tz("GMT");
223245
224246 // Using 2050-01-01 00:00:00 for 64-bit systems
225247 // value that's safe for 64-bit time_t
......@@ -237,7 +259,9 @@ fn test_localtime_r_future_64b() {
237259 assert_eq!(tm.tm_year, 150); // 2050 - 1900
238260 assert_eq!(tm.tm_wday, 6); // Saturday
239261 assert_eq!(tm.tm_yday, 0);
240 assert_eq!(tm.tm_isdst, -1);
262 if cfg!(miri) {
263 assert_eq!(tm.tm_isdst, -1);
264 }
241265
242266 #[cfg(any(
243267 target_os = "linux",
......@@ -248,19 +272,20 @@ fn test_localtime_r_future_64b() {
248272 {
249273 assert_eq!(tm.tm_gmtoff, 0);
250274 unsafe {
251 assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00");
275 assert_eq!(
276 std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(),
277 if cfg!(miri) { "+00" } else { "GMT" }
278 );
252279 }
253280 }
254281
255282 assert!(ptr::eq(res, &mut tm));
256 env::remove_var(key);
257283}
258284
259285/// Future date test (testing large values for 32b target).
260286#[cfg(target_pointer_width = "32")]
261287fn test_localtime_r_future_32b() {
262 let key = "TZ";
263 env::set_var(key, "GMT");
288 set_tz("GMT");
264289
265290 // Using 2030-01-01 00:00:00 for 32-bit systems
266291 // Safe value within i32 range
......@@ -279,7 +304,9 @@ fn test_localtime_r_future_32b() {
279304 assert_eq!(tm.tm_year, 130); // 2030 - 1900
280305 assert_eq!(tm.tm_wday, 2); // Tuesday
281306 assert_eq!(tm.tm_yday, 0);
282 assert_eq!(tm.tm_isdst, -1);
307 if cfg!(miri) {
308 assert_eq!(tm.tm_isdst, -1);
309 }
283310
284311 #[cfg(any(
285312 target_os = "linux",
......@@ -290,19 +317,20 @@ fn test_localtime_r_future_32b() {
290317 {
291318 assert_eq!(tm.tm_gmtoff, 0);
292319 unsafe {
293 assert_eq!(std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00");
320 assert_eq!(
321 std::ffi::CStr::from_ptr(tm.tm_zone).to_str().unwrap(),
322 if cfg!(miri) { "+00" } else { "GMT" }
323 );
294324 }
295325 }
296326
297327 assert!(ptr::eq(res, &mut tm));
298 env::remove_var(key);
299328}
300329
301330/// Tests the behavior of `localtime_r` with multiple calls to ensure deduplication of `tm_zone` pointers.
302331#[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android"))]
303332fn test_localtime_r_multiple_calls_deduplication() {
304 let key = "TZ";
305 env::set_var(key, "PST8PDT");
333 set_tz("PST8PDT");
306334
307335 const TIME_SINCE_EPOCH_BASE: libc::time_t = 1712475836; // Base timestamp: 2024-04-07 07:43:56 GMT
308336 const NUM_CALLS: usize = 50;
......@@ -321,9 +349,11 @@ fn test_localtime_r_multiple_calls_deduplication() {
321349
322350 let unique_count = unique_pointers.len();
323351
352 // Miri non-determinisitcally de-duplicates. Native always deduplicates.
353 let min = if cfg!(miri) { 2 } else { 1 };
324354 assert!(
325 unique_count >= 2 && unique_count <= (NUM_CALLS - 1),
326 "Unexpected number of unique tm_zone pointers: {} (expected between 2 and {})",
355 unique_count >= min && unique_count <= (NUM_CALLS - 1),
356 "Unexpected number of unique tm_zone pointers: {} (expected between {min} and {})",
327357 unique_count,
328358 NUM_CALLS - 1
329359 );
src/tools/miri/tests/pass-dep/libc/mmap.rs+74
......@@ -94,6 +94,78 @@ fn test_mmap<Offset: Default>(
9494 assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
9595}
9696
97fn test_mprotect() {
98 let page_size = page_size::get();
99 let ptr = unsafe {
100 libc::mmap(
101 ptr::null_mut(),
102 4 * page_size,
103 libc::PROT_READ | libc::PROT_WRITE,
104 libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
105 -1,
106 Default::default(),
107 )
108 };
109 assert!(!ptr.is_null());
110
111 // Protect part of it redundantly.
112 let res = unsafe {
113 libc::mprotect(ptr.byte_add(2 * page_size), 42, libc::PROT_READ | libc::PROT_WRITE)
114 };
115 assert_eq!(res, 0i32);
116
117 // Protect everything redundantly.
118 let res = unsafe { libc::mprotect(ptr, 4 * page_size, libc::PROT_READ | libc::PROT_WRITE) };
119 assert_eq!(res, 0i32);
120
121 // We report an error when the address is not a multiple of the page size.
122 let res =
123 unsafe { libc::mprotect(ptr.byte_add(11), page_size, libc::PROT_READ | libc::PROT_WRITE) };
124 assert_eq!(res, -1);
125 assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
126
127 // We report an error if the length cannot be rounded up to a multiple of the page size.
128 let res = unsafe { libc::mprotect(ptr, usize::MAX - 1, libc::PROT_READ | libc::PROT_WRITE) };
129 assert_eq!(res, -1);
130 assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOMEM);
131}
132
133fn test_madvise() {
134 let page_size = page_size::get();
135 let ptr = unsafe {
136 libc::mmap(
137 ptr::null_mut(),
138 4 * page_size,
139 libc::PROT_READ | libc::PROT_WRITE,
140 libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
141 -1,
142 Default::default(),
143 )
144 };
145 assert!(!ptr.is_null());
146
147 for advice in [libc::MADV_NORMAL, libc::MADV_RANDOM, libc::MADV_SEQUENTIAL, libc::MADV_WILLNEED]
148 {
149 // Advise part of it redundantly.
150 let res = unsafe { libc::madvise(ptr.byte_add(2 * page_size), 42, advice) };
151 assert_eq!(res, 0i32);
152
153 // Protect everything redundantly.
154 let res = unsafe { libc::madvise(ptr, 4 * page_size, advice) };
155 assert_eq!(res, 0i32);
156 }
157
158 // We report an error when the address is not a multiple of the page size.
159 let res = unsafe { libc::madvise(ptr.byte_add(11), page_size, libc::MADV_NORMAL) };
160 assert_eq!(res, -1);
161 assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
162
163 // We report an error if the length cannot be rounded up to a multiple of the page size.
164 let res = unsafe { libc::madvise(ptr, usize::MAX - 1, libc::MADV_NORMAL) };
165 assert_eq!(res, -1);
166 assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOMEM);
167}
168
97169#[cfg(target_os = "linux")]
98170fn test_mremap() {
99171 let page_size = page_size::get();
......@@ -145,6 +217,8 @@ fn main() {
145217 test_mmap(libc::mmap);
146218 #[cfg(target_os = "linux")]
147219 test_mmap(libc::mmap64);
220 test_mprotect();
221 test_madvise();
148222 #[cfg(target_os = "linux")]
149223 test_mremap();
150224}
src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs+49-35
......@@ -4,17 +4,21 @@ use std::ffi::{CStr, CString};
44use std::thread;
55
66const MAX_THREAD_NAME_LEN: usize = {
7 cfg_if::cfg_if! {
8 if #[cfg(any(target_os = "linux"))] {
7 cfg_select! {
8 target_os = "linux" => {
99 16
10 } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
10 }
11 any(target_os = "illumos", target_os = "solaris") => {
1112 32
12 } else if #[cfg(target_os = "macos")] {
13 }
14 target_os = "macos" => {
1315 libc::MAXTHREADNAMESIZE // 64, at the time of writing
14 } else if #[cfg(target_os = "freebsd")] {
16 }
17 target_os = "freebsd" => {
1518 usize::MAX // as far as I can tell
16 } else {
17 panic!()
19 }
20 _ => {
21 compile_error!("unsupported OS");
1822 }
1923 }
2024};
......@@ -28,35 +32,38 @@ fn main() {
2832 .collect::<String>();
2933
3034 fn set_thread_name(name: &CStr) -> i32 {
31 cfg_if::cfg_if! {
32 if #[cfg(any(
35 cfg_select! {
36 any(
3337 target_os = "linux",
3438 target_os = "freebsd",
3539 target_os = "illumos",
3640 target_os = "solaris"
37 ))] {
41 ) => {
3842 unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }
39 } else if #[cfg(target_os = "macos")] {
43 }
44 target_os = "macos" => {
4045 unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }
41 } else {
46 }
47 _ => {
4248 compile_error!("set_thread_name not supported for this OS")
4349 }
4450 }
4551 }
4652
4753 fn get_thread_name(name: &mut [u8]) -> i32 {
48 cfg_if::cfg_if! {
49 if #[cfg(any(
54 cfg_select! {
55 any(
5056 target_os = "linux",
5157 target_os = "freebsd",
5258 target_os = "illumos",
5359 target_os = "solaris",
5460 target_os = "macos"
55 ))] {
61 ) => {
5662 unsafe {
5763 libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
5864 }
59 } else {
65 }
66 _ => {
6067 compile_error!("get_thread_name not supported for this OS")
6168 }
6269 }
......@@ -95,13 +102,14 @@ fn main() {
95102
96103 // Test what happens when the buffer is shorter than 16, but still long enough.
97104 let res = get_thread_name(&mut buf[..15]);
98 cfg_if::cfg_if! {
99 if #[cfg(target_os = "linux")] {
105 cfg_select! {
106 target_os = "linux" => {
100107 // For glibc used by linux-gnu there should be a failue,
101108 // if a shorter than 16 bytes buffer is provided, even if that would be
102109 // large enough for the thread name.
103110 assert_eq!(res, libc::ERANGE);
104 } else {
111 }
112 _ => {
105113 // Everywhere else, this should work.
106114 assert_eq!(res, 0);
107115 // POSIX seems to promise at least 15 chars excluding a null terminator.
......@@ -112,15 +120,16 @@ fn main() {
112120
113121 // Test what happens when the buffer is too short even for the short name.
114122 let res = get_thread_name(&mut buf[..4]);
115 cfg_if::cfg_if! {
116 if #[cfg(any(target_os = "freebsd", target_os = "macos"))] {
123 cfg_select! {
124 any(target_os = "freebsd", target_os = "macos") => {
117125 // On macOS and FreeBSD it's not an error for the buffer to be
118126 // too short for the thread name -- they truncate instead.
119127 assert_eq!(res, 0);
120128 let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
121129 assert_eq!(cstr.to_bytes_with_nul().len(), 4);
122130 assert!(short_name.as_bytes().starts_with(cstr.to_bytes()));
123 } else {
131 }
132 _ => {
124133 // The rest should give an error.
125134 assert_eq!(res, libc::ERANGE);
126135 }
......@@ -128,12 +137,13 @@ fn main() {
128137
129138 // Test zero-sized buffer.
130139 let res = get_thread_name(&mut []);
131 cfg_if::cfg_if! {
132 if #[cfg(any(target_os = "freebsd", target_os = "macos"))] {
140 cfg_select! {
141 any(target_os = "freebsd", target_os = "macos") => {
133142 // On macOS and FreeBSD it's not an error for the buffer to be
134143 // too short for the thread name -- even with size 0.
135144 assert_eq!(res, 0);
136 } else {
145 }
146 _ => {
137147 // The rest should give an error.
138148 assert_eq!(res, libc::ERANGE);
139149 }
......@@ -149,16 +159,18 @@ fn main() {
149159 // Set full thread name.
150160 let cstr = CString::new(long_name.clone()).unwrap();
151161 let res = set_thread_name(&cstr);
152 cfg_if::cfg_if! {
153 if #[cfg(target_os = "freebsd")] {
162 cfg_select! {
163 target_os = "freebsd" => {
154164 // Names of all size are supported.
155165 assert!(cstr.to_bytes_with_nul().len() <= MAX_THREAD_NAME_LEN);
156166 assert_eq!(res, 0);
157 } else if #[cfg(target_os = "macos")] {
167 }
168 target_os = "macos" => {
158169 // Name is too long.
159170 assert!(cstr.to_bytes_with_nul().len() > MAX_THREAD_NAME_LEN);
160171 assert_eq!(res, libc::ENAMETOOLONG);
161 } else {
172 }
173 _ => {
162174 // Name is too long.
163175 assert!(cstr.to_bytes_with_nul().len() > MAX_THREAD_NAME_LEN);
164176 assert_eq!(res, libc::ERANGE);
......@@ -179,14 +191,15 @@ fn main() {
179191
180192 // Test what happens when our buffer is just one byte too small.
181193 let res = get_thread_name(&mut buf[..truncated_name.len()]);
182 cfg_if::cfg_if! {
183 if #[cfg(any(target_os = "freebsd", target_os = "macos"))] {
194 cfg_select! {
195 any(target_os = "freebsd", target_os = "macos") => {
184196 // On macOS and FreeBSD it's not an error for the buffer to be
185197 // too short for the thread name -- they truncate instead.
186198 assert_eq!(res, 0);
187199 let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
188200 assert_eq!(cstr.to_bytes(), &truncated_name.as_bytes()[..(truncated_name.len() - 1)]);
189 } else {
201 }
202 _ => {
190203 // The rest should give an error.
191204 assert_eq!(res, libc::ERANGE);
192205 }
......@@ -199,10 +212,11 @@ fn main() {
199212 // Now set the name for a non-existing thread and verify error codes.
200213 let invalid_thread = 0xdeadbeef;
201214 let error = {
202 cfg_if::cfg_if! {
203 if #[cfg(target_os = "linux")] {
215 cfg_select! {
216 target_os = "linux" => {
204217 libc::ENOENT
205 } else {
218 }
219 _ => {
206220 libc::ESRCH
207221 }
208222 }
src/tools/miri/tests/pass-dep/shims/gettid.rs+18-10
......@@ -5,29 +5,37 @@
55#![feature(linkage)]
66
77fn gettid() -> u64 {
8 cfg_if::cfg_if! {
9 if #[cfg(any(target_os = "android", target_os = "linux"))] {
8 cfg_select! {
9 any(target_os = "android", target_os = "linux") => {
1010 gettid_linux_like()
11 } else if #[cfg(target_os = "nto")] {
11 }
12 target_os = "nto" => {
1213 unsafe { libc::gettid() as u64 }
13 } else if #[cfg(target_os = "openbsd")] {
14 }
15 target_os = "openbsd" => {
1416 unsafe { libc::getthrid() as u64 }
15 } else if #[cfg(target_os = "freebsd")] {
17 }
18 target_os = "freebsd" => {
1619 unsafe { libc::pthread_getthreadid_np() as u64 }
17 } else if #[cfg(target_os = "netbsd")] {
20 }
21 target_os = "netbsd" => {
1822 unsafe { libc::_lwp_self() as u64 }
19 } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
23 }
24 any(target_os = "solaris", target_os = "illumos") => {
2025 // On Solaris and Illumos, the `pthread_t` is the OS TID.
2126 unsafe { libc::pthread_self() as u64 }
22 } else if #[cfg(target_vendor = "apple")] {
27 }
28 target_vendor = "apple" => {
2329 let mut id = 0u64;
2430 let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) };
2531 assert_eq!(status, 0);
2632 id
27 } else if #[cfg(windows)] {
33 }
34 windows => {
2835 use windows_sys::Win32::System::Threading::GetCurrentThreadId;
2936 unsafe { GetCurrentThreadId() as u64 }
30 } else {
37 }
38 _ => {
3139 compile_error!("platform has no gettid")
3240 }
3341 }
src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.rs created+9
......@@ -0,0 +1,9 @@
1fn main() {
2 foo(1234);
3}
4
5#[allow(no_mangle_generic_items)]
6#[unsafe(no_mangle)]
7fn foo<T: std::fmt::Debug>(value: T) {
8 println!("{value:?}");
9}
src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.stdout created+1
......@@ -0,0 +1 @@
11234
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-aes.rs+1
......@@ -1,6 +1,7 @@
11// We're testing aarch64 AES target specific features.
22//@only-target: aarch64
33//@compile-flags: -C target-feature=+neon,+aes
4//@run-native
45
56use std::arch::aarch64::*;
67use std::arch::is_aarch64_feature_detected;
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-crc32.rs+1
......@@ -1,6 +1,7 @@
11// We're testing aarch64 CRC32 target specific features
22//@only-target: aarch64
33//@compile-flags: -C target-feature=+crc
4//@run-native
45
56use std::arch::aarch64::*;
67use std::arch::is_aarch64_feature_detected;
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs+50
......@@ -1,6 +1,7 @@
11// We're testing aarch64 target specific features
22//@only-target: aarch64
33//@compile-flags: -C target-feature=+neon
4//@run-native
45
56use std::arch::aarch64::*;
67use std::arch::is_aarch64_feature_detected;
......@@ -14,6 +15,7 @@ fn main() {
1415 test_tbl1_v16i8_basic();
1516 test_vpadd();
1617 test_vpaddl();
18 test_vqdmulh();
1719 }
1820}
1921
......@@ -157,3 +159,51 @@ unsafe fn test_vpaddl() {
157159 vst1q_u64(r.as_mut_ptr(), vpaddlq_u32(a));
158160 assert_eq!(r, e);
159161}
162
163#[target_feature(enable = "neon")]
164unsafe fn test_vqdmulh() {
165 let a = vld1_s32([i32::MIN, i32::MAX].as_ptr());
166 let r: [i32; 2] = transmute(vqdmulh_n_s32(a, i32::MIN));
167 assert_eq!(r, [i32::MAX, -i32::MAX]);
168
169 // This is the actual calculation that happens.
170 let product = i32::MIN as i128 * i32::MIN as i128 * 2;
171 assert_eq!(i32::MAX, (product >> 32).clamp(i32::MIN as i128, i32::MAX as i128) as i32);
172
173 let product = i32::MAX as i128 * i32::MIN as i128 * 2;
174 assert_eq!(-i32::MAX, (product >> 32).clamp(i32::MIN as i128, i32::MAX as i128) as i32);
175
176 let b = vld1_s32([123, i32::MIN].as_ptr());
177 let r: [i32; 2] = transmute(vqdmulh_s32(a, b));
178 assert_eq!(r, [-123, -i32::MAX]);
179
180 // Wider 32-bit versions.
181 let a = vld1q_s32([0x4000_0000, -0x4000_0000, i32::MIN, i32::MAX].as_ptr());
182
183 let b = vld1q_s32([123, 456, 0x4000_0000, 789].as_ptr());
184 let r: [i32; 4] = transmute(vqdmulhq_s32(a, b));
185 assert_eq!(r, [61, -228, -1073741824, 788]);
186
187 let r: [i32; 4] = transmute(vqdmulhq_n_s32(a, 0x4000_0000));
188 assert_eq!(r, [536870912, -536870912, -1073741824, 1073741823]);
189
190 // 16-bit versions.
191
192 let a = vld1_s16([i16::MIN, i16::MAX, 0, 16384].as_ptr());
193 let r: [i16; 4] = transmute(vqdmulh_n_s16(a, i16::MIN));
194 assert_eq!(r, [i16::MAX, -i16::MAX, 0, -16384]);
195
196 let b = vld1_s16([123, i16::MIN, 456, 789].as_ptr());
197 let r: [i16; 4] = transmute(vqdmulh_s16(a, b));
198 assert_eq!(r, [-123, -i16::MAX, 0, 394]);
199
200 // Wider 16-bit versions.
201
202 let a = vld1q_s16([i16::MIN, i16::MAX, 0, 16384, -16384, 8192, 1, -1].as_ptr());
203 let b = vld1q_s16([123, 456, 789, i16::MIN, 1, 2, 3, 4].as_ptr());
204 let r: [i16; 8] = transmute(vqdmulhq_s16(a, b));
205 assert_eq!(r, [-123, 455, 0, -16384, -1, 0, 0, -1]);
206
207 let r: [i16; 8] = transmute(vqdmulhq_n_s16(a, i16::MIN));
208 assert_eq!(r, [32767, -32767, 0, -16384, 16384, -8192, -1, 1]);
209}
src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+sha,+sse2,+ssse3,+sse4.1
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+adx
4//@run-native
45
56#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
67mod x86 {
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs+8-2
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+aes,+vaes,+avx512f
4//@run-native
45
56use core::mem::transmute;
67#[cfg(target_arch = "x86")]
......@@ -11,7 +12,6 @@ use std::arch::x86_64::*;
1112fn main() {
1213 assert!(is_x86_feature_detected!("aes"));
1314 assert!(is_x86_feature_detected!("vaes"));
14 assert!(is_x86_feature_detected!("avx512f"));
1515
1616 unsafe {
1717 test_aes();
......@@ -86,7 +86,7 @@ unsafe fn test_aes() {
8686// be interpreted as integers; signedness does not make sense for them, but
8787// __m128i happens to be defined in terms of signed integers.
8888#[allow(overflowing_literals)]
89#[target_feature(enable = "vaes,avx512f")]
89#[target_feature(enable = "vaes")]
9090unsafe fn test_vaes() {
9191 #[target_feature(enable = "avx")]
9292 unsafe fn get_a256() -> __m256i {
......@@ -177,6 +177,12 @@ unsafe fn test_vaes() {
177177 }
178178 test_mm256_aesenclast_epi128();
179179
180 // The tests below require avx512.
181 if !is_x86_feature_detected!("avx512f") {
182 println!("warning: skipping avx512 tests");
183 return;
184 }
185
180186 #[target_feature(enable = "avx512f")]
181187 unsafe fn get_a512() -> __m512i {
182188 // Constants are random
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+avx
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx2.rs+14-5
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+avx2
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
......@@ -1068,23 +1069,31 @@ unsafe fn test_avx2() {
10681069 18, 20, 22, 24, 26, 28, 30,
10691070 );
10701071
1071 let r = _mm256_mpsadbw_epu8::<0b000>(a, a);
1072 let r = _mm256_mpsadbw_epu8::<0b00000>(a, a);
10721073 let e = _mm256_setr_epi16(0, 4, 8, 12, 16, 20, 24, 28, 0, 8, 16, 24, 32, 40, 48, 56);
10731074 assert_eq_m256i(r, e);
10741075
1075 let r = _mm256_mpsadbw_epu8::<0b001>(a, a);
1076 let r = _mm256_mpsadbw_epu8::<0b001001>(a, a);
10761077 let e = _mm256_setr_epi16(16, 12, 8, 4, 0, 4, 8, 12, 32, 24, 16, 8, 0, 8, 16, 24);
10771078 assert_eq_m256i(r, e);
10781079
1079 let r = _mm256_mpsadbw_epu8::<0b100>(a, a);
1080 let r = _mm256_mpsadbw_epu8::<0b000001>(a, a);
1081 let e = _mm256_setr_epi16(16, 12, 8, 4, 0, 4, 8, 12, 0, 8, 16, 24, 32, 40, 48, 56);
1082 assert_eq_m256i(r, e);
1083
1084 let r = _mm256_mpsadbw_epu8::<0b001000>(a, a);
1085 let e = _mm256_setr_epi16(0, 4, 8, 12, 16, 20, 24, 28, 32, 24, 16, 8, 0, 8, 16, 24);
1086 assert_eq_m256i(r, e);
1087
1088 let r = _mm256_mpsadbw_epu8::<0b100100>(a, a);
10801089 let e = _mm256_setr_epi16(16, 20, 24, 28, 32, 36, 40, 44, 32, 40, 48, 56, 64, 72, 80, 88);
10811090 assert_eq_m256i(r, e);
10821091
1083 let r = _mm256_mpsadbw_epu8::<0b101>(a, a);
1092 let r = _mm256_mpsadbw_epu8::<0b101101>(a, a);
10841093 let e = _mm256_setr_epi16(0, 4, 8, 12, 16, 20, 24, 28, 0, 8, 16, 24, 32, 40, 48, 56);
10851094 assert_eq_m256i(r, e);
10861095
1087 let r = _mm256_mpsadbw_epu8::<0b111>(a, a);
1096 let r = _mm256_mpsadbw_epu8::<0b111111>(a, a);
10881097 let e = _mm256_setr_epi16(32, 28, 24, 20, 16, 12, 8, 4, 64, 56, 48, 40, 32, 24, 16, 8);
10891098 assert_eq_m256i(r, e);
10901099 }
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs+8
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512bitalg,+avx512vpopcntdq,+avx512vnni,+avx512vbmi
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
......@@ -9,6 +10,13 @@ use std::arch::x86_64::*;
910use std::mem::transmute;
1011
1112fn main() {
13 if !is_x86_feature_detected!("avx512f") {
14 // GH runners don't have this, but we still want to run this natively if
15 // the machine happens to have gfni. So we bail out dynamically.
16 println!("warning: skipping AVX512 tests");
17 return;
18 }
19
1220 assert!(is_x86_feature_detected!("avx512f"));
1321 assert!(is_x86_feature_detected!("avx512vl"));
1422 assert!(is_x86_feature_detected!("avx512bw"));
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+bmi1,+bmi2
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs+17-5
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+gfni,+avx512f
4//@run-native
45
56// The constants in the tests below are just bit patterns. They should not
67// be interpreted as integers; signedness does not make sense for them, but
......@@ -20,8 +21,14 @@ const CONSTANT_BYTE: i32 = 0x63;
2021fn main() {
2122 // Mostly copied from library/stdarch/crates/core_arch/src/x86/gfni.rs
2223
23 assert!(is_x86_feature_detected!("avx512f"));
24 assert!(is_x86_feature_detected!("gfni"));
24 assert!(is_x86_feature_detected!("avx"));
25
26 if !is_x86_feature_detected!("gfni") {
27 // GH runners don't have this, but we still want to run this natively if
28 // the machine happens to have gfni. So we bail out dynamically.
29 println!("warning: skipping gfni tests");
30 return;
31 }
2532
2633 unsafe {
2734 let byte_mul_test_data = generate_byte_mul_test_data();
......@@ -29,15 +36,20 @@ fn main() {
2936 let affine_mul_test_data_constant = generate_affine_mul_test_data(CONSTANT_BYTE as u8);
3037 let inv_tests_data = generate_inv_tests_data();
3138
32 test_mm512_gf2p8mul_epi8(&byte_mul_test_data);
3339 test_mm256_gf2p8mul_epi8(&byte_mul_test_data);
3440 test_mm_gf2p8mul_epi8(&byte_mul_test_data);
35 test_mm512_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity);
3641 test_mm256_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity);
3742 test_mm_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity);
38 test_mm512_gf2p8affineinv_epi64_epi8(&inv_tests_data, &affine_mul_test_data_constant);
3943 test_mm256_gf2p8affineinv_epi64_epi8(&inv_tests_data, &affine_mul_test_data_constant);
4044 test_mm_gf2p8affineinv_epi64_epi8(&inv_tests_data, &affine_mul_test_data_constant);
45
46 if is_x86_feature_detected!("avx512f") {
47 test_mm512_gf2p8mul_epi8(&byte_mul_test_data);
48 test_mm512_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity);
49 test_mm512_gf2p8affineinv_epi64_epi8(&inv_tests_data, &affine_mul_test_data_constant);
50 } else {
51 println!("warning: skipping avx512 tests");
52 }
4153 }
4254}
4355
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pclmulqdq.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+pclmulqdq
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs+1
......@@ -1,5 +1,6 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
3//@run-native
34#![allow(unnecessary_transmutes)]
45
56#[cfg(target_arch = "x86")]
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs+1
......@@ -1,5 +1,6 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
3//@run-native
34#![allow(unnecessary_transmutes)]
45
56#[cfg(target_arch = "x86")]
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse3-ssse3.rs+1
......@@ -2,6 +2,7 @@
22//@only-target: x86_64 i686
33// SSSE3 implicitly enables SSE3
44//@compile-flags: -C target-feature=+ssse3
5//@run-native
56
67use core::mem::transmute;
78#[cfg(target_arch = "x86")]
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse41.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+sse4.1
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs+1
......@@ -1,6 +1,7 @@
11// We're testing x86 target specific features
22//@only-target: x86_64 i686
33//@compile-flags: -C target-feature=+sse4.2
4//@run-native
45
56#[cfg(target_arch = "x86")]
67use std::arch::x86::*;
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs+1
......@@ -3,6 +3,7 @@
33//@only-target: x86_64 i686
44//@[avx512]compile-flags: -C target-feature=+vpclmulqdq,+avx512f
55//@[avx]compile-flags: -C target-feature=+vpclmulqdq,+avx2
6//@run-native
67
78// The constants in the tests below are just bit patterns. They should not
89// be interpreted as integers; signedness does not make sense for them, but
src/tools/miri/tests/pass/shims/x86/intrinsics-x86.rs+3-2
......@@ -1,4 +1,6 @@
1#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1//@only-target: x86_64 i686
2//@run-native
3
24mod x86 {
35 #[cfg(target_arch = "x86")]
46 use core::arch::x86 as arch;
......@@ -84,7 +86,6 @@ mod x86_64 {
8486}
8587
8688fn main() {
87 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
8889 x86::main();
8990 #[cfg(target_arch = "x86_64")]
9091 x86_64::main();
src/tools/miri/tests/utils/libc.rs+1-1
......@@ -86,7 +86,7 @@ pub fn read_exact_array<const N: usize>(fd: libc::c_int) -> io::Result<[u8; N]>
8686/// Do a single read from `fd` and return the part of the buffer that was written into,
8787/// and the rest.
8888#[track_caller]
89pub fn read_split_slice(fd: libc::c_int, buf: &mut [u8]) -> io::Result<(&mut [u8], &mut [u8])> {
89pub fn read_partial(fd: libc::c_int, buf: &mut [u8]) -> io::Result<(&mut [u8], &mut [u8])> {
9090 let res = errno_result(unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) })?;
9191 Ok(buf.split_at_mut(res as usize))
9292}
src/tools/tidy/src/issues.txt-1
......@@ -2442,7 +2442,6 @@ ui/span/issue-42234-unknown-receiver-type.rs
24422442ui/span/issue-43927-non-ADT-derive.rs
24432443ui/span/issue-71363.rs
24442444ui/span/issue-81800.rs
2445ui/span/issue28498-reject-ex1.rs
24462445ui/span/issue28498-reject-lifetime-param.rs
24472446ui/span/issue28498-reject-passed-to-fn.rs
24482447ui/span/issue28498-reject-trait-bound.rs
tests/rustdoc-html/impl/impl-fundamental-nesting.rs created+58
......@@ -0,0 +1,58 @@
1// Followup to https://github.com/rust-lang/rust/issues/92940 and impl-box.rs.
2//
3// Show traits implemented on fundamental types that wrap local ones: nested edition.
4
5#![crate_name = "foo"]
6
7use std::pin::Pin;
8
9pub struct Local;
10
11//@ has 'foo/struct.Local.html'
12
13// Nested fundamental + foreign Self.
14//@ has '-' '//*[@id="impl-From%3CBox%3CLocal%3E%3E-for-String"]' 'impl From<Box<Local>> for String'
15impl From<Box<Local>> for String {
16 fn from(_: Box<Local>) -> String {
17 String::new()
18 }
19}
20
21// Also test with Pin.
22//@ has '-' '//*[@id="impl-From%3CPin%3CLocal%3E%3E-for-u8"]' 'impl From<Pin<Local>> for u8'
23impl From<Pin<Local>> for u8 {
24 fn from(_: Pin<Local>) -> u8 {
25 0
26 }
27}
28
29// Reference to a fundamental wrapper.
30//@ has '-' '//*[@id="impl-From%3C%26Box%3CLocal%3E%3E-for-u16"]' "impl<'a> From<&'a Box<Local>> for u16"
31impl<'a> From<&'a Box<Local>> for u16 {
32 fn from(_: &'a Box<Local>) -> u16 {
33 0
34 }
35}
36
37// Nested two levels deep in Self.
38//@ has '-' '//*[@id="impl-From%3Cu32%3E-for-Box%3CBox%3CLocal%3E%3E"]' 'impl From<u32> for Box<Box<Local>>'
39impl From<u32> for Box<Box<Local>> {
40 fn from(_: u32) -> Box<Box<Local>> {
41 Box::new(Box::new(Local))
42 }
43}
44
45// Mixed fundamental wrappers in Self.
46//@ has '-' '//*[@id="impl-From%3Cu64%3E-for-Pin%3CBox%3CLocal%3E%3E"]' 'impl From<u64> for Pin<Box<Local>>'
47impl From<u64> for Pin<Box<Local>> {
48 fn from(_: u64) -> Pin<Box<Local>> {
49 Pin::new(Box::new(Local))
50 }
51}
52
53// A non-fundamental wrapper must not show up on Local's page, but it should still be listed on the
54// trait's own page.
55pub trait Marker {}
56//@ has 'foo/trait.Marker.html' '//*[@id="impl-Marker-for-Vec%3CLocal%3E"]' 'impl Marker for Vec<Local>'
57//@ !has 'foo/struct.Local.html' '//*[@id="impl-Marker-for-Vec%3CLocal%3E"]' 'impl Marker for Vec<Local>'
58impl Marker for Vec<Local> {}
tests/rustdoc-json/impls/fundamental_nesting.rs created+57
......@@ -0,0 +1,57 @@
1// Companion to tests/rustdoc-html/impl/impl-fundamental-nesting.rs.
2//
3// Show traits implemented on fundamental types that wrap local ones: nested edition.
4
5use std::pin::Pin;
6
7pub struct Local;
8
9// Nested fundamental + foreign Self.
10/// from box local
11impl From<Box<Local>> for String {
12 fn from(_: Box<Local>) -> String {
13 String::new()
14 }
15}
16//@ set from_box_local = "$.index[?(@.docs=='from box local')].id"
17//@ has "$.index[?(@.name=='Local')].inner.struct.impls[*]" $from_box_local
18
19// Reference to a fundamental wrapper.
20/// from ref box local
21impl<'a> From<&'a Box<Local>> for u16 {
22 fn from(_: &'a Box<Local>) -> u16 {
23 0
24 }
25}
26//@ set from_ref_box_local = "$.index[?(@.docs=='from ref box local')].id"
27//@ has "$.index[?(@.name=='Local')].inner.struct.impls[*]" $from_ref_box_local
28
29// Nested two levels deep in Self.
30/// u32 for box box local
31impl From<u32> for Box<Box<Local>> {
32 fn from(_: u32) -> Box<Box<Local>> {
33 Box::new(Box::new(Local))
34 }
35}
36//@ set u32_for_box_box_local = "$.index[?(@.docs=='u32 for box box local')].id"
37//@ has "$.index[?(@.name=='Local')].inner.struct.impls[*]" $u32_for_box_box_local
38
39// Mixed fundamental wrappers in Self.
40/// u64 for pin box local
41impl From<u64> for Pin<Box<Local>> {
42 fn from(_: u64) -> Pin<Box<Local>> {
43 Pin::new(Box::new(Local))
44 }
45}
46//@ set u64_for_pin_box_local = "$.index[?(@.docs=='u64 for pin box local')].id"
47//@ has "$.index[?(@.name=='Local')].inner.struct.impls[*]" $u64_for_pin_box_local
48
49// A non-fundamental wrapper must not associate the impl with Local, but the impl must still be
50// listed on the trait itself.
51pub trait Marker {}
52
53/// marker for vec local
54impl Marker for Vec<Local> {}
55//@ set marker_for_vec_local = "$.index[?(@.docs=='marker for vec local')].id"
56//@ !has "$.index[?(@.name=='Local')].inner.struct.impls[*]" $marker_for_vec_local
57//@ has "$.index[?(@.name=='Marker')].inner.trait.implementations[*]" $marker_for_vec_local
tests/ui/README.md+4
......@@ -1351,6 +1351,10 @@ Generic collection of tests for suggestions, when no more specific directories a
13511351
13521352**FIXME**: Some overlap with `tests/ui/did_you_mean/`, that directory should probably be moved under here.
13531353
1354## `tests/ui/supertrait-shadowing/`
1355
1356Tests for supertrait item shadowing (RFC 3624).
1357
13541358## `tests/ui/svh/`: Strict Version Hash
13551359
13561360Tests on the *Strict Version Hash* (SVH, also known as the "crate hash").
tests/ui/associated-types/nested-fnonce-output-projection.rs created+18
......@@ -0,0 +1,18 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28550>.
2//@ run-pass
3
4struct A<F: FnOnce()->T,T>(F::Output);
5struct B<F: FnOnce()->T,T>(A<F,T>);
6
7// Removing Option causes it to compile.
8fn foo<T,F: FnOnce()->T>(f: F) -> Option<B<F,T>> {
9 Some(B(A(f())))
10}
11
12fn main() {
13 let v = (|| foo(||4))();
14 match v {
15 Some(B(A(4))) => {},
16 _ => unreachable!()
17 }
18}
tests/ui/associated-types/projection-as-type-alias.rs created+21
......@@ -0,0 +1,21 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28828>.
2//! This failed to compile as associated types aliases were not normalized.
3//@ run-pass
4
5pub trait Foo {
6 type Out;
7}
8
9impl Foo for () {
10 type Out = bool;
11}
12
13fn main() {
14 type Bool = <() as Foo>::Out;
15
16 let x: Bool = true;
17 assert!(x);
18
19 let y: Option<Bool> = None;
20 assert_eq!(y, None);
21}
tests/ui/associated-types/resolve-method-with-missing-assoc-type.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28344>.
2//! Test we don't ICE on item resolution when associated type is omitted.
3//@ edition:2015
4
5use std::ops::BitXor;
6
7fn main() {
8 let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
9 //~^ ERROR must be specified
10 //~| WARN trait objects without an explicit `dyn` are deprecated
11 //~| WARN this is accepted in the current edition
12
13 let g = BitXor::bitor;
14 //~^ ERROR must be specified
15 //~| WARN trait objects without an explicit `dyn` are deprecated
16 //~| WARN this is accepted in the current edition
17}
tests/ui/associated-types/resolve-method-with-missing-assoc-type.stderr created+52
......@@ -0,0 +1,52 @@
1warning: trait objects without an explicit `dyn` are deprecated
2 --> $DIR/resolve-method-with-missing-assoc-type.rs:8:17
3 |
4LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
5 | ^^^^^^
6 |
7 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
8 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
9 = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
10help: if this is a dyn-compatible trait, use `dyn`
11 |
12LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
13 | ++++ +
14
15error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
16 --> $DIR/resolve-method-with-missing-assoc-type.rs:8:17
17 |
18LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
19 | ^^^^^^
20 |
21help: specify the associated type
22 |
23LL | let x: u8 = BitXor::<Output = /* Type */>::bitor(0 as u8, 0 as u8);
24 | +++++++++++++++++++++++
25
26warning: trait objects without an explicit `dyn` are deprecated
27 --> $DIR/resolve-method-with-missing-assoc-type.rs:13:13
28 |
29LL | let g = BitXor::bitor;
30 | ^^^^^^
31 |
32 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
33 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
34help: if this is a dyn-compatible trait, use `dyn`
35 |
36LL | let g = <dyn BitXor>::bitor;
37 | ++++ +
38
39error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
40 --> $DIR/resolve-method-with-missing-assoc-type.rs:13:13
41 |
42LL | let g = BitXor::bitor;
43 | ^^^^^^
44 |
45help: specify the associated type
46 |
47LL | let g = BitXor::<Output = /* Type */>::bitor;
48 | +++++++++++++++++++++++
49
50error: aborting due to 2 previous errors; 2 warnings emitted
51
52For more information about this error, try `rustc --explain E0191`.
tests/ui/binop/binop-subtyping-lifetimes.rs created+42
......@@ -0,0 +1,42 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27949>.
2//!
3//! At one time, the `==` operator (and other binary operators) did not
4//! support subtyping during type checking, and would therefore require
5//! LHS and RHS to be exactly identical--i.e. to have the same lifetimes.
6//!
7//! This was fixed in 1a7fb7dc78439a704f024609ce3dc0beb1386552.
8//@ run-pass
9
10#[derive(Copy, Clone)]
11struct Input<'a> {
12 foo: &'a u32
13}
14
15impl <'a> std::cmp::PartialEq<Input<'a>> for Input<'a> {
16 fn eq(&self, other: &Input<'a>) -> bool {
17 self.foo == other.foo
18 }
19
20 fn ne(&self, other: &Input<'a>) -> bool {
21 self.foo != other.foo
22 }
23}
24
25
26fn check_equal<'a, 'b>(x: Input<'a>, y: Input<'b>) -> bool {
27 // Type checking error due to 'a != 'b prior to 1a7fb7dc78
28 x == y
29}
30
31fn main() {
32 let i = 1u32;
33 let j = 1u32;
34 let k = 2u32;
35
36 let input_i = Input { foo: &i };
37 let input_j = Input { foo: &j };
38 let input_k = Input { foo: &k };
39 assert!(check_equal(input_i, input_i));
40 assert!(check_equal(input_i, input_j));
41 assert!(!check_equal(input_i, input_k));
42}
tests/ui/borrowck/enum-variants-share-field-name.rs created+24
......@@ -0,0 +1,24 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27889>.
2//! Test that a field can have the same name in different variants
3//! of an enum, and borrowck won't treat them as the same value.
4//@ check-pass
5#![allow(unused_assignments)]
6#![allow(unused_variables)]
7
8pub enum Foo {
9 X { foo: u32 },
10 Y { foo: u32 }
11}
12
13pub fn foo(mut x: Foo) {
14 let mut y = None;
15 let mut z = None;
16 if let Foo::X { ref foo } = x {
17 z = Some(foo);
18 }
19 if let Foo::Y { ref mut foo } = x {
20 y = Some(foo);
21 }
22}
23
24fn main() {}
tests/ui/derives/clone-copy/derive-copy-clone-non-copy-field-diagnostic.rs created+11
......@@ -0,0 +1,11 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27340>.
2//! Test anon fields in tuple-syntax structs which don't implement trait
3//! get nice error message mentioning the type of field and its span.
4
5struct Foo;
6#[derive(Copy, Clone)]
7struct Bar(Foo);
8//~^ ERROR: the trait `Copy` cannot be implemented for this type
9//~| ERROR: `Foo: Clone` is not satisfied
10
11fn main() {}
tests/ui/derives/clone-copy/derive-copy-clone-non-copy-field-diagnostic.stderr created+28
......@@ -0,0 +1,28 @@
1error[E0204]: the trait `Copy` cannot be implemented for this type
2 --> $DIR/derive-copy-clone-non-copy-field-diagnostic.rs:7:8
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- in this derive macro expansion
6LL | struct Bar(Foo);
7 | ^^^ --- this field does not implement `Copy`
8
9error[E0277]: the trait bound `Foo: Clone` is not satisfied
10 --> $DIR/derive-copy-clone-non-copy-field-diagnostic.rs:7:12
11 |
12LL | #[derive(Copy, Clone)]
13 | ----- in this derive macro expansion
14LL | struct Bar(Foo);
15 | ^^^ the trait `Clone` is not implemented for `Foo`
16 |
17note: required by a bound in `std::clone::AssertParamIsClone`
18 --> $SRC_DIR/core/src/clone.rs:LL:COL
19help: consider annotating `Foo` with `#[derive(Clone)]`
20 |
21LL + #[derive(Clone)]
22LL | struct Foo;
23 |
24
25error: aborting due to 2 previous errors
26
27Some errors have detailed explanations: E0204, E0277.
28For more information about an error, try `rustc --explain E0204`.
tests/ui/drop/drop-with-trait-bound-calls-method-on-self.rs created+34
......@@ -0,0 +1,34 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/4252
2//@ run-pass
3trait X {
4 fn call<T: std::fmt::Debug>(&self, x: &T);
5 fn default_method<T: std::fmt::Debug>(&self, x: &T) {
6 println!("X::default_method {:?}", x);
7 }
8}
9
10#[derive(Debug)]
11struct Y(#[allow(dead_code)] isize);
12
13#[derive(Debug)]
14struct Z<T: X+std::fmt::Debug> {
15 x: T
16}
17
18impl X for Y {
19 fn call<T: std::fmt::Debug>(&self, x: &T) {
20 println!("X::call {:?} {:?}", self, x);
21 }
22}
23
24impl<T: X + std::fmt::Debug> Drop for Z<T> {
25 fn drop(&mut self) {
26 // These statements used to cause an ICE.
27 self.x.call(self);
28 self.x.default_method(self);
29 }
30}
31
32pub fn main() {
33 let _z = Z {x: Y(42)};
34}
tests/ui/drop/dropflag-reinit-in-loop.rs created+26
......@@ -0,0 +1,26 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27401>.
2//! Check that when a `let`-binding occurs in a loop, its associated
3//! drop-flag is reinitialized (to indicate "needs-drop" at the end of
4//! the owning variable's scope).
5//@ run-pass
6
7struct A<'a>(&'a mut i32);
8
9impl<'a> Drop for A<'a> {
10 fn drop(&mut self) {
11 *self.0 += 1;
12 }
13}
14
15fn main() {
16 let mut cnt = 0;
17 for i in 0..2 {
18 let a = A(&mut cnt);
19 if i == 1 { // Note that
20 break; // both this break
21 } // and also
22 drop(a); // this move of `a`
23 // are necessary to expose the bug
24 }
25 assert_eq!(cnt, 2);
26}
tests/ui/dropck/drop-impl-for-type-param-with-trait-bound.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/41974
2#[derive(Copy, Clone)]
3struct Flags;
4
5trait A {
6}
7
8impl<T> Drop for T where T: A {
9 //~^ ERROR E0120
10 //~| ERROR E0210
11 fn drop(&mut self) {
12 }
13}
14
15fn main() {}
tests/ui/dropck/drop-impl-for-type-param-with-trait-bound.stderr created+19
......@@ -0,0 +1,19 @@
1error[E0210]: type parameter `T` must be used as an argument to some local type (e.g., `MyStruct<T>`)
2 --> $DIR/drop-impl-for-type-param-with-trait-bound.rs:8:6
3 |
4LL | impl<T> Drop for T where T: A {
5 | ^ uncovered type parameter
6 |
7 = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
8 = note: only traits defined in the current crate can be implemented for a type parameter
9
10error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
11 --> $DIR/drop-impl-for-type-param-with-trait-bound.rs:8:18
12 |
13LL | impl<T> Drop for T where T: A {
14 | ^ must be a struct, enum, or union in the current crate
15
16error: aborting due to 2 previous errors
17
18Some errors have detailed explanations: E0120, E0210.
19For more information about an error, try `rustc --explain E0120`.
tests/ui/dropck/dropck-resolves-associated-type-in-field.rs created+32
......@@ -0,0 +1,32 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/48132
2// Regression test for #48132. This was failing due to problems around
3// the projection caching and dropck type enumeration.
4
5//@ run-pass
6
7#![allow(dead_code)]
8
9struct Inner<I, V> {
10 iterator: I,
11 item: V,
12}
13
14struct Outer<I: Iterator> {
15 inner: Inner<I, I::Item>,
16}
17
18fn outer<I>(iterator: I) -> Outer<I>
19where I: Iterator,
20 I::Item: Default,
21{
22 Outer {
23 inner: Inner {
24 iterator: iterator,
25 item: Default::default(),
26 }
27 }
28}
29
30fn main() {
31 outer(std::iter::once(&1).cloned());
32}
tests/ui/dropck/self-referential-struct-with-boxed-closure.rs created+7
......@@ -0,0 +1,7 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/26641
2//@ run-pass
3struct Parser<'a>(#[allow(dead_code)] Box<dyn FnMut(Parser) + 'a>);
4
5fn main() {
6 let _x = Parser(Box::new(|_|{}));
7}
tests/ui/dyn-compatibility/method-with-self-trait-bound-not-dyn-safe.rs created+19
......@@ -0,0 +1,19 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/50781
2trait Trait {}
3
4trait X {
5 fn foo(&self) where Self: Trait;
6}
7
8impl X for () {
9 fn foo(&self) {}
10}
11
12impl Trait for dyn X {}
13//~^ ERROR the trait `X` is not dyn compatible
14
15pub fn main() {
16 // Check that this does not segfault.
17 <dyn X as X>::foo(&());
18 //~^ ERROR the trait `X` is not dyn compatible
19}
tests/ui/dyn-compatibility/method-with-self-trait-bound-not-dyn-safe.stderr created+37
......@@ -0,0 +1,37 @@
1error[E0038]: the trait `X` is not dyn compatible
2 --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:12:16
3 |
4LL | impl Trait for dyn X {}
5 | ^^^^^ `X` is not dyn compatible
6 |
7note: for a trait to be dyn compatible it needs to allow building a vtable
8 for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
9 --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:5:8
10 |
11LL | trait X {
12 | - this trait is not dyn compatible...
13LL | fn foo(&self) where Self: Trait;
14 | ^^^ ...because method `foo` references the `Self` type in its `where` clause
15 = help: consider moving `foo` to another trait
16 = help: only type `()` implements `X`; consider using it directly instead.
17
18error[E0038]: the trait `X` is not dyn compatible
19 --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:17:10
20 |
21LL | <dyn X as X>::foo(&());
22 | ^ `X` is not dyn compatible
23 |
24note: for a trait to be dyn compatible it needs to allow building a vtable
25 for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
26 --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:5:8
27 |
28LL | trait X {
29 | - this trait is not dyn compatible...
30LL | fn foo(&self) where Self: Trait;
31 | ^^^ ...because method `foo` references the `Self` type in its `where` clause
32 = help: consider moving `foo` to another trait
33 = help: only type `()` implements `X`; consider using it directly instead.
34
35error: aborting due to 2 previous errors
36
37For more information about this error, try `rustc --explain E0038`.
tests/ui/extern/extern-c-method-with-str-param.rs created+16
......@@ -0,0 +1,16 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28600>.
2//! pub extern fn with parameter type &str inside struct impl caused ICE.
3//@ build-pass
4
5struct Test;
6
7impl Test {
8 #[allow(dead_code)]
9 #[allow(unused_variables)]
10 #[allow(improper_ctypes_definitions)]
11 pub extern "C" fn test(val: &str) {
12
13 }
14}
15
16fn main() {}
tests/ui/higher-ranked/region-leak-rc-and-mut-ptr.rs created+25
......@@ -0,0 +1,25 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28279>.
2//! Region variables escaped comparison for common supertype, which led
3//! `Rc<Fn(&T)>` and `*mut Fn(&T)` to break.
4//@ check-pass
5
6#![allow(dead_code)]
7use std::rc::Rc;
8
9fn test1() -> Rc<dyn for<'a> Fn(&'a usize) + 'static> {
10 if let Some(_) = Some(1) {
11 loop{}
12 } else {
13 loop{}
14 }
15}
16
17fn test2() -> *mut (dyn for<'a> Fn(&'a usize) + 'static) {
18 if let Some(_) = Some(1) {
19 loop{}
20 } else {
21 loop{}
22 }
23}
24
25fn main() {}
tests/ui/inference/closure-arg-lifetime-by-ref.rs created+29
......@@ -0,0 +1,29 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28936>.
2//@ check-pass
3
4pub type Session = i32;
5pub struct StreamParser<'a, T> {
6 _tokens: T,
7 _session: &'a mut Session,
8}
9
10impl<'a, T> StreamParser<'a, T> {
11 pub fn thing(&mut self) -> bool { true }
12}
13
14pub fn parse_stream<T: Iterator<Item=i32>, U, F>(
15 _session: &mut Session, _tokens: T, _f: F) -> U
16 where F: Fn(&mut StreamParser<T>) -> U { panic!(); }
17
18pub fn thing(session: &mut Session) {
19 let mut stream = vec![1, 2, 3].into_iter();
20
21 let _b = parse_stream(session,
22 stream.by_ref(),
23 // replacing the above with the following fixes it
24 //&mut stream,
25 |p| p.thing());
26
27}
28
29fn main() {}
tests/ui/issues/issue-27401-dropflag-reinit.rs deleted-26
......@@ -1,26 +0,0 @@
1//@ run-pass
2
3// Check that when a `let`-binding occurs in a loop, its associated
4// drop-flag is reinitialized (to indicate "needs-drop" at the end of
5// the owning variable's scope).
6
7struct A<'a>(&'a mut i32);
8
9impl<'a> Drop for A<'a> {
10 fn drop(&mut self) {
11 *self.0 += 1;
12 }
13}
14
15fn main() {
16 let mut cnt = 0;
17 for i in 0..2 {
18 let a = A(&mut cnt);
19 if i == 1 { // Note that
20 break; // both this break
21 } // and also
22 drop(a); // this move of `a`
23 // are necessary to expose the bug
24 }
25 assert_eq!(cnt, 2);
26}
tests/ui/issues/issue-2761.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ run-fail
2//@ error-pattern:custom message
3//@ needs-subprocess
4
5fn main() {
6 assert!(false, "custom message");
7}
tests/ui/issues/issue-27815.rs deleted-12
......@@ -1,12 +0,0 @@
1mod A {}
2
3fn main() {
4 let u = A { x: 1 }; //~ ERROR expected struct, variant or union type, found module `A`
5 let v = u32 { x: 1 }; //~ ERROR expected struct, variant or union type, found builtin type `u32`
6 match () {
7 A { x: 1 } => {}
8 //~^ ERROR expected struct, variant or union type, found module `A`
9 u32 { x: 1 } => {}
10 //~^ ERROR expected struct, variant or union type, found builtin type `u32`
11 }
12}
tests/ui/issues/issue-27815.stderr deleted-27
......@@ -1,27 +0,0 @@
1error[E0574]: expected struct, variant or union type, found module `A`
2 --> $DIR/issue-27815.rs:4:13
3 |
4LL | let u = A { x: 1 };
5 | ^ not a struct, variant or union type
6
7error[E0574]: expected struct, variant or union type, found builtin type `u32`
8 --> $DIR/issue-27815.rs:5:13
9 |
10LL | let v = u32 { x: 1 };
11 | ^^^ not a struct, variant or union type
12
13error[E0574]: expected struct, variant or union type, found module `A`
14 --> $DIR/issue-27815.rs:7:9
15 |
16LL | A { x: 1 } => {}
17 | ^ not a struct, variant or union type
18
19error[E0574]: expected struct, variant or union type, found builtin type `u32`
20 --> $DIR/issue-27815.rs:9:9
21 |
22LL | u32 { x: 1 } => {}
23 | ^^^ not a struct, variant or union type
24
25error: aborting due to 4 previous errors
26
27For more information about this error, try `rustc --explain E0574`.
tests/ui/issues/issue-27842.rs deleted-16
......@@ -1,16 +0,0 @@
1fn main() {
2 let tup = (0, 1, 2);
3 // the case where we show a suggestion
4 let _ = tup[0];
5 //~^ ERROR cannot index into a value of type
6
7 // the case where we show just a general hint
8 let i = 0_usize;
9 let _ = tup[i];
10 //~^ ERROR cannot index into a value of type
11
12 // the case where the index is out of bounds
13 let tup = (10,);
14 let _ = tup[3];
15 //~^ ERROR cannot index into a value of type
16}
tests/ui/issues/issue-27842.stderr deleted-27
......@@ -1,27 +0,0 @@
1error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
2 --> $DIR/issue-27842.rs:4:16
3 |
4LL | let _ = tup[0];
5 | ^^^ help: to access tuple element `0`, use: `.0`
6 |
7 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
8
9error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
10 --> $DIR/issue-27842.rs:9:16
11 |
12LL | let _ = tup[i];
13 | ^^^
14 |
15 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
16
17error[E0608]: cannot index into a value of type `({integer},)`
18 --> $DIR/issue-27842.rs:14:16
19 |
20LL | let _ = tup[3];
21 | ^^^
22 |
23 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
24
25error: aborting due to 3 previous errors
26
27For more information about this error, try `rustc --explain E0608`.
tests/ui/issues/issue-27889.rs deleted-23
......@@ -1,23 +0,0 @@
1//@ check-pass
2#![allow(unused_assignments)]
3#![allow(unused_variables)]
4// Test that a field can have the same name in different variants
5// of an enum
6
7pub enum Foo {
8 X { foo: u32 },
9 Y { foo: u32 }
10}
11
12pub fn foo(mut x: Foo) {
13 let mut y = None;
14 let mut z = None;
15 if let Foo::X { ref foo } = x {
16 z = Some(foo);
17 }
18 if let Foo::Y { ref mut foo } = x {
19 y = Some(foo);
20 }
21}
22
23fn main() {}
tests/ui/issues/issue-27942.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ dont-require-annotations: NOTE
2
3pub trait Resources<'a> {}
4
5pub trait Buffer<'a, R: Resources<'a>> {
6
7 fn select(&self) -> BufferViewHandle<R>;
8 //~^ ERROR mismatched types
9 //~| NOTE lifetime mismatch
10 //~| ERROR mismatched types
11 //~| NOTE lifetime mismatch
12}
13
14pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R);
15
16fn main() {}
tests/ui/issues/issue-27942.stderr deleted-41
......@@ -1,41 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-27942.rs:7:25
3 |
4LL | fn select(&self) -> BufferViewHandle<R>;
5 | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
6 |
7 = note: expected trait `Resources<'_>`
8 found trait `Resources<'a>`
9note: the lifetime `'a` as defined here...
10 --> $DIR/issue-27942.rs:5:18
11 |
12LL | pub trait Buffer<'a, R: Resources<'a>> {
13 | ^^
14note: ...does not necessarily outlive the anonymous lifetime defined here
15 --> $DIR/issue-27942.rs:7:15
16 |
17LL | fn select(&self) -> BufferViewHandle<R>;
18 | ^^^^^
19
20error[E0308]: mismatched types
21 --> $DIR/issue-27942.rs:7:25
22 |
23LL | fn select(&self) -> BufferViewHandle<R>;
24 | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
25 |
26 = note: expected trait `Resources<'_>`
27 found trait `Resources<'a>`
28note: the anonymous lifetime defined here...
29 --> $DIR/issue-27942.rs:7:15
30 |
31LL | fn select(&self) -> BufferViewHandle<R>;
32 | ^^^^^
33note: ...does not necessarily outlive the lifetime `'a` as defined here
34 --> $DIR/issue-27942.rs:5:18
35 |
36LL | pub trait Buffer<'a, R: Resources<'a>> {
37 | ^^
38
39error: aborting due to 2 previous errors
40
41For more information about this error, try `rustc --explain E0308`.
tests/ui/issues/issue-27949.rs deleted-41
......@@ -1,41 +0,0 @@
1//@ run-pass
2//
3// At one time, the `==` operator (and other binary operators) did not
4// support subtyping during type checking, and would therefore require
5// LHS and RHS to be exactly identical--i.e. to have the same lifetimes.
6//
7// This was fixed in 1a7fb7dc78439a704f024609ce3dc0beb1386552.
8
9#[derive(Copy, Clone)]
10struct Input<'a> {
11 foo: &'a u32
12}
13
14impl <'a> std::cmp::PartialEq<Input<'a>> for Input<'a> {
15 fn eq(&self, other: &Input<'a>) -> bool {
16 self.foo == other.foo
17 }
18
19 fn ne(&self, other: &Input<'a>) -> bool {
20 self.foo != other.foo
21 }
22}
23
24
25fn check_equal<'a, 'b>(x: Input<'a>, y: Input<'b>) -> bool {
26 // Type checking error due to 'a != 'b prior to 1a7fb7dc78
27 x == y
28}
29
30fn main() {
31 let i = 1u32;
32 let j = 1u32;
33 let k = 2u32;
34
35 let input_i = Input { foo: &i };
36 let input_j = Input { foo: &j };
37 let input_k = Input { foo: &k };
38 assert!(check_equal(input_i, input_i));
39 assert!(check_equal(input_i, input_j));
40 assert!(!check_equal(input_i, input_k));
41}
tests/ui/issues/issue-28279.rs deleted-21
......@@ -1,21 +0,0 @@
1//@ check-pass
2#![allow(dead_code)]
3use std::rc::Rc;
4
5fn test1() -> Rc<dyn for<'a> Fn(&'a usize) + 'static> {
6 if let Some(_) = Some(1) {
7 loop{}
8 } else {
9 loop{}
10 }
11}
12
13fn test2() -> *mut (dyn for<'a> Fn(&'a usize) + 'static) {
14 if let Some(_) = Some(1) {
15 loop{}
16 } else {
17 loop{}
18 }
19}
20
21fn main() {}
tests/ui/issues/issue-28344.rs deleted-14
......@@ -1,14 +0,0 @@
1//@ edition:2015
2use std::ops::BitXor;
3
4fn main() {
5 let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
6 //~^ ERROR must be specified
7 //~| WARN trait objects without an explicit `dyn` are deprecated
8 //~| WARN this is accepted in the current edition
9
10 let g = BitXor::bitor;
11 //~^ ERROR must be specified
12 //~| WARN trait objects without an explicit `dyn` are deprecated
13 //~| WARN this is accepted in the current edition
14}
tests/ui/issues/issue-28344.stderr deleted-52
......@@ -1,52 +0,0 @@
1warning: trait objects without an explicit `dyn` are deprecated
2 --> $DIR/issue-28344.rs:5:17
3 |
4LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
5 | ^^^^^^
6 |
7 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
8 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
9 = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
10help: if this is a dyn-compatible trait, use `dyn`
11 |
12LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
13 | ++++ +
14
15error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
16 --> $DIR/issue-28344.rs:5:17
17 |
18LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
19 | ^^^^^^
20 |
21help: specify the associated type
22 |
23LL | let x: u8 = BitXor::<Output = /* Type */>::bitor(0 as u8, 0 as u8);
24 | +++++++++++++++++++++++
25
26warning: trait objects without an explicit `dyn` are deprecated
27 --> $DIR/issue-28344.rs:10:13
28 |
29LL | let g = BitXor::bitor;
30 | ^^^^^^
31 |
32 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
33 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
34help: if this is a dyn-compatible trait, use `dyn`
35 |
36LL | let g = <dyn BitXor>::bitor;
37 | ++++ +
38
39error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified
40 --> $DIR/issue-28344.rs:10:13
41 |
42LL | let g = BitXor::bitor;
43 | ^^^^^^
44 |
45help: specify the associated type
46 |
47LL | let g = BitXor::<Output = /* Type */>::bitor;
48 | +++++++++++++++++++++++
49
50error: aborting due to 2 previous errors; 2 warnings emitted
51
52For more information about this error, try `rustc --explain E0191`.
tests/ui/issues/issue-28472.rs deleted-14
......@@ -1,14 +0,0 @@
1// Check that the visibility modifier is included in the span of foreign items.
2
3extern "C" {
4 fn foo();
5
6 pub //~ ERROR the name `foo` is defined multiple times
7 fn foo();
8
9 pub //~ ERROR the name `foo` is defined multiple times
10 static mut foo: u32;
11}
12
13fn main() {
14}
tests/ui/issues/issue-28472.stderr deleted-27
......@@ -1,27 +0,0 @@
1error[E0428]: the name `foo` is defined multiple times
2 --> $DIR/issue-28472.rs:6:3
3 |
4LL | fn foo();
5 | --------- previous definition of the value `foo` here
6LL |
7LL | / pub
8LL | | fn foo();
9 | |___________^ `foo` redefined here
10 |
11 = note: `foo` must be defined only once in the value namespace of this module
12
13error[E0428]: the name `foo` is defined multiple times
14 --> $DIR/issue-28472.rs:9:3
15 |
16LL | fn foo();
17 | --------- previous definition of the value `foo` here
18...
19LL | / pub
20LL | | static mut foo: u32;
21 | |______________________^ `foo` redefined here
22 |
23 = note: `foo` must be defined only once in the value namespace of this module
24
25error: aborting due to 2 previous errors
26
27For more information about this error, try `rustc --explain E0428`.
tests/ui/issues/issue-28498-must-work-ex1.rs deleted-18
......@@ -1,18 +0,0 @@
1//@ run-pass
2// Example taken from RFC 1238 text
3
4// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
5// #examples-of-code-that-must-continue-to-work
6
7use std::cell::Cell;
8
9struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
10
11fn main() {
12 let mut data = Vec::new();
13 data.push(Concrete(0, Cell::new(None)));
14 data.push(Concrete(0, Cell::new(None)));
15
16 data[0].1.set(Some(&data[1]));
17 data[1].1.set(Some(&data[0]));
18}
tests/ui/issues/issue-28498-must-work-ex2.rs deleted-20
......@@ -1,20 +0,0 @@
1//@ run-pass
2// Example taken from RFC 1238 text
3
4// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
5// #examples-of-code-that-must-continue-to-work
6
7use std::cell::Cell;
8
9struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
10
11struct Foo<T> { data: Vec<T> }
12
13fn main() {
14 let mut foo = Foo { data: Vec::new() };
15 foo.data.push(Concrete(0, Cell::new(None)));
16 foo.data.push(Concrete(0, Cell::new(None)));
17
18 foo.data[0].1.set(Some(&foo.data[1]));
19 foo.data[1].1.set(Some(&foo.data[0]));
20}
tests/ui/issues/issue-28498-ugeh-ex1.rs deleted-27
......@@ -1,27 +0,0 @@
1//@ run-pass
2
3// Example taken from RFC 1238 text
4
5// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
6// #example-of-the-unguarded-escape-hatch
7
8#![feature(dropck_eyepatch)]
9use std::cell::Cell;
10
11struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
12
13struct Foo<T> { data: Vec<T> }
14
15// Below is the UGEH attribute
16unsafe impl<#[may_dangle] T> Drop for Foo<T> {
17 fn drop(&mut self) { }
18}
19
20fn main() {
21 let mut foo = Foo { data: Vec::new() };
22 foo.data.push(Concrete(0, Cell::new(None)));
23 foo.data.push(Concrete(0, Cell::new(None)));
24
25 foo.data[0].1.set(Some(&foo.data[1]));
26 foo.data[1].1.set(Some(&foo.data[0]));
27}
tests/ui/issues/issue-28550.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2struct A<F: FnOnce()->T,T>(F::Output);
3struct B<F: FnOnce()->T,T>(A<F,T>);
4
5// Removing Option causes it to compile.
6fn foo<T,F: FnOnce()->T>(f: F) -> Option<B<F,T>> {
7 Some(B(A(f())))
8}
9
10fn main() {
11 let v = (|| foo(||4))();
12 match v {
13 Some(B(A(4))) => {},
14 _ => unreachable!()
15 }
16}
tests/ui/issues/issue-28600.rs deleted-15
......@@ -1,15 +0,0 @@
1//@ build-pass
2// #28600 ICE: pub extern fn with parameter type &str inside struct impl
3
4struct Test;
5
6impl Test {
7 #[allow(dead_code)]
8 #[allow(unused_variables)]
9 #[allow(improper_ctypes_definitions)]
10 pub extern "C" fn test(val: &str) {
11
12 }
13}
14
15fn main() {}
tests/ui/issues/issue-28776.rs deleted-6
......@@ -1,6 +0,0 @@
1use std::ptr;
2
3fn main() {
4 (&ptr::write)(1 as *mut _, 42);
5 //~^ ERROR E0133
6}
tests/ui/issues/issue-28776.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block
2 --> $DIR/issue-28776.rs:4:5
3 |
4LL | (&ptr::write)(1 as *mut _, 42);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
6 |
7 = note: consult the function's documentation for information on how to avoid undefined behavior
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0133`.
tests/ui/issues/issue-28828.rs deleted-18
......@@ -1,18 +0,0 @@
1//@ run-pass
2pub trait Foo {
3 type Out;
4}
5
6impl Foo for () {
7 type Out = bool;
8}
9
10fn main() {
11 type Bool = <() as Foo>::Out;
12
13 let x: Bool = true;
14 assert!(x);
15
16 let y: Option<Bool> = None;
17 assert_eq!(y, None);
18}
tests/ui/issues/issue-28936.rs deleted-27
......@@ -1,27 +0,0 @@
1//@ check-pass
2pub type Session = i32;
3pub struct StreamParser<'a, T> {
4 _tokens: T,
5 _session: &'a mut Session,
6}
7
8impl<'a, T> StreamParser<'a, T> {
9 pub fn thing(&mut self) -> bool { true }
10}
11
12pub fn parse_stream<T: Iterator<Item=i32>, U, F>(
13 _session: &mut Session, _tokens: T, _f: F) -> U
14 where F: Fn(&mut StreamParser<T>) -> U { panic!(); }
15
16pub fn thing(session: &mut Session) {
17 let mut stream = vec![1, 2, 3].into_iter();
18
19 let _b = parse_stream(session,
20 stream.by_ref(),
21 // replacing the above with the following fixes it
22 //&mut stream,
23 |p| p.thing());
24
25}
26
27fn main() {}
tests/ui/issues/issue-28999.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ check-pass
2pub struct Xyz<'a, V> {
3 pub v: (V, &'a u32),
4}
5
6pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool
7 where V: PartialEq {
8 this.v == other.v
9}
10
11fn main() {}
tests/ui/issues/issue-41974.rs deleted-14
......@@ -1,14 +0,0 @@
1#[derive(Copy, Clone)]
2struct Flags;
3
4trait A {
5}
6
7impl<T> Drop for T where T: A {
8 //~^ ERROR E0120
9 //~| ERROR E0210
10 fn drop(&mut self) {
11 }
12}
13
14fn main() {}
tests/ui/issues/issue-41974.stderr deleted-19
......@@ -1,19 +0,0 @@
1error[E0210]: type parameter `T` must be used as an argument to some local type (e.g., `MyStruct<T>`)
2 --> $DIR/issue-41974.rs:7:6
3 |
4LL | impl<T> Drop for T where T: A {
5 | ^ uncovered type parameter
6 |
7 = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
8 = note: only traits defined in the current crate can be implemented for a type parameter
9
10error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
11 --> $DIR/issue-41974.rs:7:18
12 |
13LL | impl<T> Drop for T where T: A {
14 | ^ must be a struct, enum, or union in the current crate
15
16error: aborting due to 2 previous errors
17
18Some errors have detailed explanations: E0120, E0210.
19For more information about an error, try `rustc --explain E0120`.
tests/ui/issues/issue-4252.rs deleted-33
......@@ -1,33 +0,0 @@
1//@ run-pass
2trait X {
3 fn call<T: std::fmt::Debug>(&self, x: &T);
4 fn default_method<T: std::fmt::Debug>(&self, x: &T) {
5 println!("X::default_method {:?}", x);
6 }
7}
8
9#[derive(Debug)]
10struct Y(#[allow(dead_code)] isize);
11
12#[derive(Debug)]
13struct Z<T: X+std::fmt::Debug> {
14 x: T
15}
16
17impl X for Y {
18 fn call<T: std::fmt::Debug>(&self, x: &T) {
19 println!("X::call {:?} {:?}", self, x);
20 }
21}
22
23impl<T: X + std::fmt::Debug> Drop for Z<T> {
24 fn drop(&mut self) {
25 // These statements used to cause an ICE.
26 self.x.call(self);
27 self.x.default_method(self);
28 }
29}
30
31pub fn main() {
32 let _z = Z {x: Y(42)};
33}
tests/ui/issues/issue-48132.rs deleted-31
......@@ -1,31 +0,0 @@
1// Regression test for #48132. This was failing due to problems around
2// the projection caching and dropck type enumeration.
3
4//@ run-pass
5
6#![allow(dead_code)]
7
8struct Inner<I, V> {
9 iterator: I,
10 item: V,
11}
12
13struct Outer<I: Iterator> {
14 inner: Inner<I, I::Item>,
15}
16
17fn outer<I>(iterator: I) -> Outer<I>
18where I: Iterator,
19 I::Item: Default,
20{
21 Outer {
22 inner: Inner {
23 iterator: iterator,
24 item: Default::default(),
25 }
26 }
27}
28
29fn main() {
30 outer(std::iter::once(&1).cloned());
31}
tests/ui/issues/issue-50781.rs deleted-18
......@@ -1,18 +0,0 @@
1trait Trait {}
2
3trait X {
4 fn foo(&self) where Self: Trait;
5}
6
7impl X for () {
8 fn foo(&self) {}
9}
10
11impl Trait for dyn X {}
12//~^ ERROR the trait `X` is not dyn compatible
13
14pub fn main() {
15 // Check that this does not segfault.
16 <dyn X as X>::foo(&());
17 //~^ ERROR the trait `X` is not dyn compatible
18}
tests/ui/issues/issue-50781.stderr deleted-37
......@@ -1,37 +0,0 @@
1error[E0038]: the trait `X` is not dyn compatible
2 --> $DIR/issue-50781.rs:11:16
3 |
4LL | impl Trait for dyn X {}
5 | ^^^^^ `X` is not dyn compatible
6 |
7note: for a trait to be dyn compatible it needs to allow building a vtable
8 for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
9 --> $DIR/issue-50781.rs:4:8
10 |
11LL | trait X {
12 | - this trait is not dyn compatible...
13LL | fn foo(&self) where Self: Trait;
14 | ^^^ ...because method `foo` references the `Self` type in its `where` clause
15 = help: consider moving `foo` to another trait
16 = help: only type `()` implements `X`; consider using it directly instead.
17
18error[E0038]: the trait `X` is not dyn compatible
19 --> $DIR/issue-50781.rs:16:10
20 |
21LL | <dyn X as X>::foo(&());
22 | ^ `X` is not dyn compatible
23 |
24note: for a trait to be dyn compatible it needs to allow building a vtable
25 for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
26 --> $DIR/issue-50781.rs:4:8
27 |
28LL | trait X {
29 | - this trait is not dyn compatible...
30LL | fn foo(&self) where Self: Trait;
31 | ^^^ ...because method `foo` references the `Self` type in its `where` clause
32 = help: consider moving `foo` to another trait
33 = help: only type `()` implements `X`; consider using it directly instead.
34
35error: aborting due to 2 previous errors
36
37For more information about this error, try `rustc --explain E0038`.
tests/ui/lifetimes/field-borrow-lifetime-inference.rs created+14
......@@ -0,0 +1,14 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28999>.
2//! `this.v` was not constrained and inferred `'a`.
3//@ check-pass
4
5pub struct Xyz<'a, V> {
6 pub v: (V, &'a u32),
7}
8
9pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool
10 where V: PartialEq {
11 this.v == other.v
12}
13
14fn main() {}
tests/ui/lifetimes/lifetime-errors/trait-method-return-lifetime-mismatch.rs created+18
......@@ -0,0 +1,18 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27942>.
2//! Test internal compiler structs do not leak into error message.
3//@ dont-require-annotations: NOTE
4
5pub trait Resources<'a> {}
6
7pub trait Buffer<'a, R: Resources<'a>> {
8
9 fn select(&self) -> BufferViewHandle<R>;
10 //~^ ERROR mismatched types
11 //~| NOTE lifetime mismatch
12 //~| ERROR mismatched types
13 //~| NOTE lifetime mismatch
14}
15
16pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R);
17
18fn main() {}
tests/ui/lifetimes/lifetime-errors/trait-method-return-lifetime-mismatch.stderr created+41
......@@ -0,0 +1,41 @@
1error[E0308]: mismatched types
2 --> $DIR/trait-method-return-lifetime-mismatch.rs:9:25
3 |
4LL | fn select(&self) -> BufferViewHandle<R>;
5 | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
6 |
7 = note: expected trait `Resources<'_>`
8 found trait `Resources<'a>`
9note: the lifetime `'a` as defined here...
10 --> $DIR/trait-method-return-lifetime-mismatch.rs:7:18
11 |
12LL | pub trait Buffer<'a, R: Resources<'a>> {
13 | ^^
14note: ...does not necessarily outlive the anonymous lifetime defined here
15 --> $DIR/trait-method-return-lifetime-mismatch.rs:9:15
16 |
17LL | fn select(&self) -> BufferViewHandle<R>;
18 | ^^^^^
19
20error[E0308]: mismatched types
21 --> $DIR/trait-method-return-lifetime-mismatch.rs:9:25
22 |
23LL | fn select(&self) -> BufferViewHandle<R>;
24 | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
25 |
26 = note: expected trait `Resources<'_>`
27 found trait `Resources<'a>`
28note: the anonymous lifetime defined here...
29 --> $DIR/trait-method-return-lifetime-mismatch.rs:9:15
30 |
31LL | fn select(&self) -> BufferViewHandle<R>;
32 | ^^^^^
33note: ...does not necessarily outlive the lifetime `'a` as defined here
34 --> $DIR/trait-method-return-lifetime-mismatch.rs:7:18
35 |
36LL | pub trait Buffer<'a, R: Resources<'a>> {
37 | ^^
38
39error: aborting due to 2 previous errors
40
41For more information about this error, try `rustc --explain E0308`.
tests/ui/lint/auxiliary/lint_stability.rs+6
......@@ -1,5 +1,6 @@
11#![crate_name="lint_stability"]
22#![crate_type = "lib"]
3#![feature(extern_types)]
34#![feature(staged_api)]
45#![feature(associated_type_defaults)]
56#![stable(feature = "lint_stability", since = "1.0.0")]
......@@ -186,3 +187,8 @@ macro_rules! macro_test_arg {
186187macro_rules! macro_test_arg_nested {
187188 ($func:ident) => (macro_test_arg!($func()));
188189}
190
191extern "C" {
192 #[unstable(feature = "unstable_test_feature", issue = "none")]
193 pub type UnstableForeignType;
194}
tests/ui/lint/lint-stability.rs+4-1
......@@ -6,7 +6,7 @@
66#![allow(deprecated)]
77#![allow(dead_code)]
88#![feature(staged_api)]
9
9#![feature(extern_types)]
1010#![stable(feature = "rust1", since = "1.0.0")]
1111
1212#[macro_use]
......@@ -18,6 +18,9 @@ mod cross_crate {
1818
1919 use lint_stability::*;
2020
21 fn test_foreign_type(_: &mut UnstableForeignType) { //~ ERROR use of unstable library feature
22 }
23
2124 fn test() {
2225 type Foo = MethodTester;
2326 let foo = MethodTester;
tests/ui/lint/lint-stability.stderr+52-43
......@@ -8,7 +8,16 @@ LL | extern crate stability_cfg2;
88 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
99
1010error[E0658]: use of unstable library feature `unstable_test_feature`
11 --> $DIR/lint-stability.rs:45:9
11 --> $DIR/lint-stability.rs:21:34
12 |
13LL | fn test_foreign_type(_: &mut UnstableForeignType) {
14 | ^^^^^^^^^^^^^^^^^^^
15 |
16 = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
17 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
18
19error[E0658]: use of unstable library feature `unstable_test_feature`
20 --> $DIR/lint-stability.rs:48:9
1221 |
1322LL | deprecated_unstable();
1423 | ^^^^^^^^^^^^^^^^^^^
......@@ -17,7 +26,7 @@ LL | deprecated_unstable();
1726 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1827
1928error[E0658]: use of unstable library feature `unstable_test_feature`
20 --> $DIR/lint-stability.rs:47:9
29 --> $DIR/lint-stability.rs:50:9
2130 |
2231LL | Trait::trait_deprecated_unstable(&foo);
2332 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -26,7 +35,7 @@ LL | Trait::trait_deprecated_unstable(&foo);
2635 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2736
2837error[E0658]: use of unstable library feature `unstable_test_feature`
29 --> $DIR/lint-stability.rs:49:9
38 --> $DIR/lint-stability.rs:52:9
3039 |
3140LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
3241 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -35,7 +44,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
3544 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3645
3746error[E0658]: use of unstable library feature `unstable_test_feature`
38 --> $DIR/lint-stability.rs:52:9
47 --> $DIR/lint-stability.rs:55:9
3948 |
4049LL | deprecated_unstable_text();
4150 | ^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -44,7 +53,7 @@ LL | deprecated_unstable_text();
4453 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4554
4655error[E0658]: use of unstable library feature `unstable_test_feature`
47 --> $DIR/lint-stability.rs:54:9
56 --> $DIR/lint-stability.rs:57:9
4857 |
4958LL | Trait::trait_deprecated_unstable_text(&foo);
5059 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -53,7 +62,7 @@ LL | Trait::trait_deprecated_unstable_text(&foo);
5362 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
5463
5564error[E0658]: use of unstable library feature `unstable_test_feature`
56 --> $DIR/lint-stability.rs:56:9
65 --> $DIR/lint-stability.rs:59:9
5766 |
5867LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
5968 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -62,7 +71,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
6271 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
6372
6473error[E0658]: use of unstable library feature `unstable_test_feature`
65 --> $DIR/lint-stability.rs:59:9
74 --> $DIR/lint-stability.rs:62:9
6675 |
6776LL | unstable();
6877 | ^^^^^^^^
......@@ -71,7 +80,7 @@ LL | unstable();
7180 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
7281
7382error[E0658]: use of unstable library feature `unstable_test_feature`
74 --> $DIR/lint-stability.rs:60:9
83 --> $DIR/lint-stability.rs:63:9
7584 |
7685LL | Trait::trait_unstable(&foo);
7786 | ^^^^^^^^^^^^^^^^^^^^^
......@@ -80,7 +89,7 @@ LL | Trait::trait_unstable(&foo);
8089 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
8190
8291error[E0658]: use of unstable library feature `unstable_test_feature`
83 --> $DIR/lint-stability.rs:61:9
92 --> $DIR/lint-stability.rs:64:9
8493 |
8594LL | <Foo as Trait>::trait_unstable(&foo);
8695 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -89,7 +98,7 @@ LL | <Foo as Trait>::trait_unstable(&foo);
8998 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9099
91100error[E0658]: use of unstable library feature `unstable_test_feature`: text
92 --> $DIR/lint-stability.rs:63:9
101 --> $DIR/lint-stability.rs:66:9
93102 |
94103LL | unstable_text();
95104 | ^^^^^^^^^^^^^
......@@ -98,7 +107,7 @@ LL | unstable_text();
98107 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
99108
100109error[E0658]: use of unstable library feature `unstable_test_feature`: text
101 --> $DIR/lint-stability.rs:65:9
110 --> $DIR/lint-stability.rs:68:9
102111 |
103112LL | Trait::trait_unstable_text(&foo);
104113 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -107,7 +116,7 @@ LL | Trait::trait_unstable_text(&foo);
107116 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
108117
109118error[E0658]: use of unstable library feature `unstable_test_feature`: text
110 --> $DIR/lint-stability.rs:67:9
119 --> $DIR/lint-stability.rs:70:9
111120 |
112121LL | <Foo as Trait>::trait_unstable_text(&foo);
113122 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -116,7 +125,7 @@ LL | <Foo as Trait>::trait_unstable_text(&foo);
116125 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
117126
118127error[E0658]: use of unstable library feature `unstable_test_feature`
119 --> $DIR/lint-stability.rs:99:17
128 --> $DIR/lint-stability.rs:102:17
120129 |
121130LL | let _ = DeprecatedUnstableStruct {
122131 | ^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -125,7 +134,7 @@ LL | let _ = DeprecatedUnstableStruct {
125134 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
126135
127136error[E0658]: use of unstable library feature `unstable_test_feature`
128 --> $DIR/lint-stability.rs:103:17
137 --> $DIR/lint-stability.rs:106:17
129138 |
130139LL | let _ = UnstableStruct { i: 0 };
131140 | ^^^^^^^^^^^^^^
......@@ -134,7 +143,7 @@ LL | let _ = UnstableStruct { i: 0 };
134143 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
135144
136145error[E0658]: use of unstable library feature `unstable_test_feature`
137 --> $DIR/lint-stability.rs:107:17
146 --> $DIR/lint-stability.rs:110:17
138147 |
139148LL | let _ = DeprecatedUnstableUnitStruct;
140149 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -143,7 +152,7 @@ LL | let _ = DeprecatedUnstableUnitStruct;
143152 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
144153
145154error[E0658]: use of unstable library feature `unstable_test_feature`
146 --> $DIR/lint-stability.rs:109:17
155 --> $DIR/lint-stability.rs:112:17
147156 |
148157LL | let _ = UnstableUnitStruct;
149158 | ^^^^^^^^^^^^^^^^^^
......@@ -152,7 +161,7 @@ LL | let _ = UnstableUnitStruct;
152161 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
153162
154163error[E0658]: use of unstable library feature `unstable_test_feature`
155 --> $DIR/lint-stability.rs:113:17
164 --> $DIR/lint-stability.rs:116:17
156165 |
157166LL | let _ = Enum::DeprecatedUnstableVariant;
158167 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -161,7 +170,7 @@ LL | let _ = Enum::DeprecatedUnstableVariant;
161170 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
162171
163172error[E0658]: use of unstable library feature `unstable_test_feature`
164 --> $DIR/lint-stability.rs:115:17
173 --> $DIR/lint-stability.rs:118:17
165174 |
166175LL | let _ = Enum::UnstableVariant;
167176 | ^^^^^^^^^^^^^^^^^^^^^
......@@ -170,7 +179,7 @@ LL | let _ = Enum::UnstableVariant;
170179 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
171180
172181error[E0658]: use of unstable library feature `unstable_test_feature`
173 --> $DIR/lint-stability.rs:119:17
182 --> $DIR/lint-stability.rs:122:17
174183 |
175184LL | let _ = DeprecatedUnstableTupleStruct (1);
176185 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -179,7 +188,7 @@ LL | let _ = DeprecatedUnstableTupleStruct (1);
179188 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
180189
181190error[E0658]: use of unstable library feature `unstable_test_feature`
182 --> $DIR/lint-stability.rs:121:17
191 --> $DIR/lint-stability.rs:124:17
183192 |
184193LL | let _ = UnstableTupleStruct (1);
185194 | ^^^^^^^^^^^^^^^^^^^
......@@ -188,7 +197,7 @@ LL | let _ = UnstableTupleStruct (1);
188197 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
189198
190199error[E0658]: use of unstable library feature `unstable_test_feature`
191 --> $DIR/lint-stability.rs:130:25
200 --> $DIR/lint-stability.rs:133:25
192201 |
193202LL | macro_test_arg!(deprecated_unstable_text());
194203 | ^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -197,7 +206,7 @@ LL | macro_test_arg!(deprecated_unstable_text());
197206 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
198207
199208error[E0658]: use of unstable library feature `unstable_test_feature`
200 --> $DIR/lint-stability.rs:144:9
209 --> $DIR/lint-stability.rs:147:9
201210 |
202211LL | Trait::trait_deprecated_unstable(&foo);
203212 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -206,7 +215,7 @@ LL | Trait::trait_deprecated_unstable(&foo);
206215 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
207216
208217error[E0658]: use of unstable library feature `unstable_test_feature`
209 --> $DIR/lint-stability.rs:146:9
218 --> $DIR/lint-stability.rs:149:9
210219 |
211220LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
212221 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -215,7 +224,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable(&foo);
215224 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
216225
217226error[E0658]: use of unstable library feature `unstable_test_feature`
218 --> $DIR/lint-stability.rs:148:9
227 --> $DIR/lint-stability.rs:151:9
219228 |
220229LL | Trait::trait_deprecated_unstable_text(&foo);
221230 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -224,7 +233,7 @@ LL | Trait::trait_deprecated_unstable_text(&foo);
224233 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
225234
226235error[E0658]: use of unstable library feature `unstable_test_feature`
227 --> $DIR/lint-stability.rs:150:9
236 --> $DIR/lint-stability.rs:153:9
228237 |
229238LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
230239 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -233,7 +242,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo);
233242 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
234243
235244error[E0658]: use of unstable library feature `unstable_test_feature`
236 --> $DIR/lint-stability.rs:152:9
245 --> $DIR/lint-stability.rs:155:9
237246 |
238247LL | Trait::trait_unstable(&foo);
239248 | ^^^^^^^^^^^^^^^^^^^^^
......@@ -242,7 +251,7 @@ LL | Trait::trait_unstable(&foo);
242251 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
243252
244253error[E0658]: use of unstable library feature `unstable_test_feature`
245 --> $DIR/lint-stability.rs:153:9
254 --> $DIR/lint-stability.rs:156:9
246255 |
247256LL | <Foo as Trait>::trait_unstable(&foo);
248257 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -251,7 +260,7 @@ LL | <Foo as Trait>::trait_unstable(&foo);
251260 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
252261
253262error[E0658]: use of unstable library feature `unstable_test_feature`: text
254 --> $DIR/lint-stability.rs:154:9
263 --> $DIR/lint-stability.rs:157:9
255264 |
256265LL | Trait::trait_unstable_text(&foo);
257266 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -260,7 +269,7 @@ LL | Trait::trait_unstable_text(&foo);
260269 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
261270
262271error[E0658]: use of unstable library feature `unstable_test_feature`: text
263 --> $DIR/lint-stability.rs:156:9
272 --> $DIR/lint-stability.rs:159:9
264273 |
265274LL | <Foo as Trait>::trait_unstable_text(&foo);
266275 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -269,7 +278,7 @@ LL | <Foo as Trait>::trait_unstable_text(&foo);
269278 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
270279
271280error[E0658]: use of unstable library feature `unstable_test_feature`
272 --> $DIR/lint-stability.rs:172:10
281 --> $DIR/lint-stability.rs:175:10
273282 |
274283LL | impl UnstableTrait for S { }
275284 | ^^^^^^^^^^^^^
......@@ -278,7 +287,7 @@ LL | impl UnstableTrait for S { }
278287 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
279288
280289error[E0658]: use of unstable library feature `unstable_test_feature`
281 --> $DIR/lint-stability.rs:174:24
290 --> $DIR/lint-stability.rs:177:24
282291 |
283292LL | trait LocalTrait : UnstableTrait { }
284293 | ^^^^^^^^^^^^^
......@@ -287,7 +296,7 @@ LL | trait LocalTrait : UnstableTrait { }
287296 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
288297
289298error[E0658]: use of unstable library feature `unstable_test_feature`
290 --> $DIR/lint-stability.rs:179:9
299 --> $DIR/lint-stability.rs:182:9
291300 |
292301LL | fn trait_unstable(&self) {}
293302 | ^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -296,7 +305,7 @@ LL | fn trait_unstable(&self) {}
296305 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
297306
298307error[E0658]: use of unstable library feature `unstable_test_feature`
299 --> $DIR/lint-stability.rs:184:5
308 --> $DIR/lint-stability.rs:187:5
300309 |
301310LL | extern crate inherited_stability;
302311 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -305,7 +314,7 @@ LL | extern crate inherited_stability;
305314 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
306315
307316error[E0658]: use of unstable library feature `unstable_test_feature`
308 --> $DIR/lint-stability.rs:185:9
317 --> $DIR/lint-stability.rs:188:9
309318 |
310319LL | use self::inherited_stability::*;
311320 | ^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -314,7 +323,7 @@ LL | use self::inherited_stability::*;
314323 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
315324
316325error[E0658]: use of unstable library feature `unstable_test_feature`
317 --> $DIR/lint-stability.rs:188:9
326 --> $DIR/lint-stability.rs:191:9
318327 |
319328LL | unstable();
320329 | ^^^^^^^^
......@@ -323,7 +332,7 @@ LL | unstable();
323332 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
324333
325334error[E0658]: use of unstable library feature `unstable_test_feature`
326 --> $DIR/lint-stability.rs:191:9
335 --> $DIR/lint-stability.rs:194:9
327336 |
328337LL | stable_mod::unstable();
329338 | ^^^^^^^^^^^^^^^^^^^^
......@@ -332,7 +341,7 @@ LL | stable_mod::unstable();
332341 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
333342
334343error[E0658]: use of unstable library feature `unstable_test_feature`
335 --> $DIR/lint-stability.rs:194:9
344 --> $DIR/lint-stability.rs:197:9
336345 |
337346LL | unstable_mod::deprecated();
338347 | ^^^^^^^^^^^^
......@@ -341,7 +350,7 @@ LL | unstable_mod::deprecated();
341350 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
342351
343352error[E0658]: use of unstable library feature `unstable_test_feature`
344 --> $DIR/lint-stability.rs:195:9
353 --> $DIR/lint-stability.rs:198:9
345354 |
346355LL | unstable_mod::unstable();
347356 | ^^^^^^^^^^^^^^^^^^^^^^
......@@ -350,7 +359,7 @@ LL | unstable_mod::unstable();
350359 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
351360
352361error[E0658]: use of unstable library feature `unstable_test_feature`
353 --> $DIR/lint-stability.rs:197:17
362 --> $DIR/lint-stability.rs:200:17
354363 |
355364LL | let _ = Unstable::UnstableVariant;
356365 | ^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -359,7 +368,7 @@ LL | let _ = Unstable::UnstableVariant;
359368 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
360369
361370error[E0658]: use of unstable library feature `unstable_test_feature`
362 --> $DIR/lint-stability.rs:198:17
371 --> $DIR/lint-stability.rs:201:17
363372 |
364373LL | let _ = Unstable::StableVariant;
365374 | ^^^^^^^^
......@@ -368,7 +377,7 @@ LL | let _ = Unstable::StableVariant;
368377 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
369378
370379error[E0658]: use of unstable library feature `unstable_test_feature`
371 --> $DIR/lint-stability.rs:88:48
380 --> $DIR/lint-stability.rs:91:48
372381 |
373382LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
374383 | ^^^^^^^^^^^^^^^
......@@ -377,7 +386,7 @@ LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
377386 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
378387
379388error[E0658]: use of unstable library feature `unstable_test_feature`
380 --> $DIR/lint-stability.rs:92:13
389 --> $DIR/lint-stability.rs:95:13
381390 |
382391LL | TypeUnstable = u8,
383392 | ^^^^^^^^^^^^^^^^^
......@@ -385,6 +394,6 @@ LL | TypeUnstable = u8,
385394 = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
386395 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
387396
388error: aborting due to 43 previous errors
397error: aborting due to 44 previous errors
389398
390399For more information about this error, try `rustc --explain E0658`.
tests/ui/macros/assert-with-custom-message.rs created+8
......@@ -0,0 +1,8 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/2761>.
2//@ run-fail
3//@ error-pattern:custom message
4//@ needs-subprocess
5
6fn main() {
7 assert!(false, "custom message");
8}
tests/ui/methods/supertrait-shadowing/assoc-const.rs deleted-22
......@@ -1,22 +0,0 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![allow(dead_code)]
5
6trait A {
7 const CONST: i32;
8}
9impl<T> A for T {
10 const CONST: i32 = 1;
11}
12
13trait B: A {
14 const CONST: i32;
15}
16impl<T> B for T {
17 const CONST: i32 = 2;
18}
19
20fn main() {
21 assert_eq!(i32::CONST, 2)
22}
tests/ui/methods/supertrait-shadowing/auxiliary/shadowed_stability.rs deleted-22
......@@ -1,22 +0,0 @@
1#![feature(staged_api)]
2#![stable(feature = "main", since = "1.0.0")]
3
4#[stable(feature = "main", since = "1.0.0")]
5pub trait A {
6 #[stable(feature = "main", since = "1.0.0")]
7 fn hello(&self) -> &'static str {
8 "A"
9 }
10}
11#[stable(feature = "main", since = "1.0.0")]
12impl<T> A for T {}
13
14#[stable(feature = "main", since = "1.0.0")]
15pub trait B: A {
16 #[unstable(feature = "downstream", issue = "none")]
17 fn hello(&self) -> &'static str {
18 "B"
19 }
20}
21#[stable(feature = "main", since = "1.0.0")]
22impl<T> B for T {}
tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs deleted-33
......@@ -1,33 +0,0 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![warn(resolving_to_items_shadowing_supertrait_items)]
5#![warn(shadowing_supertrait_items)]
6#![allow(dead_code)]
7
8trait A {
9 fn hello(&self) -> &'static str {
10 "A"
11 }
12}
13impl<T> A for T {}
14
15trait B {
16 fn hello(&self) -> &'static str {
17 "B"
18 }
19}
20impl<T> B for T {}
21
22trait C: A + B {
23 fn hello(&self) -> &'static str {
24 //~^ WARN trait item `hello` from `C` shadows identically named item
25 "C"
26 }
27}
28impl<T> C for T {}
29
30fn main() {
31 assert_eq!(().hello(), "C");
32 //~^ WARN trait item `hello` from `C` shadows identically named item from supertrait
33}
tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr deleted-47
......@@ -1,47 +0,0 @@
1warning: trait item `hello` from `C` shadows identically named item from supertrait
2 --> $DIR/common-ancestor-2.rs:23:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: items from several supertraits are shadowed: `B` and `A`
8 --> $DIR/common-ancestor-2.rs:9:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12...
13LL | fn hello(&self) -> &'static str {
14 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15note: the lint level is defined here
16 --> $DIR/common-ancestor-2.rs:5:9
17 |
18LL | #![warn(shadowing_supertrait_items)]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
20
21warning: trait item `hello` from `C` shadows identically named item from supertrait
22 --> $DIR/common-ancestor-2.rs:31:19
23 |
24LL | assert_eq!(().hello(), "C");
25 | ^^^^^
26 |
27note: item from `C` shadows a supertrait item
28 --> $DIR/common-ancestor-2.rs:23:5
29 |
30LL | fn hello(&self) -> &'static str {
31 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32note: items from several supertraits are shadowed: `A` and `B`
33 --> $DIR/common-ancestor-2.rs:9:5
34 |
35LL | fn hello(&self) -> &'static str {
36 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37...
38LL | fn hello(&self) -> &'static str {
39 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40note: the lint level is defined here
41 --> $DIR/common-ancestor-2.rs:4:9
42 |
43LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
45
46warning: 2 warnings emitted
47
tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs deleted-43
......@@ -1,43 +0,0 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![warn(resolving_to_items_shadowing_supertrait_items)]
5#![warn(shadowing_supertrait_items)]
6#![allow(dead_code)]
7
8trait A {
9 fn hello(&self) -> &'static str {
10 "A"
11 }
12}
13impl<T> A for T {}
14
15trait B {
16 fn hello(&self) -> &'static str {
17 "B"
18 }
19}
20impl<T> B for T {}
21
22trait C: A + B {
23 fn hello(&self) -> &'static str {
24 //~^ WARN trait item `hello` from `C` shadows identically named item
25 "C"
26 }
27}
28impl<T> C for T {}
29
30// `D` extends `C` which extends `B` and `A`
31
32trait D: C {
33 fn hello(&self) -> &'static str {
34 //~^ WARN trait item `hello` from `D` shadows identically named item
35 "D"
36 }
37}
38impl<T> D for T {}
39
40fn main() {
41 assert_eq!(().hello(), "D");
42 //~^ WARN trait item `hello` from `D` shadows identically named item from supertrait
43}
tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr deleted-68
......@@ -1,68 +0,0 @@
1warning: trait item `hello` from `C` shadows identically named item from supertrait
2 --> $DIR/common-ancestor-3.rs:23:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: items from several supertraits are shadowed: `B` and `A`
8 --> $DIR/common-ancestor-3.rs:9:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12...
13LL | fn hello(&self) -> &'static str {
14 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15note: the lint level is defined here
16 --> $DIR/common-ancestor-3.rs:5:9
17 |
18LL | #![warn(shadowing_supertrait_items)]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
20
21warning: trait item `hello` from `D` shadows identically named item from supertrait
22 --> $DIR/common-ancestor-3.rs:33:5
23 |
24LL | fn hello(&self) -> &'static str {
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27note: items from several supertraits are shadowed: `C`, `B`, and `A`
28 --> $DIR/common-ancestor-3.rs:9:5
29 |
30LL | fn hello(&self) -> &'static str {
31 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32...
33LL | fn hello(&self) -> &'static str {
34 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35...
36LL | fn hello(&self) -> &'static str {
37 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38
39warning: trait item `hello` from `D` shadows identically named item from supertrait
40 --> $DIR/common-ancestor-3.rs:41:19
41 |
42LL | assert_eq!(().hello(), "D");
43 | ^^^^^
44 |
45note: item from `D` shadows a supertrait item
46 --> $DIR/common-ancestor-3.rs:33:5
47 |
48LL | fn hello(&self) -> &'static str {
49 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50note: items from several supertraits are shadowed: `A`, `B`, and `C`
51 --> $DIR/common-ancestor-3.rs:9:5
52 |
53LL | fn hello(&self) -> &'static str {
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55...
56LL | fn hello(&self) -> &'static str {
57 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58...
59LL | fn hello(&self) -> &'static str {
60 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
61note: the lint level is defined here
62 --> $DIR/common-ancestor-3.rs:4:9
63 |
64LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
65 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
67warning: 3 warnings emitted
68
tests/ui/methods/supertrait-shadowing/common-ancestor.rs deleted-26
......@@ -1,26 +0,0 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![warn(resolving_to_items_shadowing_supertrait_items)]
5#![warn(shadowing_supertrait_items)]
6#![allow(dead_code)]
7
8trait A {
9 fn hello(&self) -> &'static str {
10 "A"
11 }
12}
13impl<T> A for T {}
14
15trait B: A {
16 fn hello(&self) -> &'static str {
17 //~^ WARN trait item `hello` from `B` shadows identically named item
18 "B"
19 }
20}
21impl<T> B for T {}
22
23fn main() {
24 assert_eq!(().hello(), "B");
25 //~^ WARN trait item `hello` from `B` shadows identically named item from supertrait
26}
tests/ui/methods/supertrait-shadowing/common-ancestor.stderr deleted-41
......@@ -1,41 +0,0 @@
1warning: trait item `hello` from `B` shadows identically named item from supertrait
2 --> $DIR/common-ancestor.rs:16:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: item from `A` is shadowed by a subtrait item
8 --> $DIR/common-ancestor.rs:9:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/common-ancestor.rs:5:9
14 |
15LL | #![warn(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18warning: trait item `hello` from `B` shadows identically named item from supertrait
19 --> $DIR/common-ancestor.rs:24:19
20 |
21LL | assert_eq!(().hello(), "B");
22 | ^^^^^
23 |
24note: item from `B` shadows a supertrait item
25 --> $DIR/common-ancestor.rs:16:5
26 |
27LL | fn hello(&self) -> &'static str {
28 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29note: item from `A` is shadowed by a subtrait item
30 --> $DIR/common-ancestor.rs:9:5
31 |
32LL | fn hello(&self) -> &'static str {
33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34note: the lint level is defined here
35 --> $DIR/common-ancestor.rs:4:9
36 |
37LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40warning: 2 warnings emitted
41
tests/ui/methods/supertrait-shadowing/definition-site.rs deleted-18
......@@ -1,18 +0,0 @@
1#![feature(supertrait_item_shadowing)]
2#![deny(shadowing_supertrait_items)]
3
4trait SuperSuper {
5 fn method();
6}
7
8trait Super: SuperSuper {
9 fn method();
10 //~^ ERROR trait item `method` from `Super` shadows identically named item
11}
12
13trait Sub: Super {
14 fn method();
15 //~^ ERROR trait item `method` from `Sub` shadows identically named item
16}
17
18fn main() {}
tests/ui/methods/supertrait-shadowing/definition-site.stderr deleted-34
......@@ -1,34 +0,0 @@
1error: trait item `method` from `Super` shadows identically named item from supertrait
2 --> $DIR/definition-site.rs:9:5
3 |
4LL | fn method();
5 | ^^^^^^^^^^^^
6 |
7note: item from `SuperSuper` is shadowed by a subtrait item
8 --> $DIR/definition-site.rs:5:5
9 |
10LL | fn method();
11 | ^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/definition-site.rs:2:9
14 |
15LL | #![deny(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18error: trait item `method` from `Sub` shadows identically named item from supertrait
19 --> $DIR/definition-site.rs:14:5
20 |
21LL | fn method();
22 | ^^^^^^^^^^^^
23 |
24note: items from several supertraits are shadowed: `Super` and `SuperSuper`
25 --> $DIR/definition-site.rs:5:5
26 |
27LL | fn method();
28 | ^^^^^^^^^^^^
29...
30LL | fn method();
31 | ^^^^^^^^^^^^
32
33error: aborting due to 2 previous errors
34
tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.rs deleted-26
......@@ -1,26 +0,0 @@
1#![feature(supertrait_item_shadowing)]
2#![warn(resolving_to_items_shadowing_supertrait_items)]
3#![warn(shadowing_supertrait_items)]
4
5struct W<T>(T);
6
7trait Upstream {
8 fn hello(&self) {}
9}
10impl<T> Upstream for T {}
11
12trait Downstream: Upstream {
13 fn hello(&self) {}
14 //~^ WARN trait item `hello` from `Downstream` shadows identically named item
15}
16impl<T> Downstream for W<T> where T: Foo {}
17
18trait Foo {}
19
20fn main() {
21 let x = W(Default::default());
22 x.hello();
23 //~^ ERROR the trait bound `i32: Foo` is not satisfied
24 //~| WARN trait item `hello` from `Downstream` shadows identically named item from supertrait
25 let _: i32 = x.0;
26}
tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.stderr deleted-59
......@@ -1,59 +0,0 @@
1warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
2 --> $DIR/false-subtrait-after-inference.rs:13:5
3 |
4LL | fn hello(&self) {}
5 | ^^^^^^^^^^^^^^^
6 |
7note: item from `Upstream` is shadowed by a subtrait item
8 --> $DIR/false-subtrait-after-inference.rs:8:5
9 |
10LL | fn hello(&self) {}
11 | ^^^^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/false-subtrait-after-inference.rs:3:9
14 |
15LL | #![warn(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
19 --> $DIR/false-subtrait-after-inference.rs:22:7
20 |
21LL | x.hello();
22 | ^^^^^
23 |
24note: item from `Downstream` shadows a supertrait item
25 --> $DIR/false-subtrait-after-inference.rs:13:5
26 |
27LL | fn hello(&self) {}
28 | ^^^^^^^^^^^^^^^
29note: item from `Upstream` is shadowed by a subtrait item
30 --> $DIR/false-subtrait-after-inference.rs:8:5
31 |
32LL | fn hello(&self) {}
33 | ^^^^^^^^^^^^^^^
34note: the lint level is defined here
35 --> $DIR/false-subtrait-after-inference.rs:2:9
36 |
37LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40error[E0277]: the trait bound `i32: Foo` is not satisfied
41 --> $DIR/false-subtrait-after-inference.rs:22:7
42 |
43LL | x.hello();
44 | ^^^^^ the trait `Foo` is not implemented for `i32`
45 |
46help: this trait has no implementations, consider adding one
47 --> $DIR/false-subtrait-after-inference.rs:18:1
48 |
49LL | trait Foo {}
50 | ^^^^^^^^^
51note: required for `W<i32>` to implement `Downstream`
52 --> $DIR/false-subtrait-after-inference.rs:16:9
53 |
54LL | impl<T> Downstream for W<T> where T: Foo {}
55 | ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here
56
57error: aborting due to 1 previous error; 2 warnings emitted
58
59For more information about this error, try `rustc --explain E0277`.
tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.rs deleted-37
......@@ -1,37 +0,0 @@
1#![feature(supertrait_item_shadowing)]
2
3trait A {
4 fn hello(&self) -> &'static str {
5 "A"
6 }
7}
8impl<T> A for T {}
9
10trait B {
11 fn hello(&self) -> &'static str {
12 "B"
13 }
14}
15impl<T> B for T {}
16
17trait C: A + B {
18 fn hello(&self) -> &'static str {
19 "C"
20 }
21}
22impl<T> C for T {}
23
24// Since `D` is not a subtrait of `C`,
25// we have no obvious lower bound.
26
27trait D: B {
28 fn hello(&self) -> &'static str {
29 "D"
30 }
31}
32impl<T> D for T {}
33
34fn main() {
35 ().hello();
36 //~^ ERROR multiple applicable items in scope
37}
tests/ui/methods/supertrait-shadowing/no-common-ancestor-2.stderr deleted-50
......@@ -1,50 +0,0 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/no-common-ancestor-2.rs:35:8
3 |
4LL | ().hello();
5 | ^^^^^ multiple `hello` found
6 |
7note: candidate #1 is defined in an impl of the trait `A` for the type `T`
8 --> $DIR/no-common-ancestor-2.rs:4:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: candidate #2 is defined in an impl of the trait `B` for the type `T`
13 --> $DIR/no-common-ancestor-2.rs:11:5
14 |
15LL | fn hello(&self) -> &'static str {
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17note: candidate #3 is defined in an impl of the trait `C` for the type `T`
18 --> $DIR/no-common-ancestor-2.rs:18:5
19 |
20LL | fn hello(&self) -> &'static str {
21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22note: candidate #4 is defined in an impl of the trait `D` for the type `T`
23 --> $DIR/no-common-ancestor-2.rs:28:5
24 |
25LL | fn hello(&self) -> &'static str {
26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27help: disambiguate the method for candidate #1
28 |
29LL - ().hello();
30LL + A::hello(&());
31 |
32help: disambiguate the method for candidate #2
33 |
34LL - ().hello();
35LL + B::hello(&());
36 |
37help: disambiguate the method for candidate #3
38 |
39LL - ().hello();
40LL + C::hello(&());
41 |
42help: disambiguate the method for candidate #4
43 |
44LL - ().hello();
45LL + D::hello(&());
46 |
47
48error: aborting due to 1 previous error
49
50For more information about this error, try `rustc --explain E0034`.
tests/ui/methods/supertrait-shadowing/no-common-ancestor.rs deleted-20
......@@ -1,20 +0,0 @@
1#![feature(supertrait_item_shadowing)]
2
3trait A {
4 fn hello(&self) -> &'static str {
5 "A"
6 }
7}
8impl<T> A for T {}
9
10trait B {
11 fn hello(&self) -> &'static str {
12 "B"
13 }
14}
15impl<T> B for T {}
16
17fn main() {
18 ().hello();
19 //~^ ERROR multiple applicable items in scope
20}
tests/ui/methods/supertrait-shadowing/no-common-ancestor.stderr deleted-30
......@@ -1,30 +0,0 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/no-common-ancestor.rs:18:8
3 |
4LL | ().hello();
5 | ^^^^^ multiple `hello` found
6 |
7note: candidate #1 is defined in an impl of the trait `A` for the type `T`
8 --> $DIR/no-common-ancestor.rs:4:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: candidate #2 is defined in an impl of the trait `B` for the type `T`
13 --> $DIR/no-common-ancestor.rs:11:5
14 |
15LL | fn hello(&self) -> &'static str {
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17help: disambiguate the method for candidate #1
18 |
19LL - ().hello();
20LL + A::hello(&());
21 |
22help: disambiguate the method for candidate #2
23 |
24LL - ().hello();
25LL + B::hello(&());
26 |
27
28error: aborting due to 1 previous error
29
30For more information about this error, try `rustc --explain E0034`.
tests/ui/methods/supertrait-shadowing/out-of-scope.rs deleted-23
......@@ -1,23 +0,0 @@
1//@ run-pass
2
3#![allow(dead_code)]
4
5mod out_of_scope {
6 pub trait Subtrait: super::Supertrait {
7 fn hello(&self) -> &'static str {
8 "subtrait"
9 }
10 }
11 impl<T> Subtrait for T {}
12}
13
14trait Supertrait {
15 fn hello(&self) -> &'static str {
16 "supertrait"
17 }
18}
19impl<T> Supertrait for T {}
20
21fn main() {
22 assert_eq!(().hello(), "supertrait");
23}
tests/ui/methods/supertrait-shadowing/trivially-false-subtrait.rs deleted-29
......@@ -1,29 +0,0 @@
1//@ run-pass
2
3// Make sure we don't prefer a subtrait that we would've otherwise eliminated
4// in `consider_probe` during method probing.
5
6#![allow(dead_code)]
7
8struct W<T>(T);
9
10trait Upstream {
11 fn hello(&self) -> &'static str {
12 "upstream"
13 }
14}
15impl<T> Upstream for T {}
16
17trait Downstream: Upstream {
18 fn hello(&self) -> &'static str {
19 "downstream"
20 }
21}
22impl<T> Downstream for W<T> where T: Foo {}
23
24trait Foo {}
25
26fn main() {
27 let x = W(1i32);
28 assert_eq!(x.hello(), "upstream");
29}
tests/ui/methods/supertrait-shadowing/type-dependent.rs deleted-28
......@@ -1,28 +0,0 @@
1//@ run-pass
2
3// Makes sure we can shadow with type-dependent method syntax.
4
5#![feature(supertrait_item_shadowing)]
6#![allow(dead_code)]
7
8trait A {
9 fn hello() -> &'static str {
10 "A"
11 }
12}
13impl<T> A for T {}
14
15trait B: A {
16 fn hello() -> &'static str {
17 "B"
18 }
19}
20impl<T> B for T {}
21
22fn foo<T>() -> &'static str {
23 T::hello()
24}
25
26fn main() {
27 assert_eq!(foo::<()>(), "B");
28}
tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr deleted-17
......@@ -1,17 +0,0 @@
1warning: a method with this name may be added to the standard library in the future
2 --> $DIR/unstable.rs:26:19
3 |
4LL | assert_eq!(().hello(), "A");
5 | ^^^^^
6 |
7 = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method
8 = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
9 = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
10 = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default
11help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello`
12 |
13LL + #![feature(downstream)]
14 |
15
16warning: 1 warning emitted
17
tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr deleted-17
......@@ -1,17 +0,0 @@
1warning: a method with this name may be added to the standard library in the future
2 --> $DIR/unstable.rs:26:19
3 |
4LL | assert_eq!(().hello(), "A");
5 | ^^^^^
6 |
7 = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method
8 = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
9 = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
10 = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default
11help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello`
12 |
13LL + #![feature(downstream)]
14 |
15
16warning: 1 warning emitted
17
tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr deleted-22
......@@ -1,22 +0,0 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/unstable.rs:30:19
3 |
4LL | assert_eq!(().hello(), "B");
5 | ^^^^^ multiple `hello` found
6 |
7 = note: candidate #1 is defined in an impl of the trait `shadowed_stability::A` for the type `T`
8 = note: candidate #2 is defined in an impl of the trait `shadowed_stability::B` for the type `T`
9help: disambiguate the method for candidate #1
10 |
11LL - assert_eq!(().hello(), "B");
12LL + assert_eq!(shadowed_stability::A::hello(&()), "B");
13 |
14help: disambiguate the method for candidate #2
15 |
16LL - assert_eq!(().hello(), "B");
17LL + assert_eq!(shadowed_stability::B::hello(&()), "B");
18 |
19
20error: aborting due to 1 previous error
21
22For more information about this error, try `rustc --explain E0034`.
tests/ui/methods/supertrait-shadowing/unstable.rs deleted-32
......@@ -1,32 +0,0 @@
1// This tests the interaction of feature staging and supertrait item shadowing.
2// When a feature is *off*, then we should not consider unstable methods for probing.
3// When a feature is *on*, then we follow the normal supertrait item shadowing rules:
4// - When supertrait item shadowing is disabled, this is a clash.
5// - When supertrait item shadowing is enabled, we pick subtraits.
6
7//@ aux-build: shadowed_stability.rs
8//@ revisions: off_normal on_normal off_shadowing on_shadowing
9//@[off_normal] run-pass
10//@[on_normal] check-fail
11//@[off_shadowing] run-pass
12//@[on_shadowing] run-pass
13//@ check-run-results
14
15#![allow(dead_code, unused_features, unused_imports)]
16#![cfg_attr(on_shadowing, feature(downstream))]
17#![cfg_attr(on_normal, feature(downstream))]
18#![cfg_attr(off_shadowing, feature(supertrait_item_shadowing))]
19#![cfg_attr(on_shadowing, feature(supertrait_item_shadowing))]
20
21extern crate shadowed_stability;
22use shadowed_stability::*;
23
24fn main() {
25 #[cfg(any(off_normal, off_shadowing))]
26 assert_eq!(().hello(), "A");
27 //[off_normal,off_shadowing]~^ WARN a method with this name may be added
28 //[off_normal,off_shadowing]~| WARN once this associated item is added
29 #[cfg(any(on_normal, on_shadowing))]
30 assert_eq!(().hello(), "B");
31 //[on_normal]~^ ERROR multiple applicable items in scope
32}
tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex1.rs created+17
......@@ -0,0 +1,17 @@
1//! Test for <https://github.com/rust-lang/rust/issues/28498>.
2//! Example taken from RFC 1238 text
3//! <https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md>.
4//@ run-pass
5
6use std::cell::Cell;
7
8struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
9
10fn main() {
11 let mut data = Vec::new();
12 data.push(Concrete(0, Cell::new(None)));
13 data.push(Concrete(0, Cell::new(None)));
14
15 data[0].1.set(Some(&data[1]));
16 data[1].1.set(Some(&data[0]));
17}
tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs created+19
......@@ -0,0 +1,19 @@
1//! Test for <https://github.com/rust-lang/rust/issues/28498>.
2//! Example taken from RFC 1238 text
3//! <https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md>.
4//@ run-pass
5
6use std::cell::Cell;
7
8struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
9
10struct Foo<T> { data: Vec<T> }
11
12fn main() {
13 let mut foo = Foo { data: Vec::new() };
14 foo.data.push(Concrete(0, Cell::new(None)));
15 foo.data.push(Concrete(0, Cell::new(None)));
16
17 foo.data[0].1.set(Some(&foo.data[1]));
18 foo.data[1].1.set(Some(&foo.data[0]));
19}
tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.rs created+35
......@@ -0,0 +1,35 @@
1//! Test for <https://github.com/rust-lang/rust/issues/28498>.
2//! Example taken from RFC 1238 text
3//! <https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md>.
4//! Compare against tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs.
5
6use std::cell::Cell;
7
8struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
9
10struct Foo<T> { data: Vec<T> }
11
12fn potentially_specialized_wrt_t<T>(t: &T) {
13 // Hypothetical code that does one thing for generic T and then is
14 // specialized for T == Concrete (and the specialized form can
15 // then access a reference held in concrete tuple).
16 //
17 // (We don't have specialization yet, but we want to allow for it
18 // in the future.)
19}
20
21impl<T> Drop for Foo<T> {
22 fn drop(&mut self) {
23 potentially_specialized_wrt_t(&self.data[0])
24 }
25}
26
27fn main() {
28 let mut foo = Foo { data: Vec::new() };
29 foo.data.push(Concrete(0, Cell::new(None)));
30 foo.data.push(Concrete(0, Cell::new(None)));
31
32 foo.data[0].1.set(Some(&foo.data[1]));
33 //~^ ERROR borrow may still be in use when destructor runs
34 foo.data[1].1.set(Some(&foo.data[0]));
35}
tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.stderr created+17
......@@ -0,0 +1,17 @@
1error[E0713]: borrow may still be in use when destructor runs
2 --> $DIR/reject-ex1.rs:32:29
3 |
4LL | foo.data[0].1.set(Some(&foo.data[1]));
5 | ^^^^^^^^
6...
7LL | }
8 | -
9 | |
10 | here, drop of `foo` needs exclusive access to `foo.data`, because the type `Foo<Concrete<'_>>` implements the `Drop` trait
11 | borrow might be used here, when `foo` is dropped and runs the `Drop` code for type `Foo`
12 |
13 = note: consider using a `let` binding to create a longer lived value
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0713`.
tests/ui/rfcs/rfc-1238-nonparametric-dropck/ugeh-ex1.rs created+25
......@@ -0,0 +1,25 @@
1//! Test for <https://github.com/rust-lang/rust/issues/28498>.
2//! Example taken from RFC 1238 text
3//! <https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md>.
4//@ run-pass
5
6#![feature(dropck_eyepatch)]
7use std::cell::Cell;
8
9struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>);
10
11struct Foo<T> { data: Vec<T> }
12
13// Below is the UGEH attribute
14unsafe impl<#[may_dangle] T> Drop for Foo<T> {
15 fn drop(&mut self) { }
16}
17
18fn main() {
19 let mut foo = Foo { data: Vec::new() };
20 foo.data.push(Concrete(0, Cell::new(None)));
21 foo.data.push(Concrete(0, Cell::new(None)));
22
23 foo.data[0].1.set(Some(&foo.data[1]));
24 foo.data[1].1.set(Some(&foo.data[0]));
25}
tests/ui/span/foreign-item-vis-span.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28472>.
2//! Check that the visibility modifier is included in the span of foreign items.
3
4extern "C" {
5 fn foo();
6
7 pub //~ ERROR the name `foo` is defined multiple times
8 fn foo();
9
10 pub //~ ERROR the name `foo` is defined multiple times
11 static mut foo: u32;
12}
13
14fn main() {
15}
tests/ui/span/foreign-item-vis-span.stderr created+27
......@@ -0,0 +1,27 @@
1error[E0428]: the name `foo` is defined multiple times
2 --> $DIR/foreign-item-vis-span.rs:7:3
3 |
4LL | fn foo();
5 | --------- previous definition of the value `foo` here
6LL |
7LL | / pub
8LL | | fn foo();
9 | |___________^ `foo` redefined here
10 |
11 = note: `foo` must be defined only once in the value namespace of this module
12
13error[E0428]: the name `foo` is defined multiple times
14 --> $DIR/foreign-item-vis-span.rs:10:3
15 |
16LL | fn foo();
17 | --------- previous definition of the value `foo` here
18...
19LL | / pub
20LL | | static mut foo: u32;
21 | |______________________^ `foo` redefined here
22 |
23 = note: `foo` must be defined only once in the value namespace of this module
24
25error: aborting due to 2 previous errors
26
27For more information about this error, try `rustc --explain E0428`.
tests/ui/span/issue28498-reject-ex1.rs deleted-37
......@@ -1,37 +0,0 @@
1// Example taken from RFC 1238 text
2
3// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
4// #examples-of-code-that-will-start-to-be-rejected
5
6// Compare against test/run-pass/issue28498-must-work-ex2.rs
7
8use std::cell::Cell;
9
10struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>);
11
12struct Foo<T> { data: Vec<T> }
13
14fn potentially_specialized_wrt_t<T>(t: &T) {
15 // Hypothetical code that does one thing for generic T and then is
16 // specialized for T == Concrete (and the specialized form can
17 // then access a reference held in concrete tuple).
18 //
19 // (We don't have specialization yet, but we want to allow for it
20 // in the future.)
21}
22
23impl<T> Drop for Foo<T> {
24 fn drop(&mut self) {
25 potentially_specialized_wrt_t(&self.data[0])
26 }
27}
28
29fn main() {
30 let mut foo = Foo { data: Vec::new() };
31 foo.data.push(Concrete(0, Cell::new(None)));
32 foo.data.push(Concrete(0, Cell::new(None)));
33
34 foo.data[0].1.set(Some(&foo.data[1]));
35 //~^ ERROR borrow may still be in use when destructor runs
36 foo.data[1].1.set(Some(&foo.data[0]));
37}
tests/ui/span/issue28498-reject-ex1.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0713]: borrow may still be in use when destructor runs
2 --> $DIR/issue28498-reject-ex1.rs:34:29
3 |
4LL | foo.data[0].1.set(Some(&foo.data[1]));
5 | ^^^^^^^^
6...
7LL | }
8 | -
9 | |
10 | here, drop of `foo` needs exclusive access to `foo.data`, because the type `Foo<Concrete<'_>>` implements the `Drop` trait
11 | borrow might be used here, when `foo` is dropped and runs the `Drop` code for type `Foo`
12 |
13 = note: consider using a `let` binding to create a longer lived value
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0713`.
tests/ui/structs/non-struct-in-struct-position.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27815>.
2//! Test usage of struct literal syntax with non-structs doesn't ICE.
3
4mod A {}
5
6fn main() {
7 let u = A { x: 1 }; //~ ERROR expected struct, variant or union type, found module `A`
8 let v = u32 { x: 1 }; //~ ERROR expected struct, variant or union type, found builtin type `u32`
9 match () {
10 A { x: 1 } => {}
11 //~^ ERROR expected struct, variant or union type, found module `A`
12 u32 { x: 1 } => {}
13 //~^ ERROR expected struct, variant or union type, found builtin type `u32`
14 }
15}
tests/ui/structs/non-struct-in-struct-position.stderr created+27
......@@ -0,0 +1,27 @@
1error[E0574]: expected struct, variant or union type, found module `A`
2 --> $DIR/non-struct-in-struct-position.rs:7:13
3 |
4LL | let u = A { x: 1 };
5 | ^ not a struct, variant or union type
6
7error[E0574]: expected struct, variant or union type, found builtin type `u32`
8 --> $DIR/non-struct-in-struct-position.rs:8:13
9 |
10LL | let v = u32 { x: 1 };
11 | ^^^ not a struct, variant or union type
12
13error[E0574]: expected struct, variant or union type, found module `A`
14 --> $DIR/non-struct-in-struct-position.rs:10:9
15 |
16LL | A { x: 1 } => {}
17 | ^ not a struct, variant or union type
18
19error[E0574]: expected struct, variant or union type, found builtin type `u32`
20 --> $DIR/non-struct-in-struct-position.rs:12:9
21 |
22LL | u32 { x: 1 } => {}
23 | ^^^ not a struct, variant or union type
24
25error: aborting due to 4 previous errors
26
27For more information about this error, try `rustc --explain E0574`.
tests/ui/supertrait-shadowing/assoc-const.rs created+31
......@@ -0,0 +1,31 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![feature(min_generic_const_args)]
5#![allow(dead_code)]
6
7trait A {
8 const CONST: i32;
9}
10impl<T> A for T {
11 const CONST: i32 = 1;
12}
13
14trait B: A {
15 type const CONST: i32;
16}
17impl<T> B for T {
18 type const CONST: i32 = 2;
19}
20
21trait C: B {}
22impl<T> C for T {}
23
24fn main() {
25 assert_eq!(i32::CONST, 2);
26 generic::<u32>();
27}
28
29fn generic<T: C<CONST = 2>>() {
30 assert_eq!(T::CONST, 2);
31}
tests/ui/supertrait-shadowing/assoc-type-fail.rs created+47
......@@ -0,0 +1,47 @@
1#![feature(supertrait_item_shadowing)]
2#![allow(dead_code)]
3
4use std::mem::size_of;
5
6trait A {
7 type Assoc;
8}
9impl<X> A for X {
10 type Assoc = i8;
11}
12
13trait B: A {
14 type Assoc;
15}
16impl<X> B for X {
17 type Assoc = i16;
18}
19
20trait C: B {}
21impl<X> C for X {}
22
23fn main() {
24 b_unbound::<u32>();
25 c_unbound::<u32>();
26
27 b_assoc_is_a::<u32>();
28 //~^ ERROR type mismatch resolving `<u32 as B>::Assoc == i8`
29 c_assoc_is_a::<u32>();
30 //~^ ERROR type mismatch resolving `<u32 as B>::Assoc == i8`
31}
32
33fn b_unbound<U: B>() {
34 let _ = size_of::<U::Assoc>();
35}
36
37fn c_unbound<U: C>() {
38 let _ = size_of::<U::Assoc>();
39}
40
41fn b_assoc_is_a<U: B<Assoc = i8>>() {
42 let _ = size_of::<U::Assoc>();
43}
44
45fn c_assoc_is_a<U: C<Assoc = i8>>() {
46 let _ = size_of::<U::Assoc>();
47}
tests/ui/supertrait-shadowing/assoc-type-fail.stderr created+37
......@@ -0,0 +1,37 @@
1error[E0271]: type mismatch resolving `<u32 as B>::Assoc == i8`
2 --> $DIR/assoc-type-fail.rs:27:20
3 |
4LL | b_assoc_is_a::<u32>();
5 | ^^^ type mismatch resolving `<u32 as B>::Assoc == i8`
6 |
7note: expected this to be `i8`
8 --> $DIR/assoc-type-fail.rs:17:18
9 |
10LL | type Assoc = i16;
11 | ^^^
12note: required by a bound in `b_assoc_is_a`
13 --> $DIR/assoc-type-fail.rs:41:22
14 |
15LL | fn b_assoc_is_a<U: B<Assoc = i8>>() {
16 | ^^^^^^^^^^ required by this bound in `b_assoc_is_a`
17
18error[E0271]: type mismatch resolving `<u32 as B>::Assoc == i8`
19 --> $DIR/assoc-type-fail.rs:29:20
20 |
21LL | c_assoc_is_a::<u32>();
22 | ^^^ type mismatch resolving `<u32 as B>::Assoc == i8`
23 |
24note: expected this to be `i8`
25 --> $DIR/assoc-type-fail.rs:17:18
26 |
27LL | type Assoc = i16;
28 | ^^^
29note: required by a bound in `c_assoc_is_a`
30 --> $DIR/assoc-type-fail.rs:45:22
31 |
32LL | fn c_assoc_is_a<U: C<Assoc = i8>>() {
33 | ^^^^^^^^^^ required by this bound in `c_assoc_is_a`
34
35error: aborting due to 2 previous errors
36
37For more information about this error, try `rustc --explain E0271`.
tests/ui/supertrait-shadowing/assoc-type-predicates.rs created+45
......@@ -0,0 +1,45 @@
1//@ normalize-stderr: "assoc_type_predicates\[[^\]]+\]" -> "assoc_type_predicates[HASH]"
2
3#![feature(rustc_attrs)]
4#![feature(supertrait_item_shadowing)]
5#![allow(dead_code)]
6
7trait A {
8 type Assoc;
9}
10impl<T> A for T {
11 type Assoc = i8;
12}
13
14trait B: A {
15 type Assoc;
16}
17impl<T> B for T {
18 type Assoc = i16;
19}
20
21trait C: B {}
22impl<T> C for T {}
23
24#[rustc_dump_predicates]
25fn a_bound<T: A<Assoc = i8>>() {}
26//~^ ERROR rustc_dump_predicates
27//~| NOTE TraitPredicate(<T as std::marker::Sized>
28//~| NOTE TraitPredicate(<T as A>
29//~| NOTE A::Assoc
30
31#[rustc_dump_predicates]
32fn b_bound<T: B<Assoc = i16>>() {}
33//~^ ERROR rustc_dump_predicates
34//~| NOTE TraitPredicate(<T as std::marker::Sized>
35//~| NOTE TraitPredicate(<T as B>
36//~| NOTE B::Assoc
37
38#[rustc_dump_predicates]
39fn c_bound<T: C<Assoc = i16>>() {}
40//~^ ERROR rustc_dump_predicates
41//~| NOTE TraitPredicate(<T as std::marker::Sized>
42//~| NOTE TraitPredicate(<T as C>
43//~| NOTE B::Assoc
44
45fn main() {}
tests/ui/supertrait-shadowing/assoc-type-predicates.stderr created+32
......@@ -0,0 +1,32 @@
1error: rustc_dump_predicates
2 --> $DIR/assoc-type-predicates.rs:25:1
3 |
4LL | fn a_bound<T: A<Assoc = i8>>() {}
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7 = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] }
8 = note: Binder { value: TraitPredicate(<T as A>, polarity:Positive), bound_vars: [] }
9 = note: Binder { value: ProjectionPredicate(Alias { kind: ProjectionTy { def_id: DefId(0:4 ~ assoc_type_predicates[HASH]::A::Assoc) }, args: [T/#0], .. }, Term::Ty(i8)), bound_vars: [] }
10
11error: rustc_dump_predicates
12 --> $DIR/assoc-type-predicates.rs:32:1
13 |
14LL | fn b_bound<T: B<Assoc = i16>>() {}
15 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16 |
17 = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] }
18 = note: Binder { value: TraitPredicate(<T as B>, polarity:Positive), bound_vars: [] }
19 = note: Binder { value: ProjectionPredicate(Alias { kind: ProjectionTy { def_id: DefId(0:9 ~ assoc_type_predicates[HASH]::B::Assoc) }, args: [T/#0], .. }, Term::Ty(i16)), bound_vars: [] }
20
21error: rustc_dump_predicates
22 --> $DIR/assoc-type-predicates.rs:39:1
23 |
24LL | fn c_bound<T: C<Assoc = i16>>() {}
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26 |
27 = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] }
28 = note: Binder { value: TraitPredicate(<T as C>, polarity:Positive), bound_vars: [] }
29 = note: Binder { value: ProjectionPredicate(Alias { kind: ProjectionTy { def_id: DefId(0:9 ~ assoc_type_predicates[HASH]::B::Assoc) }, args: [T/#0], .. }, Term::Ty(i16)), bound_vars: [] }
30
31error: aborting due to 3 previous errors
32
tests/ui/supertrait-shadowing/assoc-type.rs created+53
......@@ -0,0 +1,53 @@
1//@ run-pass
2//@ check-run-results
3
4#![feature(supertrait_item_shadowing)]
5#![allow(dead_code)]
6
7use std::mem::size_of;
8
9trait A {
10 type Assoc;
11}
12impl<T> A for T {
13 type Assoc = i8;
14}
15
16trait B: A {
17 type Assoc;
18}
19impl<T> B for T {
20 type Assoc = i16;
21}
22
23trait C: B {}
24impl<T> C for T {}
25
26fn main() {
27 generic::<u32>();
28 generic2::<u32>();
29 generic3::<u32>();
30 generic4::<u32>();
31 generic5::<u32>();
32}
33
34fn generic<T: B>() {
35 assert_eq!(size_of::<T::Assoc>(), 2);
36}
37
38fn generic2<T: A<Assoc = i8>>() {
39 assert_eq!(size_of::<T::Assoc>(), 1);
40}
41
42fn generic3<T: B<Assoc = i16>>() {
43 assert_eq!(size_of::<T::Assoc>(), 2);
44}
45
46fn generic4<T: C<Assoc = i16>>() {
47 assert_eq!(size_of::<T::Assoc>(), 2);
48}
49
50fn generic5<T: B>() {
51 assert_eq!(size_of::<<T as A>::Assoc>(), 1);
52 assert_eq!(size_of::<<T as B>::Assoc>(), 2);
53}
tests/ui/supertrait-shadowing/auxiliary/shadowed_stability.rs created+22
......@@ -0,0 +1,22 @@
1#![feature(staged_api)]
2#![stable(feature = "main", since = "1.0.0")]
3
4#[stable(feature = "main", since = "1.0.0")]
5pub trait A {
6 #[stable(feature = "main", since = "1.0.0")]
7 fn hello(&self) -> &'static str {
8 "A"
9 }
10}
11#[stable(feature = "main", since = "1.0.0")]
12impl<T> A for T {}
13
14#[stable(feature = "main", since = "1.0.0")]
15pub trait B: A {
16 #[unstable(feature = "downstream", issue = "none")]
17 fn hello(&self) -> &'static str {
18 "B"
19 }
20}
21#[stable(feature = "main", since = "1.0.0")]
22impl<T> B for T {}
tests/ui/supertrait-shadowing/common-ancestor-2.rs created+59
......@@ -0,0 +1,59 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![feature(min_generic_const_args)]
5#![warn(resolving_to_items_shadowing_supertrait_items)]
6#![warn(shadowing_supertrait_items)]
7#![allow(dead_code)]
8
9use std::mem::size_of;
10
11trait A {
12 fn hello(&self) -> &'static str {
13 "A"
14 }
15 type Assoc;
16 const CONST: i32;
17}
18impl<T> A for T {
19 type Assoc = i8;
20 const CONST: i32 = 1;
21}
22
23trait B {
24 fn hello(&self) -> &'static str {
25 "B"
26 }
27 type Assoc;
28 const CONST: i32;
29}
30impl<T> B for T {
31 type Assoc = i16;
32 const CONST: i32 = 2;
33}
34
35trait C: A + B {
36 fn hello(&self) -> &'static str {
37 //~^ WARN trait item `hello` from `C` shadows identically named item
38 "C"
39 }
40 type Assoc;
41 //~^ WARN trait item `Assoc` from `C` shadows identically named item
42 type const CONST: i32;
43 //~^ WARN trait item `CONST` from `C` shadows identically named item
44}
45impl<T> C for T {
46 type Assoc = i32;
47 type const CONST: i32 = 3;
48}
49
50fn main() {
51 assert_eq!(().hello(), "C");
52 //~^ WARN trait item `hello` from `C` shadows identically named item from supertrait
53 check::<()>();
54}
55
56fn check<T: C>() {
57 assert_eq!(size_of::<T::Assoc>(), 4);
58 assert_eq!(T::CONST, 3);
59}
tests/ui/supertrait-shadowing/common-ancestor-2.stderr created+77
......@@ -0,0 +1,77 @@
1warning: trait item `hello` from `C` shadows identically named item from supertrait
2 --> $DIR/common-ancestor-2.rs:36:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: items from several supertraits are shadowed: `B` and `A`
8 --> $DIR/common-ancestor-2.rs:12:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12...
13LL | fn hello(&self) -> &'static str {
14 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15note: the lint level is defined here
16 --> $DIR/common-ancestor-2.rs:6:9
17 |
18LL | #![warn(shadowing_supertrait_items)]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
20
21warning: trait item `Assoc` from `C` shadows identically named item from supertrait
22 --> $DIR/common-ancestor-2.rs:40:5
23 |
24LL | type Assoc;
25 | ^^^^^^^^^^
26 |
27note: items from several supertraits are shadowed: `B` and `A`
28 --> $DIR/common-ancestor-2.rs:15:5
29 |
30LL | type Assoc;
31 | ^^^^^^^^^^
32...
33LL | type Assoc;
34 | ^^^^^^^^^^
35
36warning: trait item `CONST` from `C` shadows identically named item from supertrait
37 --> $DIR/common-ancestor-2.rs:42:5
38 |
39LL | type const CONST: i32;
40 | ^^^^^^^^^^^^^^^^^^^^^
41 |
42note: items from several supertraits are shadowed: `B` and `A`
43 --> $DIR/common-ancestor-2.rs:16:5
44 |
45LL | const CONST: i32;
46 | ^^^^^^^^^^^^^^^^
47...
48LL | const CONST: i32;
49 | ^^^^^^^^^^^^^^^^
50
51warning: trait item `hello` from `C` shadows identically named item from supertrait
52 --> $DIR/common-ancestor-2.rs:51:19
53 |
54LL | assert_eq!(().hello(), "C");
55 | ^^^^^
56 |
57note: item from `C` shadows a supertrait item
58 --> $DIR/common-ancestor-2.rs:36:5
59 |
60LL | fn hello(&self) -> &'static str {
61 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62note: items from several supertraits are shadowed: `A` and `B`
63 --> $DIR/common-ancestor-2.rs:12:5
64 |
65LL | fn hello(&self) -> &'static str {
66 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67...
68LL | fn hello(&self) -> &'static str {
69 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
70note: the lint level is defined here
71 --> $DIR/common-ancestor-2.rs:5:9
72 |
73LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
74 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
75
76warning: 4 warnings emitted
77
tests/ui/supertrait-shadowing/common-ancestor-3.rs created+76
......@@ -0,0 +1,76 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![feature(min_generic_const_args)]
5#![warn(resolving_to_items_shadowing_supertrait_items)]
6#![warn(shadowing_supertrait_items)]
7#![allow(dead_code)]
8
9use std::mem::size_of;
10
11trait A {
12 fn hello(&self) -> &'static str {
13 "A"
14 }
15 type Assoc;
16 const CONST: i32;
17}
18impl<T> A for T {
19 type Assoc = i8;
20 const CONST: i32 = 1;
21}
22
23trait B {
24 fn hello(&self) -> &'static str {
25 "B"
26 }
27 type Assoc;
28 const CONST: i32;
29}
30impl<T> B for T {
31 type Assoc = i16;
32 const CONST: i32 = 2;
33}
34
35trait C: A + B {
36 fn hello(&self) -> &'static str {
37 //~^ WARN trait item `hello` from `C` shadows identically named item
38 "C"
39 }
40 type Assoc;
41 //~^ WARN trait item `Assoc` from `C` shadows identically named item
42 type const CONST: i32;
43 //~^ WARN trait item `CONST` from `C` shadows identically named item
44}
45impl<T> C for T {
46 type Assoc = i32;
47 type const CONST: i32 = 3;
48}
49
50// `D` extends `C` which extends `B` and `A`
51
52trait D: C {
53 fn hello(&self) -> &'static str {
54 //~^ WARN trait item `hello` from `D` shadows identically named item
55 "D"
56 }
57 type Assoc;
58 //~^ WARN trait item `Assoc` from `D` shadows identically named item
59 type const CONST: i32;
60 //~^ WARN trait item `CONST` from `D` shadows identically named item
61}
62impl<T> D for T {
63 type Assoc = i64;
64 type const CONST: i32 = 4;
65}
66
67fn main() {
68 assert_eq!(().hello(), "D");
69 //~^ WARN trait item `hello` from `D` shadows identically named item from supertrait
70 check::<()>();
71}
72
73fn check<T: D>() {
74 assert_eq!(size_of::<T::Assoc>(), 8);
75 assert_eq!(T::CONST, 4);
76}
tests/ui/supertrait-shadowing/common-ancestor-3.stderr created+134
......@@ -0,0 +1,134 @@
1warning: trait item `hello` from `C` shadows identically named item from supertrait
2 --> $DIR/common-ancestor-3.rs:36:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: items from several supertraits are shadowed: `B` and `A`
8 --> $DIR/common-ancestor-3.rs:12:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12...
13LL | fn hello(&self) -> &'static str {
14 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15note: the lint level is defined here
16 --> $DIR/common-ancestor-3.rs:6:9
17 |
18LL | #![warn(shadowing_supertrait_items)]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
20
21warning: trait item `Assoc` from `C` shadows identically named item from supertrait
22 --> $DIR/common-ancestor-3.rs:40:5
23 |
24LL | type Assoc;
25 | ^^^^^^^^^^
26 |
27note: items from several supertraits are shadowed: `B` and `A`
28 --> $DIR/common-ancestor-3.rs:15:5
29 |
30LL | type Assoc;
31 | ^^^^^^^^^^
32...
33LL | type Assoc;
34 | ^^^^^^^^^^
35
36warning: trait item `CONST` from `C` shadows identically named item from supertrait
37 --> $DIR/common-ancestor-3.rs:42:5
38 |
39LL | type const CONST: i32;
40 | ^^^^^^^^^^^^^^^^^^^^^
41 |
42note: items from several supertraits are shadowed: `B` and `A`
43 --> $DIR/common-ancestor-3.rs:16:5
44 |
45LL | const CONST: i32;
46 | ^^^^^^^^^^^^^^^^
47...
48LL | const CONST: i32;
49 | ^^^^^^^^^^^^^^^^
50
51warning: trait item `hello` from `D` shadows identically named item from supertrait
52 --> $DIR/common-ancestor-3.rs:53:5
53 |
54LL | fn hello(&self) -> &'static str {
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56 |
57note: items from several supertraits are shadowed: `C`, `B`, and `A`
58 --> $DIR/common-ancestor-3.rs:12:5
59 |
60LL | fn hello(&self) -> &'static str {
61 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62...
63LL | fn hello(&self) -> &'static str {
64 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65...
66LL | fn hello(&self) -> &'static str {
67 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68
69warning: trait item `Assoc` from `D` shadows identically named item from supertrait
70 --> $DIR/common-ancestor-3.rs:57:5
71 |
72LL | type Assoc;
73 | ^^^^^^^^^^
74 |
75note: items from several supertraits are shadowed: `C`, `B`, and `A`
76 --> $DIR/common-ancestor-3.rs:15:5
77 |
78LL | type Assoc;
79 | ^^^^^^^^^^
80...
81LL | type Assoc;
82 | ^^^^^^^^^^
83...
84LL | type Assoc;
85 | ^^^^^^^^^^
86
87warning: trait item `CONST` from `D` shadows identically named item from supertrait
88 --> $DIR/common-ancestor-3.rs:59:5
89 |
90LL | type const CONST: i32;
91 | ^^^^^^^^^^^^^^^^^^^^^
92 |
93note: items from several supertraits are shadowed: `C`, `B`, and `A`
94 --> $DIR/common-ancestor-3.rs:16:5
95 |
96LL | const CONST: i32;
97 | ^^^^^^^^^^^^^^^^
98...
99LL | const CONST: i32;
100 | ^^^^^^^^^^^^^^^^
101...
102LL | type const CONST: i32;
103 | ^^^^^^^^^^^^^^^^^^^^^
104
105warning: trait item `hello` from `D` shadows identically named item from supertrait
106 --> $DIR/common-ancestor-3.rs:68:19
107 |
108LL | assert_eq!(().hello(), "D");
109 | ^^^^^
110 |
111note: item from `D` shadows a supertrait item
112 --> $DIR/common-ancestor-3.rs:53:5
113 |
114LL | fn hello(&self) -> &'static str {
115 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
116note: items from several supertraits are shadowed: `A`, `B`, and `C`
117 --> $DIR/common-ancestor-3.rs:12:5
118 |
119LL | fn hello(&self) -> &'static str {
120 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
121...
122LL | fn hello(&self) -> &'static str {
123 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
124...
125LL | fn hello(&self) -> &'static str {
126 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127note: the lint level is defined here
128 --> $DIR/common-ancestor-3.rs:5:9
129 |
130LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
131 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
132
133warning: 7 warnings emitted
134
tests/ui/supertrait-shadowing/common-ancestor.rs created+47
......@@ -0,0 +1,47 @@
1//@ run-pass
2
3#![feature(supertrait_item_shadowing)]
4#![feature(min_generic_const_args)]
5#![warn(resolving_to_items_shadowing_supertrait_items)]
6#![warn(shadowing_supertrait_items)]
7#![allow(dead_code)]
8
9use std::mem::size_of;
10
11trait A {
12 fn hello(&self) -> &'static str {
13 "A"
14 }
15 type Assoc;
16 const CONST: i32;
17}
18impl<T> A for T {
19 type Assoc = i8;
20 const CONST: i32 = 1;
21}
22
23trait B: A {
24 fn hello(&self) -> &'static str {
25 //~^ WARN trait item `hello` from `B` shadows identically named item
26 "B"
27 }
28 type Assoc;
29 //~^ WARN trait item `Assoc` from `B` shadows identically named item
30 type const CONST: i32;
31 //~^ WARN trait item `CONST` from `B` shadows identically named item
32}
33impl<T> B for T {
34 type Assoc = i16;
35 type const CONST: i32 = 2;
36}
37
38fn main() {
39 assert_eq!(().hello(), "B");
40 //~^ WARN trait item `hello` from `B` shadows identically named item from supertrait
41 check::<()>();
42}
43
44fn check<T: B>() {
45 assert_eq!(size_of::<T::Assoc>(), 2);
46 assert_eq!(T::CONST, 2);
47}
tests/ui/supertrait-shadowing/common-ancestor.stderr created+65
......@@ -0,0 +1,65 @@
1warning: trait item `hello` from `B` shadows identically named item from supertrait
2 --> $DIR/common-ancestor.rs:24:5
3 |
4LL | fn hello(&self) -> &'static str {
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: item from `A` is shadowed by a subtrait item
8 --> $DIR/common-ancestor.rs:12:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/common-ancestor.rs:6:9
14 |
15LL | #![warn(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18warning: trait item `Assoc` from `B` shadows identically named item from supertrait
19 --> $DIR/common-ancestor.rs:28:5
20 |
21LL | type Assoc;
22 | ^^^^^^^^^^
23 |
24note: item from `A` is shadowed by a subtrait item
25 --> $DIR/common-ancestor.rs:15:5
26 |
27LL | type Assoc;
28 | ^^^^^^^^^^
29
30warning: trait item `CONST` from `B` shadows identically named item from supertrait
31 --> $DIR/common-ancestor.rs:30:5
32 |
33LL | type const CONST: i32;
34 | ^^^^^^^^^^^^^^^^^^^^^
35 |
36note: item from `A` is shadowed by a subtrait item
37 --> $DIR/common-ancestor.rs:16:5
38 |
39LL | const CONST: i32;
40 | ^^^^^^^^^^^^^^^^
41
42warning: trait item `hello` from `B` shadows identically named item from supertrait
43 --> $DIR/common-ancestor.rs:39:19
44 |
45LL | assert_eq!(().hello(), "B");
46 | ^^^^^
47 |
48note: item from `B` shadows a supertrait item
49 --> $DIR/common-ancestor.rs:24:5
50 |
51LL | fn hello(&self) -> &'static str {
52 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
53note: item from `A` is shadowed by a subtrait item
54 --> $DIR/common-ancestor.rs:12:5
55 |
56LL | fn hello(&self) -> &'static str {
57 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58note: the lint level is defined here
59 --> $DIR/common-ancestor.rs:5:9
60 |
61LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
62 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
63
64warning: 4 warnings emitted
65
tests/ui/supertrait-shadowing/definition-site.rs created+28
......@@ -0,0 +1,28 @@
1#![feature(supertrait_item_shadowing)]
2#![deny(shadowing_supertrait_items)]
3
4trait SuperSuper {
5 fn method();
6 const CONST: i32;
7 type Assoc;
8}
9
10trait Super: SuperSuper {
11 fn method();
12 //~^ ERROR trait item `method` from `Super` shadows identically named item
13 const CONST: i32;
14 //~^ ERROR trait item `CONST` from `Super` shadows identically named item
15 type Assoc;
16 //~^ ERROR trait item `Assoc` from `Super` shadows identically named item
17}
18
19trait Sub: Super {
20 fn method();
21 //~^ ERROR trait item `method` from `Sub` shadows identically named item
22 const CONST: i32;
23 //~^ ERROR trait item `CONST` from `Sub` shadows identically named item
24 type Assoc;
25 //~^ ERROR trait item `Assoc` from `Sub` shadows identically named item
26}
27
28fn main() {}
tests/ui/supertrait-shadowing/definition-site.stderr created+88
......@@ -0,0 +1,88 @@
1error: trait item `method` from `Super` shadows identically named item from supertrait
2 --> $DIR/definition-site.rs:11:5
3 |
4LL | fn method();
5 | ^^^^^^^^^^^^
6 |
7note: item from `SuperSuper` is shadowed by a subtrait item
8 --> $DIR/definition-site.rs:5:5
9 |
10LL | fn method();
11 | ^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/definition-site.rs:2:9
14 |
15LL | #![deny(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18error: trait item `CONST` from `Super` shadows identically named item from supertrait
19 --> $DIR/definition-site.rs:13:5
20 |
21LL | const CONST: i32;
22 | ^^^^^^^^^^^^^^^^
23 |
24note: item from `SuperSuper` is shadowed by a subtrait item
25 --> $DIR/definition-site.rs:6:5
26 |
27LL | const CONST: i32;
28 | ^^^^^^^^^^^^^^^^
29
30error: trait item `Assoc` from `Super` shadows identically named item from supertrait
31 --> $DIR/definition-site.rs:15:5
32 |
33LL | type Assoc;
34 | ^^^^^^^^^^
35 |
36note: item from `SuperSuper` is shadowed by a subtrait item
37 --> $DIR/definition-site.rs:7:5
38 |
39LL | type Assoc;
40 | ^^^^^^^^^^
41
42error: trait item `method` from `Sub` shadows identically named item from supertrait
43 --> $DIR/definition-site.rs:20:5
44 |
45LL | fn method();
46 | ^^^^^^^^^^^^
47 |
48note: items from several supertraits are shadowed: `Super` and `SuperSuper`
49 --> $DIR/definition-site.rs:5:5
50 |
51LL | fn method();
52 | ^^^^^^^^^^^^
53...
54LL | fn method();
55 | ^^^^^^^^^^^^
56
57error: trait item `CONST` from `Sub` shadows identically named item from supertrait
58 --> $DIR/definition-site.rs:22:5
59 |
60LL | const CONST: i32;
61 | ^^^^^^^^^^^^^^^^
62 |
63note: items from several supertraits are shadowed: `Super` and `SuperSuper`
64 --> $DIR/definition-site.rs:6:5
65 |
66LL | const CONST: i32;
67 | ^^^^^^^^^^^^^^^^
68...
69LL | const CONST: i32;
70 | ^^^^^^^^^^^^^^^^
71
72error: trait item `Assoc` from `Sub` shadows identically named item from supertrait
73 --> $DIR/definition-site.rs:24:5
74 |
75LL | type Assoc;
76 | ^^^^^^^^^^
77 |
78note: items from several supertraits are shadowed: `Super` and `SuperSuper`
79 --> $DIR/definition-site.rs:7:5
80 |
81LL | type Assoc;
82 | ^^^^^^^^^^
83...
84LL | type Assoc;
85 | ^^^^^^^^^^
86
87error: aborting due to 6 previous errors
88
tests/ui/supertrait-shadowing/false-subtrait-after-inference.rs created+26
......@@ -0,0 +1,26 @@
1#![feature(supertrait_item_shadowing)]
2#![warn(resolving_to_items_shadowing_supertrait_items)]
3#![warn(shadowing_supertrait_items)]
4
5struct W<T>(T);
6
7trait Upstream {
8 fn hello(&self) {}
9}
10impl<T> Upstream for T {}
11
12trait Downstream: Upstream {
13 fn hello(&self) {}
14 //~^ WARN trait item `hello` from `Downstream` shadows identically named item
15}
16impl<T> Downstream for W<T> where T: Foo {}
17
18trait Foo {}
19
20fn main() {
21 let x = W(Default::default());
22 x.hello();
23 //~^ ERROR the trait bound `i32: Foo` is not satisfied
24 //~| WARN trait item `hello` from `Downstream` shadows identically named item from supertrait
25 let _: i32 = x.0;
26}
tests/ui/supertrait-shadowing/false-subtrait-after-inference.stderr created+59
......@@ -0,0 +1,59 @@
1warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
2 --> $DIR/false-subtrait-after-inference.rs:13:5
3 |
4LL | fn hello(&self) {}
5 | ^^^^^^^^^^^^^^^
6 |
7note: item from `Upstream` is shadowed by a subtrait item
8 --> $DIR/false-subtrait-after-inference.rs:8:5
9 |
10LL | fn hello(&self) {}
11 | ^^^^^^^^^^^^^^^
12note: the lint level is defined here
13 --> $DIR/false-subtrait-after-inference.rs:3:9
14 |
15LL | #![warn(shadowing_supertrait_items)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18warning: trait item `hello` from `Downstream` shadows identically named item from supertrait
19 --> $DIR/false-subtrait-after-inference.rs:22:7
20 |
21LL | x.hello();
22 | ^^^^^
23 |
24note: item from `Downstream` shadows a supertrait item
25 --> $DIR/false-subtrait-after-inference.rs:13:5
26 |
27LL | fn hello(&self) {}
28 | ^^^^^^^^^^^^^^^
29note: item from `Upstream` is shadowed by a subtrait item
30 --> $DIR/false-subtrait-after-inference.rs:8:5
31 |
32LL | fn hello(&self) {}
33 | ^^^^^^^^^^^^^^^
34note: the lint level is defined here
35 --> $DIR/false-subtrait-after-inference.rs:2:9
36 |
37LL | #![warn(resolving_to_items_shadowing_supertrait_items)]
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40error[E0277]: the trait bound `i32: Foo` is not satisfied
41 --> $DIR/false-subtrait-after-inference.rs:22:7
42 |
43LL | x.hello();
44 | ^^^^^ the trait `Foo` is not implemented for `i32`
45 |
46help: this trait has no implementations, consider adding one
47 --> $DIR/false-subtrait-after-inference.rs:18:1
48 |
49LL | trait Foo {}
50 | ^^^^^^^^^
51note: required for `W<i32>` to implement `Downstream`
52 --> $DIR/false-subtrait-after-inference.rs:16:9
53 |
54LL | impl<T> Downstream for W<T> where T: Foo {}
55 | ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here
56
57error: aborting due to 1 previous error; 2 warnings emitted
58
59For more information about this error, try `rustc --explain E0277`.
tests/ui/supertrait-shadowing/no-common-ancestor-2.rs created+68
......@@ -0,0 +1,68 @@
1#![feature(supertrait_item_shadowing)]
2#![feature(min_generic_const_args)]
3
4use std::mem::size_of;
5
6trait A {
7 fn hello(&self) -> &'static str {
8 "A"
9 }
10 type Assoc;
11 const CONST: i32;
12}
13impl<T> A for T {
14 type Assoc = i8;
15 const CONST: i32 = 1;
16}
17
18trait B {
19 fn hello(&self) -> &'static str {
20 "B"
21 }
22 type Assoc;
23 const CONST: i32;
24}
25impl<T> B for T {
26 type Assoc = i16;
27 const CONST: i32 = 2;
28}
29
30trait C: A + B {
31 fn hello(&self) -> &'static str {
32 "C"
33 }
34 type Assoc;
35 type const CONST: i32;
36}
37impl<T> C for T {
38 type Assoc = i32;
39 type const CONST: i32 = 3;
40}
41
42// Since `D` is not a subtrait of `C`,
43// we have no obvious lower bound.
44
45trait D: B {
46 fn hello(&self) -> &'static str {
47 "D"
48 }
49 type Assoc;
50 type const CONST: i32;
51}
52impl<T> D for T {
53 type Assoc = i64;
54 type const CONST: i32 = 4;
55}
56
57fn main() {
58 ().hello();
59 //~^ ERROR multiple applicable items in scope
60 check::<()>();
61}
62
63fn check<T: C + D>() {
64 let _ = size_of::<T::Assoc>();
65 //~^ ERROR ambiguous associated type `Assoc` in bounds of `T`
66 let _ = T::CONST;
67 //~^ ERROR multiple applicable items in scope
68}
tests/ui/supertrait-shadowing/no-common-ancestor-2.stderr created+131
......@@ -0,0 +1,131 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/no-common-ancestor-2.rs:58:8
3 |
4LL | ().hello();
5 | ^^^^^ multiple `hello` found
6 |
7note: candidate #1 is defined in an impl of the trait `A` for the type `T`
8 --> $DIR/no-common-ancestor-2.rs:7:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: candidate #2 is defined in an impl of the trait `B` for the type `T`
13 --> $DIR/no-common-ancestor-2.rs:19:5
14 |
15LL | fn hello(&self) -> &'static str {
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17note: candidate #3 is defined in an impl of the trait `C` for the type `T`
18 --> $DIR/no-common-ancestor-2.rs:31:5
19 |
20LL | fn hello(&self) -> &'static str {
21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22note: candidate #4 is defined in an impl of the trait `D` for the type `T`
23 --> $DIR/no-common-ancestor-2.rs:46:5
24 |
25LL | fn hello(&self) -> &'static str {
26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27help: disambiguate the method for candidate #1
28 |
29LL - ().hello();
30LL + A::hello(&());
31 |
32help: disambiguate the method for candidate #2
33 |
34LL - ().hello();
35LL + B::hello(&());
36 |
37help: disambiguate the method for candidate #3
38 |
39LL - ().hello();
40LL + C::hello(&());
41 |
42help: disambiguate the method for candidate #4
43 |
44LL - ().hello();
45LL + D::hello(&());
46 |
47
48error[E0221]: ambiguous associated type `Assoc` in bounds of `T`
49 --> $DIR/no-common-ancestor-2.rs:64:23
50 |
51LL | type Assoc;
52 | ---------- ambiguous `Assoc` from `A`
53...
54LL | type Assoc;
55 | ---------- ambiguous `Assoc` from `B`
56...
57LL | type Assoc;
58 | ---------- ambiguous `Assoc` from `C`
59...
60LL | type Assoc;
61 | ---------- ambiguous `Assoc` from `D`
62...
63LL | let _ = size_of::<T::Assoc>();
64 | ^^^^^^^^ ambiguous associated type `Assoc`
65 |
66help: use fully-qualified syntax to disambiguate
67 |
68LL - let _ = size_of::<T::Assoc>();
69LL + let _ = size_of::<<T as A>::Assoc>();
70 |
71help: use fully-qualified syntax to disambiguate
72 |
73LL - let _ = size_of::<T::Assoc>();
74LL + let _ = size_of::<<T as C>::Assoc>();
75 |
76help: use fully-qualified syntax to disambiguate
77 |
78LL - let _ = size_of::<T::Assoc>();
79LL + let _ = size_of::<<T as B>::Assoc>();
80 |
81help: use fully-qualified syntax to disambiguate
82 |
83LL - let _ = size_of::<T::Assoc>();
84LL + let _ = size_of::<<T as D>::Assoc>();
85 |
86
87error[E0034]: multiple applicable items in scope
88 --> $DIR/no-common-ancestor-2.rs:66:16
89 |
90LL | let _ = T::CONST;
91 | ^^^^^ multiple `CONST` found
92 |
93note: candidate #1 is defined in the trait `A`
94 --> $DIR/no-common-ancestor-2.rs:11:5
95 |
96LL | const CONST: i32;
97 | ^^^^^^^^^^^^^^^^
98note: candidate #2 is defined in the trait `B`
99 --> $DIR/no-common-ancestor-2.rs:23:5
100 |
101LL | const CONST: i32;
102 | ^^^^^^^^^^^^^^^^
103note: candidate #3 is defined in the trait `C`
104 --> $DIR/no-common-ancestor-2.rs:35:5
105 |
106LL | type const CONST: i32;
107 | ^^^^^^^^^^^^^^^^^^^^^
108note: candidate #4 is defined in the trait `D`
109 --> $DIR/no-common-ancestor-2.rs:50:5
110 |
111LL | type const CONST: i32;
112 | ^^^^^^^^^^^^^^^^^^^^^
113help: use fully-qualified syntax to disambiguate
114 |
115LL - let _ = T::CONST;
116LL + let _ = <T as A>::CONST;
117 |
118LL - let _ = T::CONST;
119LL + let _ = <T as B>::CONST;
120 |
121LL - let _ = T::CONST;
122LL + let _ = <T as C>::CONST;
123 |
124LL - let _ = T::CONST;
125LL + let _ = <T as D>::CONST;
126 |
127
128error: aborting due to 3 previous errors
129
130Some errors have detailed explanations: E0034, E0221.
131For more information about an error, try `rustc --explain E0034`.
tests/ui/supertrait-shadowing/no-common-ancestor.rs created+41
......@@ -0,0 +1,41 @@
1#![feature(supertrait_item_shadowing)]
2#![feature(min_generic_const_args)]
3
4use std::mem::size_of;
5
6trait A {
7 fn hello(&self) -> &'static str {
8 "A"
9 }
10 type Assoc;
11 const CONST: i32;
12}
13impl<T> A for T {
14 type Assoc = i8;
15 const CONST: i32 = 1;
16}
17
18trait B {
19 fn hello(&self) -> &'static str {
20 "B"
21 }
22 type Assoc;
23 const CONST: i32;
24}
25impl<T> B for T {
26 type Assoc = i16;
27 const CONST: i32 = 2;
28}
29
30fn main() {
31 ().hello();
32 //~^ ERROR multiple applicable items in scope
33 check::<()>();
34}
35
36fn check<T: A + B>() {
37 let _ = size_of::<T::Assoc>();
38 //~^ ERROR ambiguous associated type `Assoc` in bounds of `T`
39 let _ = T::CONST;
40 //~^ ERROR multiple applicable items in scope
41}
tests/ui/supertrait-shadowing/no-common-ancestor.stderr created+79
......@@ -0,0 +1,79 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/no-common-ancestor.rs:31:8
3 |
4LL | ().hello();
5 | ^^^^^ multiple `hello` found
6 |
7note: candidate #1 is defined in an impl of the trait `A` for the type `T`
8 --> $DIR/no-common-ancestor.rs:7:5
9 |
10LL | fn hello(&self) -> &'static str {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12note: candidate #2 is defined in an impl of the trait `B` for the type `T`
13 --> $DIR/no-common-ancestor.rs:19:5
14 |
15LL | fn hello(&self) -> &'static str {
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17help: disambiguate the method for candidate #1
18 |
19LL - ().hello();
20LL + A::hello(&());
21 |
22help: disambiguate the method for candidate #2
23 |
24LL - ().hello();
25LL + B::hello(&());
26 |
27
28error[E0221]: ambiguous associated type `Assoc` in bounds of `T`
29 --> $DIR/no-common-ancestor.rs:37:23
30 |
31LL | type Assoc;
32 | ---------- ambiguous `Assoc` from `A`
33...
34LL | type Assoc;
35 | ---------- ambiguous `Assoc` from `B`
36...
37LL | let _ = size_of::<T::Assoc>();
38 | ^^^^^^^^ ambiguous associated type `Assoc`
39 |
40help: use fully-qualified syntax to disambiguate
41 |
42LL - let _ = size_of::<T::Assoc>();
43LL + let _ = size_of::<<T as A>::Assoc>();
44 |
45help: use fully-qualified syntax to disambiguate
46 |
47LL - let _ = size_of::<T::Assoc>();
48LL + let _ = size_of::<<T as B>::Assoc>();
49 |
50
51error[E0034]: multiple applicable items in scope
52 --> $DIR/no-common-ancestor.rs:39:16
53 |
54LL | let _ = T::CONST;
55 | ^^^^^ multiple `CONST` found
56 |
57note: candidate #1 is defined in the trait `A`
58 --> $DIR/no-common-ancestor.rs:11:5
59 |
60LL | const CONST: i32;
61 | ^^^^^^^^^^^^^^^^
62note: candidate #2 is defined in the trait `B`
63 --> $DIR/no-common-ancestor.rs:23:5
64 |
65LL | const CONST: i32;
66 | ^^^^^^^^^^^^^^^^
67help: use fully-qualified syntax to disambiguate
68 |
69LL - let _ = T::CONST;
70LL + let _ = <T as A>::CONST;
71 |
72LL - let _ = T::CONST;
73LL + let _ = <T as B>::CONST;
74 |
75
76error: aborting due to 3 previous errors
77
78Some errors have detailed explanations: E0034, E0221.
79For more information about an error, try `rustc --explain E0034`.
tests/ui/supertrait-shadowing/out-of-scope.rs created+42
......@@ -0,0 +1,42 @@
1//@ run-pass
2
3#![feature(min_generic_const_args)]
4#![allow(dead_code)]
5
6use std::mem::size_of;
7
8mod out_of_scope {
9 pub trait Subtrait: super::Supertrait {
10 fn hello(&self) -> &'static str {
11 "subtrait"
12 }
13 type Assoc;
14 type const CONST: i32;
15 }
16 impl<T> Subtrait for T {
17 type Assoc = i16;
18 type const CONST: i32 = 2;
19 }
20}
21
22trait Supertrait {
23 fn hello(&self) -> &'static str {
24 "supertrait"
25 }
26 type Assoc;
27 const CONST: i32;
28}
29impl<T> Supertrait for T {
30 type Assoc = i8;
31 const CONST: i32 = 1;
32}
33
34fn main() {
35 assert_eq!(().hello(), "supertrait");
36 check::<()>();
37}
38
39fn check<T: Supertrait>() {
40 assert_eq!(size_of::<T::Assoc>(), 1);
41 assert_eq!(T::CONST, 1);
42}
tests/ui/supertrait-shadowing/trivially-false-subtrait.rs created+29
......@@ -0,0 +1,29 @@
1//@ run-pass
2
3// Make sure we don't prefer a subtrait that we would've otherwise eliminated
4// in `consider_probe` during method probing.
5
6#![allow(dead_code)]
7
8struct W<T>(T);
9
10trait Upstream {
11 fn hello(&self) -> &'static str {
12 "upstream"
13 }
14}
15impl<T> Upstream for T {}
16
17trait Downstream: Upstream {
18 fn hello(&self) -> &'static str {
19 "downstream"
20 }
21}
22impl<T> Downstream for W<T> where T: Foo {}
23
24trait Foo {}
25
26fn main() {
27 let x = W(1i32);
28 assert_eq!(x.hello(), "upstream");
29}
tests/ui/supertrait-shadowing/type-dependent.rs created+51
......@@ -0,0 +1,51 @@
1//@ run-pass
2
3// Makes sure we can shadow with type-dependent associated item syntax.
4
5#![feature(min_generic_const_args)]
6#![feature(supertrait_item_shadowing)]
7#![allow(dead_code)]
8
9use std::mem::size_of;
10
11trait A {
12 fn hello() -> &'static str {
13 "A"
14 }
15 type Assoc;
16 const CONST: i32;
17}
18impl<T> A for T {
19 type Assoc = i8;
20 const CONST: i32 = 1;
21}
22
23trait B: A {
24 fn hello() -> &'static str {
25 "B"
26 }
27 type Assoc;
28 type const CONST: i32;
29}
30impl<T> B for T {
31 type Assoc = i16;
32 type const CONST: i32 = 2;
33}
34
35fn foo<T>() -> &'static str {
36 T::hello()
37}
38
39fn assoc<T: B>() -> usize {
40 size_of::<T::Assoc>()
41}
42
43fn konst<T: B>() -> i32 {
44 T::CONST
45}
46
47fn main() {
48 assert_eq!(foo::<()>(), "B");
49 assert_eq!(assoc::<()>(), 2);
50 assert_eq!(konst::<()>(), 2);
51}
tests/ui/supertrait-shadowing/unstable.off_normal.stderr created+17
......@@ -0,0 +1,17 @@
1warning: a method with this name may be added to the standard library in the future
2 --> $DIR/unstable.rs:26:19
3 |
4LL | assert_eq!(().hello(), "A");
5 | ^^^^^
6 |
7 = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method
8 = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
9 = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
10 = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default
11help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello`
12 |
13LL + #![feature(downstream)]
14 |
15
16warning: 1 warning emitted
17
tests/ui/supertrait-shadowing/unstable.off_shadowing.stderr created+17
......@@ -0,0 +1,17 @@
1warning: a method with this name may be added to the standard library in the future
2 --> $DIR/unstable.rs:26:19
3 |
4LL | assert_eq!(().hello(), "A");
5 | ^^^^^
6 |
7 = help: call with fully qualified syntax `shadowed_stability::A::hello(...)` to keep using the current method
8 = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
9 = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
10 = note: `#[warn(unstable_name_collisions)]` (part of `#[warn(future_incompatible)]`) on by default
11help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello`
12 |
13LL + #![feature(downstream)]
14 |
15
16warning: 1 warning emitted
17
tests/ui/supertrait-shadowing/unstable.on_normal.stderr created+22
......@@ -0,0 +1,22 @@
1error[E0034]: multiple applicable items in scope
2 --> $DIR/unstable.rs:30:19
3 |
4LL | assert_eq!(().hello(), "B");
5 | ^^^^^ multiple `hello` found
6 |
7 = note: candidate #1 is defined in an impl of the trait `shadowed_stability::A` for the type `T`
8 = note: candidate #2 is defined in an impl of the trait `shadowed_stability::B` for the type `T`
9help: disambiguate the method for candidate #1
10 |
11LL - assert_eq!(().hello(), "B");
12LL + assert_eq!(shadowed_stability::A::hello(&()), "B");
13 |
14help: disambiguate the method for candidate #2
15 |
16LL - assert_eq!(().hello(), "B");
17LL + assert_eq!(shadowed_stability::B::hello(&()), "B");
18 |
19
20error: aborting due to 1 previous error
21
22For more information about this error, try `rustc --explain E0034`.
tests/ui/supertrait-shadowing/unstable.rs created+32
......@@ -0,0 +1,32 @@
1// This tests the interaction of feature staging and supertrait item shadowing.
2// When a feature is *off*, then we should not consider unstable methods for probing.
3// When a feature is *on*, then we follow the normal supertrait item shadowing rules:
4// - When supertrait item shadowing is disabled, this is a clash.
5// - When supertrait item shadowing is enabled, we pick subtraits.
6
7//@ aux-build: shadowed_stability.rs
8//@ revisions: off_normal on_normal off_shadowing on_shadowing
9//@[off_normal] run-pass
10//@[on_normal] check-fail
11//@[off_shadowing] run-pass
12//@[on_shadowing] run-pass
13//@ check-run-results
14
15#![allow(dead_code, unused_features, unused_imports)]
16#![cfg_attr(on_shadowing, feature(downstream))]
17#![cfg_attr(on_normal, feature(downstream))]
18#![cfg_attr(off_shadowing, feature(supertrait_item_shadowing))]
19#![cfg_attr(on_shadowing, feature(supertrait_item_shadowing))]
20
21extern crate shadowed_stability;
22use shadowed_stability::*;
23
24fn main() {
25 #[cfg(any(off_normal, off_shadowing))]
26 assert_eq!(().hello(), "A");
27 //[off_normal,off_shadowing]~^ WARN a method with this name may be added
28 //[off_normal,off_shadowing]~| WARN once this associated item is added
29 #[cfg(any(on_normal, on_shadowing))]
30 assert_eq!(().hello(), "B");
31 //[on_normal]~^ ERROR multiple applicable items in scope
32}
tests/ui/tuple/tuple-bracket-index-suggest-dot.rs created+20
......@@ -0,0 +1,20 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/27842>.
2//! Test we suggest the use of dot syntax when user is trying to index
3//! tuple via square brackets.
4
5fn main() {
6 let tup = (0, 1, 2);
7 // the case where we show a suggestion
8 let _ = tup[0];
9 //~^ ERROR cannot index into a value of type
10
11 // the case where we show just a general hint
12 let i = 0_usize;
13 let _ = tup[i];
14 //~^ ERROR cannot index into a value of type
15
16 // the case where the index is out of bounds
17 let tup = (10,);
18 let _ = tup[3];
19 //~^ ERROR cannot index into a value of type
20}
tests/ui/tuple/tuple-bracket-index-suggest-dot.stderr created+27
......@@ -0,0 +1,27 @@
1error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
2 --> $DIR/tuple-bracket-index-suggest-dot.rs:8:16
3 |
4LL | let _ = tup[0];
5 | ^^^ help: to access tuple element `0`, use: `.0`
6 |
7 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
8
9error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
10 --> $DIR/tuple-bracket-index-suggest-dot.rs:13:16
11 |
12LL | let _ = tup[i];
13 | ^^^
14 |
15 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
16
17error[E0608]: cannot index into a value of type `({integer},)`
18 --> $DIR/tuple-bracket-index-suggest-dot.rs:18:16
19 |
20LL | let _ = tup[3];
21 | ^^^
22 |
23 = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc.
24
25error: aborting due to 3 previous errors
26
27For more information about this error, try `rustc --explain E0608`.
tests/ui/unsafe/unsafe-fn-called-through-ref.rs created+9
......@@ -0,0 +1,9 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/28776>.
2//! Unsafe fn could be called outside of unsafe block through autoderef.
3
4use std::ptr;
5
6fn main() {
7 (&ptr::write)(1 as *mut _, 42);
8 //~^ ERROR E0133
9}
tests/ui/unsafe/unsafe-fn-called-through-ref.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block
2 --> $DIR/unsafe-fn-called-through-ref.rs:7:5
3 |
4LL | (&ptr::write)(1 as *mut _, 42);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
6 |
7 = note: consult the function's documentation for information on how to avoid undefined behavior
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0133`.