| author | bors <bors@rust-lang.org> 2026-06-28 02:37:46 UTC |
| committer | bors <bors@rust-lang.org> 2026-06-28 02:37:46 UTC |
| log | fd07dbfc91b7b6b3fa76d957e130c51e654131ee |
| tree | 090a2604fc3cef2b54a3fd9b3746e779f31b259e |
| parent | 8b95a26baf5820929d86a844317160905e7b325b |
| parent | 2f26f3a0bec4a63d2299ac740a05690c5ff5bc53 |
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(&[ |
| 40 | 40 | Allow(Target::Static), |
| 41 | 41 | Allow(Target::ForeignFn), |
| 42 | 42 | Allow(Target::ForeignStatic), |
| 43 | Allow(Target::ForeignTy), | |
| 43 | 44 | Allow(Target::ExternCrate), |
| 44 | 45 | ]); |
| 45 | 46 |
compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs+1-1| ... | ... | @@ -19,7 +19,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | match intrinsic { |
| 22 | "llvm.prefetch" => { | |
| 22 | "llvm.prefetch.p0" => { | |
| 23 | 23 | // Nothing to do. This is merely a perf hint. |
| 24 | 24 | } |
| 25 | 25 |
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 |
| 1044 | 1044 | #[cfg(feature = "master")] |
| 1045 | 1045 | pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { |
| 1046 | 1046 | let gcc_name = match name { |
| 1047 | "llvm.prefetch" => { | |
| 1047 | "llvm.prefetch.p0" => { | |
| 1048 | 1048 | let gcc_name = "__builtin_prefetch"; |
| 1049 | 1049 | let func = cx.context.get_builtin_function(gcc_name); |
| 1050 | 1050 | 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> { |
| 412 | 412 | let ptr = args[0].immediate(); |
| 413 | 413 | let locality = fn_args.const_at(1).to_leaf().to_i32(); |
| 414 | 414 | self.call_intrinsic( |
| 415 | "llvm.prefetch", | |
| 415 | "llvm.prefetch.p0", | |
| 416 | 416 | &[self.val_ty(ptr)], |
| 417 | 417 | &[ |
| 418 | 418 | ptr, |
compiler/rustc_codegen_ssa/src/back/archive.rs+18-8| ... | ... | @@ -22,7 +22,7 @@ use rustc_target::spec::Arch; |
| 22 | 22 | use tracing::trace; |
| 23 | 23 | |
| 24 | 24 | use super::metadata::{create_compressed_metadata_file, search_for_section}; |
| 25 | use super::rmeta_link; | |
| 25 | use super::rmeta_link::{self, RmetaLinkCache}; | |
| 26 | 26 | use super::symbol_edit::{apply_edits, collect_internal_names}; |
| 27 | 27 | use crate::common; |
| 28 | 28 | // Public for ArchiveBuilderBuilder::extract_bundled_libs |
| ... | ... | @@ -311,7 +311,7 @@ fn find_binutils_dlltool(sess: &Session) -> OsString { |
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | pub enum AddArchiveKind<'a> { |
| 314 | Rlib(/*skip*/ &'a dyn Fn(&str, ArchiveEntryKind) -> bool), | |
| 314 | Rlib(&'a mut RmetaLinkCache, /*skip*/ &'a dyn Fn(&str, ArchiveEntryKind) -> bool), | |
| 315 | 315 | Other, |
| 316 | 316 | } |
| 317 | 317 | |
| ... | ... | @@ -466,7 +466,11 @@ pub fn try_extract_macho_fat_archive( |
| 466 | 466 | } |
| 467 | 467 | |
| 468 | 468 | impl<'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<()> { | |
| 470 | 474 | let mut archive_path = archive_path.to_path_buf(); |
| 471 | 475 | if self.sess.target.llvm_target.contains("-apple-macosx") |
| 472 | 476 | && let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)? |
| ... | ... | @@ -481,8 +485,14 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { |
| 481 | 485 | let archive_map = unsafe { Mmap::map(File::open(&archive_path)?)? }; |
| 482 | 486 | let archive = ArchiveFile::parse(&*archive_map) |
| 483 | 487 | .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 | }), | |
| 486 | 496 | AddArchiveKind::Other => None, |
| 487 | 497 | }; |
| 488 | 498 | let archive_index = self.src_archives.len(); |
| ... | ... | @@ -512,9 +522,9 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { |
| 512 | 522 | } else { |
| 513 | 523 | ArchiveEntryKind::Other |
| 514 | 524 | }; |
| 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, | |
| 518 | 528 | }; |
| 519 | 529 | if !drop { |
| 520 | 530 | let source = if entry.is_thin() { |
compiler/rustc_codegen_ssa/src/back/link.rs+14-2| ... | ... | @@ -59,6 +59,7 @@ use super::archive::{ |
| 59 | 59 | use super::command::Command; |
| 60 | 60 | use super::linker::{self, Linker}; |
| 61 | 61 | use super::metadata::{MetadataPosition, create_wrapper_file}; |
| 62 | use super::rmeta_link::RmetaLinkCache; | |
| 62 | 63 | use super::rpath::{self, RPathConfig}; |
| 63 | 64 | use super::{apple, rmeta_link, versioned_llvm_target}; |
| 64 | 65 | use crate::base::needs_allocator_shim_for_linking; |
| ... | ... | @@ -86,6 +87,7 @@ pub fn link_binary( |
| 86 | 87 | let _timer = sess.timer("link_binary"); |
| 87 | 88 | let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); |
| 88 | 89 | let mut tempfiles_for_stdout_output: Vec<PathBuf> = Vec::new(); |
| 90 | let mut rmeta_link_cache = RmetaLinkCache::default(); | |
| 89 | 91 | for &crate_type in &crate_info.crate_types { |
| 90 | 92 | // Ignore executable crates if we have -Z no-codegen, as they will error. |
| 91 | 93 | if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen()) |
| ... | ... | @@ -139,6 +141,7 @@ pub fn link_binary( |
| 139 | 141 | link_staticlib( |
| 140 | 142 | sess, |
| 141 | 143 | archive_builder_builder, |
| 144 | &mut rmeta_link_cache, | |
| 142 | 145 | &compiled_modules, |
| 143 | 146 | &crate_info, |
| 144 | 147 | &metadata, |
| ... | ... | @@ -150,6 +153,7 @@ pub fn link_binary( |
| 150 | 153 | link_natively( |
| 151 | 154 | sess, |
| 152 | 155 | archive_builder_builder, |
| 156 | &mut rmeta_link_cache, | |
| 153 | 157 | crate_type, |
| 154 | 158 | &out_filename, |
| 155 | 159 | &compiled_modules, |
| ... | ... | @@ -502,6 +506,7 @@ fn link_rlib<'a>( |
| 502 | 506 | fn link_staticlib( |
| 503 | 507 | sess: &Session, |
| 504 | 508 | archive_builder_builder: &dyn ArchiveBuilderBuilder, |
| 509 | rmeta_link_cache: &mut RmetaLinkCache, | |
| 505 | 510 | compiled_modules: &CompiledModules, |
| 506 | 511 | crate_info: &CrateInfo, |
| 507 | 512 | metadata: &EncodedMetadata, |
| ... | ... | @@ -531,7 +536,7 @@ fn link_staticlib( |
| 531 | 536 | let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); |
| 532 | 537 | ab.add_archive( |
| 533 | 538 | path, |
| 534 | AddArchiveKind::Rlib(&|fname: &str, entry_kind| { | |
| 539 | AddArchiveKind::Rlib(rmeta_link_cache, &|fname: &str, entry_kind| { | |
| 535 | 540 | // Ignore metadata and rmeta-link files. |
| 536 | 541 | if fname == METADATA_FILENAME || fname == rmeta_link::FILENAME { |
| 537 | 542 | return true; |
| ... | ... | @@ -939,6 +944,7 @@ fn report_linker_output( |
| 939 | 944 | fn link_natively( |
| 940 | 945 | sess: &Session, |
| 941 | 946 | archive_builder_builder: &dyn ArchiveBuilderBuilder, |
| 947 | rmeta_link_cache: &mut RmetaLinkCache, | |
| 942 | 948 | crate_type: CrateType, |
| 943 | 949 | out_filename: &Path, |
| 944 | 950 | compiled_modules: &CompiledModules, |
| ... | ... | @@ -965,6 +971,7 @@ fn link_natively( |
| 965 | 971 | flavor, |
| 966 | 972 | sess, |
| 967 | 973 | archive_builder_builder, |
| 974 | rmeta_link_cache, | |
| 968 | 975 | crate_type, |
| 969 | 976 | tmpdir, |
| 970 | 977 | temp_filename, |
| ... | ... | @@ -2562,6 +2569,7 @@ fn linker_with_args( |
| 2562 | 2569 | flavor: LinkerFlavor, |
| 2563 | 2570 | sess: &Session, |
| 2564 | 2571 | archive_builder_builder: &dyn ArchiveBuilderBuilder, |
| 2572 | rmeta_link_cache: &mut RmetaLinkCache, | |
| 2565 | 2573 | crate_type: CrateType, |
| 2566 | 2574 | tmpdir: &Path, |
| 2567 | 2575 | out_filename: &Path, |
| ... | ... | @@ -2690,6 +2698,7 @@ fn linker_with_args( |
| 2690 | 2698 | cmd, |
| 2691 | 2699 | sess, |
| 2692 | 2700 | archive_builder_builder, |
| 2701 | rmeta_link_cache, | |
| 2693 | 2702 | crate_info, |
| 2694 | 2703 | crate_type, |
| 2695 | 2704 | tmpdir, |
| ... | ... | @@ -3126,6 +3135,7 @@ fn add_upstream_rust_crates( |
| 3126 | 3135 | cmd: &mut dyn Linker, |
| 3127 | 3136 | sess: &Session, |
| 3128 | 3137 | archive_builder_builder: &dyn ArchiveBuilderBuilder, |
| 3138 | rmeta_link_cache: &mut RmetaLinkCache, | |
| 3129 | 3139 | crate_info: &CrateInfo, |
| 3130 | 3140 | crate_type: CrateType, |
| 3131 | 3141 | tmpdir: &Path, |
| ... | ... | @@ -3178,6 +3188,7 @@ fn add_upstream_rust_crates( |
| 3178 | 3188 | cmd, |
| 3179 | 3189 | sess, |
| 3180 | 3190 | archive_builder_builder, |
| 3191 | rmeta_link_cache, | |
| 3181 | 3192 | crate_info, |
| 3182 | 3193 | tmpdir, |
| 3183 | 3194 | cnum, |
| ... | ... | @@ -3309,6 +3320,7 @@ fn add_static_crate( |
| 3309 | 3320 | cmd: &mut dyn Linker, |
| 3310 | 3321 | sess: &Session, |
| 3311 | 3322 | archive_builder_builder: &dyn ArchiveBuilderBuilder, |
| 3323 | rmeta_link_cache: &mut RmetaLinkCache, | |
| 3312 | 3324 | crate_info: &CrateInfo, |
| 3313 | 3325 | tmpdir: &Path, |
| 3314 | 3326 | cnum: CrateNum, |
| ... | ... | @@ -3339,7 +3351,7 @@ fn add_static_crate( |
| 3339 | 3351 | let mut archive = archive_builder_builder.new_archive_builder(sess); |
| 3340 | 3352 | if let Err(error) = archive.add_archive( |
| 3341 | 3353 | cratepath, |
| 3342 | AddArchiveKind::Rlib(&|f, entry_kind| { | |
| 3354 | AddArchiveKind::Rlib(rmeta_link_cache, &|f, entry_kind| { | |
| 3343 | 3355 | if f == METADATA_FILENAME || f == rmeta_link::FILENAME { |
| 3344 | 3356 | return true; |
| 3345 | 3357 | } |
compiler/rustc_codegen_ssa/src/back/rmeta_link.rs+17-1| ... | ... | @@ -2,9 +2,10 @@ |
| 2 | 2 | //! and potentially other data collected and used when building or linking a rlib. |
| 3 | 3 | //! See <https://github.com/rust-lang/rust/issues/138243>. |
| 4 | 4 | |
| 5 | use std::path::Path; | |
| 5 | use std::path::{Path, PathBuf}; | |
| 6 | 6 | |
| 7 | 7 | use object::read::archive::ArchiveFile; |
| 8 | use rustc_data_structures::fx::FxHashMap; | |
| 8 | 9 | use rustc_serialize::opaque::mem_encoder::MemEncoder; |
| 9 | 10 | use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder}; |
| 10 | 11 | use rustc_serialize::{Decodable, Encodable}; |
| ... | ... | @@ -54,3 +55,18 @@ pub fn read_from_data(archive_data: &[u8], rlib_path: &Path) -> Option<RmetaLink |
| 54 | 55 | let archive = ArchiveFile::parse(archive_data).ok()?; |
| 55 | 56 | read(&archive, archive_data, rlib_path) |
| 56 | 57 | } |
| 58 | ||
| 59 | #[derive(Default)] | |
| 60 | pub struct RmetaLinkCache { | |
| 61 | cache: FxHashMap<PathBuf, Option<RmetaLink>>, | |
| 62 | } | |
| 63 | ||
| 64 | impl 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> + '_ { |
| 409 | 409 | |
| 410 | 410 | pub(super) fn report_ambiguous_assoc_item( |
| 411 | 411 | &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>], | |
| 415 | 413 | qself: AssocItemQSelf, |
| 416 | 414 | assoc_tag: ty::AssocTag, |
| 417 | 415 | assoc_ident: Ident, |
| ... | ... | @@ -443,7 +441,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 443 | 441 | // predicates!). |
| 444 | 442 | // FIXME: Turn this into a structured, translatable & more actionable suggestion. |
| 445 | 443 | let mut where_bounds = vec![]; |
| 446 | for bound in [bound1, bound2].into_iter().chain(matching_candidates) { | |
| 444 | for &bound in matching_candidates { | |
| 447 | 445 | let bound_id = bound.def_id(); |
| 448 | 446 | let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind( |
| 449 | 447 | tcx, |
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+77-3| ... | ... | @@ -24,6 +24,7 @@ use std::{assert_matches, slice}; |
| 24 | 24 | use rustc_abi::FIRST_VARIANT; |
| 25 | 25 | use rustc_ast::LitKind; |
| 26 | 26 | use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; |
| 27 | use rustc_data_structures::sso::SsoHashSet; | |
| 27 | 28 | use rustc_errors::codes::*; |
| 28 | 29 | use rustc_errors::{ |
| 29 | 30 | Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, StashKey, |
| ... | ... | @@ -1262,6 +1263,74 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 1262 | 1263 | ) |
| 1263 | 1264 | } |
| 1264 | 1265 | |
| 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 | ||
| 1265 | 1334 | /// Search for a single trait bound whose trait defines the associated item given by |
| 1266 | 1335 | /// `assoc_ident`. |
| 1267 | 1336 | /// |
| ... | ... | @@ -1296,10 +1365,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 1296 | 1365 | }; |
| 1297 | 1366 | |
| 1298 | 1367 | 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 | ||
| 1299 | 1375 | return Err(self.report_ambiguous_assoc_item( |
| 1300 | bound1, | |
| 1301 | bound2, | |
| 1302 | matching_candidates, | |
| 1376 | &all_matching_candidates, | |
| 1303 | 1377 | qself, |
| 1304 | 1378 | assoc_tag, |
| 1305 | 1379 | assoc_ident, |
compiler/rustc_hir_typeck/src/method/probe.rs+4| ... | ... | @@ -2359,6 +2359,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { |
| 2359 | 2359 | /// multiple conflicting picks if there is one pick whose trait container is a subtrait |
| 2360 | 2360 | /// of the trait containers of all of the other picks. |
| 2361 | 2361 | /// |
| 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 | /// | |
| 2362 | 2366 | /// This implements RFC #3624. |
| 2363 | 2367 | fn collapse_candidates_to_subtrait_pick( |
| 2364 | 2368 | &self, |
compiler/rustc_query_impl/src/handle_cycle_error.rs+1-1| ... | ... | @@ -105,7 +105,7 @@ pub(crate) fn variances_of<'tcx>( |
| 105 | 105 | err: Diag<'_>, |
| 106 | 106 | ) -> &'tcx [ty::Variance] { |
| 107 | 107 | 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(); | |
| 109 | 109 | tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n)) |
| 110 | 110 | } |
| 111 | 111 |
compiler/rustc_resolve/src/check_unused.rs+8-5| ... | ... | @@ -10,9 +10,9 @@ |
| 10 | 10 | // |
| 11 | 11 | // Checking for unused imports is split into three steps: |
| 12 | 12 | // |
| 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 | |
| 16 | 16 | // |
| 17 | 17 | // - `calc_unused_spans` then walks over all the `use` items marked in the |
| 18 | 18 | // previous step to collect the spans associated with the `NodeId`s and to |
| ... | ... | @@ -410,7 +410,7 @@ fn calc_unused_spans( |
| 410 | 410 | } |
| 411 | 411 | |
| 412 | 412 | impl 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>) { | |
| 414 | 414 | let tcx = self.tcx; |
| 415 | 415 | let mut maybe_unused_extern_crates = FxHashMap::default(); |
| 416 | 416 | |
| ... | ... | @@ -465,7 +465,10 @@ impl Resolver<'_, '_> { |
| 465 | 465 | base_id: ast::DUMMY_NODE_ID, |
| 466 | 466 | item_span: DUMMY_SP, |
| 467 | 467 | }; |
| 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 | } | |
| 469 | 472 | |
| 470 | 473 | visitor.report_unused_extern_crate_items(maybe_unused_extern_crates); |
| 471 | 474 |
compiler/rustc_resolve/src/late.rs+17-8| ... | ... | @@ -5623,12 +5623,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |
| 5623 | 5623 | } |
| 5624 | 5624 | |
| 5625 | 5625 | /// Walks the whole crate in DFS order, visiting each item, counting the declared number of |
| 5626 | /// lifetime generic parameters and function parameters. | |
| 5627 | struct 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. | |
| 5628 | struct ItemInfoCollector<'a, 'ast, 'ra, 'tcx> { | |
| 5628 | 5629 | 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>, | |
| 5629 | 5632 | } |
| 5630 | 5633 | |
| 5631 | impl ItemInfoCollector<'_, '_, '_> { | |
| 5634 | impl ItemInfoCollector<'_, '_, '_, '_> { | |
| 5632 | 5635 | fn collect_fn_info(&mut self, decl: &FnDecl, id: NodeId) { |
| 5633 | 5636 | self.r |
| 5634 | 5637 | .delegation_fn_sigs |
| ... | ... | @@ -5662,7 +5665,7 @@ fn required_generic_args_suggestion(generics: &ast::Generics) -> Option<String> |
| 5662 | 5665 | if required.is_empty() { None } else { Some(format!("<{}>", required.join(", "))) } |
| 5663 | 5666 | } |
| 5664 | 5667 | |
| 5665 | impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { | |
| 5668 | impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, 'ast, '_, '_> { | |
| 5666 | 5669 | fn visit_item(&mut self, item: &'ast Item) { |
| 5667 | 5670 | match &item.kind { |
| 5668 | 5671 | ItemKind::TyAlias(TyAlias { generics, .. }) |
| ... | ... | @@ -5695,11 +5698,13 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { |
| 5695 | 5698 | } |
| 5696 | 5699 | } |
| 5697 | 5700 | |
| 5701 | ItemKind::Use(..) | ItemKind::ExternCrate(..) => { | |
| 5702 | self.use_items.push(item); | |
| 5703 | } | |
| 5704 | ||
| 5698 | 5705 | ItemKind::Mod(..) |
| 5699 | 5706 | | ItemKind::Static(..) |
| 5700 | 5707 | | ItemKind::ConstBlock(..) |
| 5701 | | ItemKind::Use(..) | |
| 5702 | | ItemKind::ExternCrate(..) | |
| 5703 | 5708 | | ItemKind::MacroDef(..) |
| 5704 | 5709 | | ItemKind::GlobalAsm(..) |
| 5705 | 5710 | | ItemKind::MacCall(..) |
| ... | ... | @@ -5730,9 +5735,12 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { |
| 5730 | 5735 | } |
| 5731 | 5736 | |
| 5732 | 5737 | impl<'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> { | |
| 5734 | 5740 | 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; | |
| 5736 | 5744 | let mut late_resolution_visitor = LateResolutionVisitor::new(this); |
| 5737 | 5745 | late_resolution_visitor |
| 5738 | 5746 | .resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); |
| ... | ... | @@ -5745,6 +5753,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 5745 | 5753 | crate::diagnostics::UnusedLabel, |
| 5746 | 5754 | ); |
| 5747 | 5755 | } |
| 5756 | use_items | |
| 5748 | 5757 | }) |
| 5749 | 5758 | } |
| 5750 | 5759 | } |
compiler/rustc_resolve/src/lib.rs+3-2| ... | ... | @@ -2082,9 +2082,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { |
| 2082 | 2082 | self.tcx |
| 2083 | 2083 | .sess |
| 2084 | 2084 | .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)); | |
| 2086 | 2087 | 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)); | |
| 2088 | 2089 | self.tcx.sess.time("resolve_report_errors", || self.report_errors(krate)); |
| 2089 | 2090 | self.tcx |
| 2090 | 2091 | .sess |
library/alloc/src/collections/vec_deque/mod.rs+1-1| ... | ... | @@ -267,7 +267,7 @@ impl<T, A: Allocator> VecDeque<T, A> { |
| 267 | 267 | /// |
| 268 | 268 | /// - Ranges must not overlap: `src.abs_diff(dst) >= count`. |
| 269 | 269 | /// - 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`. | |
| 271 | 271 | #[cfg(not(no_global_oom_handling))] |
| 272 | 272 | unsafe fn nonoverlapping_ranges( |
| 273 | 273 | &mut self, |
library/core/src/option.rs+97-3| ... | ... | @@ -581,6 +581,7 @@ |
| 581 | 581 | use crate::clone::TrivialClone; |
| 582 | 582 | use crate::iter::{self, FusedIterator, TrustedLen}; |
| 583 | 583 | use crate::marker::Destruct; |
| 584 | use crate::num::NonZero; | |
| 584 | 585 | use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try}; |
| 585 | 586 | use crate::panicking::{panic, panic_display}; |
| 586 | 587 | use crate::pin::Pin; |
| ... | ... | @@ -2666,18 +2667,111 @@ impl<A: Iterator> Iterator for OptionFlatten<A> { |
| 2666 | 2667 | type Item = A::Item; |
| 2667 | 2668 | |
| 2668 | 2669 | 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 | } | |
| 2670 | 2674 | } |
| 2671 | 2675 | |
| 2672 | 2676 | 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 | } | |
| 2674 | 2730 | } |
| 2675 | 2731 | } |
| 2676 | 2732 | |
| 2677 | 2733 | #[unstable(feature = "option_into_flat_iter", issue = "148441")] |
| 2678 | 2734 | impl<A: DoubleEndedIterator> DoubleEndedIterator for OptionFlatten<A> { |
| 2679 | 2735 | 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 | } | |
| 2681 | 2775 | } |
| 2682 | 2776 | } |
| 2683 | 2777 |
library/stdarch/.github/workflows/main.yml+2| ... | ... | @@ -337,6 +337,8 @@ jobs: |
| 337 | 337 | cargo run --bin=stdarch-gen-loongarch --release -- crates/stdarch-gen-loongarch/lasx.spec |
| 338 | 338 | git diff --exit-code |
| 339 | 339 | - name: Check hexagon |
| 340 | env: | |
| 341 | STDARCH_GEN_MODE: check | |
| 340 | 342 | run: | |
| 341 | 343 | cargo run -p stdarch-gen-hexagon --release |
| 342 | 344 | git diff --exit-code |
library/stdarch/Cargo.lock+87-25| ... | ... | @@ -268,6 +268,22 @@ version = "1.0.2" |
| 268 | 268 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 269 | 269 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" |
| 270 | 270 | |
| 271 | [[package]] | |
| 272 | name = "errno" | |
| 273 | version = "0.3.14" | |
| 274 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 275 | checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" | |
| 276 | dependencies = [ | |
| 277 | "libc", | |
| 278 | "windows-sys", | |
| 279 | ] | |
| 280 | ||
| 281 | [[package]] | |
| 282 | name = "fastrand" | |
| 283 | version = "2.4.1" | |
| 284 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 285 | checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" | |
| 286 | ||
| 271 | 287 | [[package]] |
| 272 | 288 | name = "find-msvc-tools" |
| 273 | 289 | version = "0.1.9" |
| ... | ... | @@ -282,13 +298,14 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" |
| 282 | 298 | |
| 283 | 299 | [[package]] |
| 284 | 300 | name = "getrandom" |
| 285 | version = "0.2.17" | |
| 301 | version = "0.3.4" | |
| 286 | 302 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 287 | checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" | |
| 303 | checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" | |
| 288 | 304 | dependencies = [ |
| 289 | 305 | "cfg-if", |
| 290 | 306 | "libc", |
| 291 | "wasi", | |
| 307 | "r-efi 5.3.0", | |
| 308 | "wasip2", | |
| 292 | 309 | ] |
| 293 | 310 | |
| 294 | 311 | [[package]] |
| ... | ... | @@ -299,7 +316,7 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" |
| 299 | 316 | dependencies = [ |
| 300 | 317 | "cfg-if", |
| 301 | 318 | "libc", |
| 302 | "r-efi", | |
| 319 | "r-efi 6.0.0", | |
| 303 | 320 | "rand_core 0.10.0", |
| 304 | 321 | "wasip2", |
| 305 | 322 | "wasip3", |
| ... | ... | @@ -445,6 +462,12 @@ version = "0.5.6" |
| 445 | 462 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 446 | 463 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" |
| 447 | 464 | |
| 465 | [[package]] | |
| 466 | name = "linux-raw-sys" | |
| 467 | version = "0.12.1" | |
| 468 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 469 | checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" | |
| 470 | ||
| 448 | 471 | [[package]] |
| 449 | 472 | name = "log" |
| 450 | 473 | version = "0.4.29" |
| ... | ... | @@ -457,6 +480,12 @@ version = "2.8.0" |
| 457 | 480 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 458 | 481 | checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" |
| 459 | 482 | |
| 483 | [[package]] | |
| 484 | name = "once_cell" | |
| 485 | version = "1.21.4" | |
| 486 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 487 | checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" | |
| 488 | ||
| 460 | 489 | [[package]] |
| 461 | 490 | name = "once_cell_polyfill" |
| 462 | 491 | version = "1.70.2" |
| ... | ... | @@ -529,7 +558,7 @@ checksum = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b" |
| 529 | 558 | dependencies = [ |
| 530 | 559 | "env_logger 0.11.10", |
| 531 | 560 | "log", |
| 532 | "rand 0.10.0", | |
| 561 | "rand 0.10.1", | |
| 533 | 562 | ] |
| 534 | 563 | |
| 535 | 564 | [[package]] |
| ... | ... | @@ -541,6 +570,12 @@ dependencies = [ |
| 541 | 570 | "proc-macro2", |
| 542 | 571 | ] |
| 543 | 572 | |
| 573 | [[package]] | |
| 574 | name = "r-efi" | |
| 575 | version = "5.3.0" | |
| 576 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 577 | checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" | |
| 578 | ||
| 544 | 579 | [[package]] |
| 545 | 580 | name = "r-efi" |
| 546 | 581 | version = "6.0.0" |
| ... | ... | @@ -549,20 +584,19 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" |
| 549 | 584 | |
| 550 | 585 | [[package]] |
| 551 | 586 | name = "rand" |
| 552 | version = "0.8.5" | |
| 587 | version = "0.9.4" | |
| 553 | 588 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 554 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" | |
| 589 | checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" | |
| 555 | 590 | dependencies = [ |
| 556 | "libc", | |
| 557 | 591 | "rand_chacha", |
| 558 | "rand_core 0.6.4", | |
| 592 | "rand_core 0.9.5", | |
| 559 | 593 | ] |
| 560 | 594 | |
| 561 | 595 | [[package]] |
| 562 | 596 | name = "rand" |
| 563 | version = "0.10.0" | |
| 597 | version = "0.10.1" | |
| 564 | 598 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 565 | checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" | |
| 599 | checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" | |
| 566 | 600 | dependencies = [ |
| 567 | 601 | "getrandom 0.4.2", |
| 568 | 602 | "rand_core 0.10.0", |
| ... | ... | @@ -570,21 +604,21 @@ dependencies = [ |
| 570 | 604 | |
| 571 | 605 | [[package]] |
| 572 | 606 | name = "rand_chacha" |
| 573 | version = "0.3.1" | |
| 607 | version = "0.9.0" | |
| 574 | 608 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 575 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" | |
| 609 | checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" | |
| 576 | 610 | dependencies = [ |
| 577 | 611 | "ppv-lite86", |
| 578 | "rand_core 0.6.4", | |
| 612 | "rand_core 0.9.5", | |
| 579 | 613 | ] |
| 580 | 614 | |
| 581 | 615 | [[package]] |
| 582 | 616 | name = "rand_core" |
| 583 | version = "0.6.4" | |
| 617 | version = "0.9.5" | |
| 584 | 618 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 585 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" | |
| 619 | checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" | |
| 586 | 620 | dependencies = [ |
| 587 | "getrandom 0.2.17", | |
| 621 | "getrandom 0.3.4", | |
| 588 | 622 | ] |
| 589 | 623 | |
| 590 | 624 | [[package]] |
| ... | ... | @@ -648,6 +682,19 @@ version = "0.1.27" |
| 648 | 682 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 649 | 683 | checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" |
| 650 | 684 | |
| 685 | [[package]] | |
| 686 | name = "rustix" | |
| 687 | version = "1.1.4" | |
| 688 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 689 | checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" | |
| 690 | dependencies = [ | |
| 691 | "bitflags", | |
| 692 | "errno", | |
| 693 | "libc", | |
| 694 | "linux-raw-sys", | |
| 695 | "windows-sys", | |
| 696 | ] | |
| 697 | ||
| 651 | 698 | [[package]] |
| 652 | 699 | name = "ryu" |
| 653 | 700 | version = "1.0.23" |
| ... | ... | @@ -787,11 +834,19 @@ dependencies = [ |
| 787 | 834 | "walkdir", |
| 788 | 835 | ] |
| 789 | 836 | |
| 837 | [[package]] | |
| 838 | name = "stdarch-gen-common" | |
| 839 | version = "0.1.0" | |
| 840 | dependencies = [ | |
| 841 | "tempfile", | |
| 842 | ] | |
| 843 | ||
| 790 | 844 | [[package]] |
| 791 | 845 | name = "stdarch-gen-hexagon" |
| 792 | 846 | version = "0.1.0" |
| 793 | 847 | dependencies = [ |
| 794 | 848 | "regex", |
| 849 | "stdarch-gen-common", | |
| 795 | 850 | ] |
| 796 | 851 | |
| 797 | 852 | [[package]] |
| ... | ... | @@ -805,7 +860,7 @@ dependencies = [ |
| 805 | 860 | name = "stdarch-gen-loongarch" |
| 806 | 861 | version = "0.1.0" |
| 807 | 862 | dependencies = [ |
| 808 | "rand 0.8.5", | |
| 863 | "rand 0.9.4", | |
| 809 | 864 | ] |
| 810 | 865 | |
| 811 | 866 | [[package]] |
| ... | ... | @@ -838,7 +893,7 @@ version = "0.0.0" |
| 838 | 893 | dependencies = [ |
| 839 | 894 | "core_arch", |
| 840 | 895 | "quickcheck", |
| 841 | "rand 0.8.5", | |
| 896 | "rand 0.9.4", | |
| 842 | 897 | ] |
| 843 | 898 | |
| 844 | 899 | [[package]] |
| ... | ... | @@ -864,6 +919,19 @@ version = "0.6.18" |
| 864 | 919 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 865 | 920 | checksum = "43d0e35dc7d73976a53c7e6d7d177ef804a0c0ee774ec77bcc520c2216fd7cbe" |
| 866 | 921 | |
| 922 | [[package]] | |
| 923 | name = "tempfile" | |
| 924 | version = "3.27.0" | |
| 925 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 926 | checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" | |
| 927 | dependencies = [ | |
| 928 | "fastrand", | |
| 929 | "getrandom 0.4.2", | |
| 930 | "once_cell", | |
| 931 | "rustix", | |
| 932 | "windows-sys", | |
| 933 | ] | |
| 934 | ||
| 867 | 935 | [[package]] |
| 868 | 936 | name = "termcolor" |
| 869 | 937 | version = "1.4.1" |
| ... | ... | @@ -921,12 +989,6 @@ dependencies = [ |
| 921 | 989 | "winapi-util", |
| 922 | 990 | ] |
| 923 | 991 | |
| 924 | [[package]] | |
| 925 | name = "wasi" | |
| 926 | version = "0.11.1+wasi-snapshot-preview1" | |
| 927 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 928 | checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" | |
| 929 | ||
| 930 | 992 | [[package]] |
| 931 | 993 | name = "wasip2" |
| 932 | 994 | version = "1.0.2+wasi-0.2.9" |
library/stdarch/ci/intrinsic-test.sh+19-12| ... | ... | @@ -1,13 +1,19 @@ |
| 1 | 1 | #!/usr/bin/env sh |
| 2 | 2 | |
| 3 | set -ex | |
| 4 | ||
| 5 | 3 | if [ $# -lt 2 ]; then |
| 6 | >&2 echo "Usage: $0 <TARGET> <CC>" | |
| 4 | >&2 echo "Usage: $0 <TARGET> <CC> <..args for \`cargo test\`..>" | |
| 7 | 5 | exit 1 |
| 8 | 6 | fi |
| 9 | 7 | |
| 10 | case ${2} in | |
| 8 | set -ex | |
| 9 | ||
| 10 | # Pop both arguments and leave "$@" as containing args to be forwarded to `cargo test` | |
| 11 | TARGET="$1" | |
| 12 | shift | |
| 13 | CC_KIND="$1" | |
| 14 | shift | |
| 15 | ||
| 16 | case ${CC_KIND} in | |
| 11 | 17 | clang) |
| 12 | 18 | export CC="${CLANG_PATH}" |
| 13 | 19 | CC_ARG_STYLE=clang |
| ... | ... | @@ -22,7 +28,7 @@ case ${2} in |
| 22 | 28 | CC_ARG_STYLE=clang |
| 23 | 29 | ;; |
| 24 | 30 | *) |
| 25 | >&2 echo "Unknown compiler: ${2}" | |
| 31 | >&2 echo "Unknown compiler: ${CC_KIND}" | |
| 26 | 32 | exit 1 |
| 27 | 33 | ;; |
| 28 | 34 | esac |
| ... | ... | @@ -35,7 +41,7 @@ echo "PROFILE=${PROFILE}" |
| 35 | 41 | |
| 36 | 42 | INTRINSIC_TEST="--manifest-path=crates/intrinsic-test/Cargo.toml" |
| 37 | 43 | |
| 38 | case ${1} in | |
| 44 | case ${TARGET} in | |
| 39 | 45 | aarch64_be*) |
| 40 | 46 | 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" |
| 41 | 47 | ARCH=aarch64_be |
| ... | ... | @@ -60,24 +66,25 @@ case ${1} in |
| 60 | 66 | |
| 61 | 67 | esac |
| 62 | 68 | |
| 63 | case "${1}" in | |
| 69 | case "${TARGET}" in | |
| 64 | 70 | x86_64-unknown-linux-gnu*) |
| 65 | 71 | env -u CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER \ |
| 66 | 72 | cargo run "${INTRINSIC_TEST}" --release \ |
| 67 | 73 | --bin intrinsic-test -- intrinsics_data/x86-intel.xml \ |
| 68 | 74 | --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}" \ | |
| 71 | 77 | --cc-arg-style "${CC_ARG_STYLE}" |
| 72 | 78 | ;; |
| 73 | 79 | *) |
| 74 | 80 | cargo run "${INTRINSIC_TEST}" --release \ |
| 75 | 81 | --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ |
| 76 | 82 | --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}" \ | |
| 79 | 85 | --cc-arg-style "${CC_ARG_STYLE}" |
| 80 | 86 | ;; |
| 81 | 87 | esac |
| 82 | 88 | |
| 83 | cargo test --manifest-path=rust_programs/Cargo.toml --target "${1}" --profile "${PROFILE}" --tests | |
| 89 | cargo 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 |
| 11903 | 11903 | unsafe extern "unadjusted" { |
| 11904 | 11904 | #[cfg_attr( |
| 11905 | 11905 | 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" | |
| 11907 | 11907 | )] |
| 11908 | 11908 | fn _vluti4q_lane_s8(a: int8x16_t, b: uint8x8_t, n: i32) -> int8x16_t; |
| 11909 | 11909 | } |
library/stdarch/crates/core_arch/src/aarch64/prefetch.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | use stdarch_test::assert_instr; |
| 3 | 3 | |
| 4 | 4 | unsafe extern "unadjusted" { |
| 5 | #[link_name = "llvm.prefetch"] | |
| 5 | #[link_name = "llvm.prefetch.p0"] | |
| 6 | 6 | fn prefetch(p: *const i8, rw: i32, loc: i32, ty: i32); |
| 7 | 7 | } |
| 8 | 8 |
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 |
| 1844 | 1844 | #[cfg_attr(test, assert_instr(and))] |
| 1845 | 1845 | pub fn svand_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 1846 | 1846 | 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")] | |
| 1848 | 1848 | fn _svand_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t; |
| 1849 | 1849 | } |
| 1850 | 1850 | 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_ |
| 2936 | 2936 | #[cfg_attr(test, assert_instr(bic))] |
| 2937 | 2937 | pub fn svbic_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 2938 | 2938 | 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")] | |
| 2940 | 2940 | fn _svbic_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t; |
| 2941 | 2941 | } |
| 2942 | 2942 | unsafe { _svbic_b_z(pg, op1, op2) } |
| ... | ... | @@ -4560,7 +4560,7 @@ pub fn svcmla_lane_f32<const IMM_INDEX: i32, const IMM_ROTATION: i32>( |
| 4560 | 4560 | unsafe extern "unadjusted" { |
| 4561 | 4561 | #[cfg_attr( |
| 4562 | 4562 | target_arch = "aarch64", |
| 4563 | link_name = "llvm.aarch64.sve.fcmla.lane.x.nxv4f32" | |
| 4563 | link_name = "llvm.aarch64.sve.fcmla.lane.nxv4f32" | |
| 4564 | 4564 | )] |
| 4565 | 4565 | fn _svcmla_lane_f32( |
| 4566 | 4566 | op1: svfloat32_t, |
| ... | ... | @@ -7658,7 +7658,10 @@ pub fn svcvt_f64_f32_z(pg: svbool_t, op: svfloat32_t) -> svfloat64_t { |
| 7658 | 7658 | #[cfg_attr(test, assert_instr(scvtf))] |
| 7659 | 7659 | pub fn svcvt_f32_s32_m(inactive: svfloat32_t, pg: svbool_t, op: svint32_t) -> svfloat32_t { |
| 7660 | 7660 | 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 | )] | |
| 7662 | 7665 | fn _svcvt_f32_s32_m(inactive: svfloat32_t, pg: svbool4_t, op: svint32_t) -> svfloat32_t; |
| 7663 | 7666 | } |
| 7664 | 7667 | 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 { |
| 7682 | 7685 | svcvt_f32_s32_m(svdup_n_f32(0.0), pg, op) |
| 7683 | 7686 | } |
| 7684 | 7687 | #[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))] | |
| 7693 | pub 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))] | |
| 7709 | pub 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))] | |
| 7718 | pub 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)"] | |
| 7686 | 7723 | #[inline] |
| 7687 | 7724 | #[target_feature(enable = "sve")] |
| 7688 | 7725 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7689 | 7726 | #[cfg_attr(test, assert_instr(scvtf))] |
| 7690 | pub fn svcvt_f32_s64_m(inactive: svfloat32_t, pg: svbool_t, op: svint64_t) -> svfloat32_t { | |
| 7727 | pub fn svcvt_f64_s64_m(inactive: svfloat64_t, pg: svbool_t, op: svint64_t) -> svfloat64_t { | |
| 7691 | 7728 | 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; | |
| 7694 | 7734 | } |
| 7695 | unsafe { _svcvt_f32_s64_m(inactive, pg.sve_into(), op) } | |
| 7735 | unsafe { _svcvt_f64_s64_m(inactive, pg.sve_into(), op) } | |
| 7696 | 7736 | } |
| 7697 | 7737 | #[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)"] | |
| 7699 | 7739 | #[inline] |
| 7700 | 7740 | #[target_feature(enable = "sve")] |
| 7701 | 7741 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7702 | 7742 | #[cfg_attr(test, assert_instr(scvtf))] |
| 7703 | pub fn svcvt_f32_s64_x(pg: svbool_t, op: svint64_t) -> svfloat32_t { | |
| 7704 | unsafe { svcvt_f32_s64_m(transmute_unchecked(op), pg, op) } | |
| 7743 | pub fn svcvt_f64_s64_x(pg: svbool_t, op: svint64_t) -> svfloat64_t { | |
| 7744 | unsafe { svcvt_f64_s64_m(transmute_unchecked(op), pg, op) } | |
| 7705 | 7745 | } |
| 7706 | 7746 | #[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)"] | |
| 7708 | 7748 | #[inline] |
| 7709 | 7749 | #[target_feature(enable = "sve")] |
| 7710 | 7750 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7711 | 7751 | #[cfg_attr(test, assert_instr(scvtf))] |
| 7712 | pub 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) | |
| 7752 | pub 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) | |
| 7714 | 7754 | } |
| 7715 | 7755 | #[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)"] | |
| 7717 | 7757 | #[inline] |
| 7718 | 7758 | #[target_feature(enable = "sve")] |
| 7719 | 7759 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7720 | 7760 | #[cfg_attr(test, assert_instr(ucvtf))] |
| 7721 | pub fn svcvt_f32_u32_m(inactive: svfloat32_t, pg: svbool_t, op: svuint32_t) -> svfloat32_t { | |
| 7761 | pub fn svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool_t, op: svuint64_t) -> svfloat64_t { | |
| 7722 | 7762 | 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; | |
| 7725 | 7768 | } |
| 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()) } | |
| 7727 | 7770 | } |
| 7728 | 7771 | #[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)"] | |
| 7730 | 7773 | #[inline] |
| 7731 | 7774 | #[target_feature(enable = "sve")] |
| 7732 | 7775 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7733 | 7776 | #[cfg_attr(test, assert_instr(ucvtf))] |
| 7734 | pub fn svcvt_f32_u32_x(pg: svbool_t, op: svuint32_t) -> svfloat32_t { | |
| 7735 | unsafe { svcvt_f32_u32_m(transmute_unchecked(op), pg, op) } | |
| 7777 | pub fn svcvt_f64_u64_x(pg: svbool_t, op: svuint64_t) -> svfloat64_t { | |
| 7778 | unsafe { svcvt_f64_u64_m(transmute_unchecked(op), pg, op) } | |
| 7736 | 7779 | } |
| 7737 | 7780 | #[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)"] | |
| 7739 | 7782 | #[inline] |
| 7740 | 7783 | #[target_feature(enable = "sve")] |
| 7741 | 7784 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7742 | 7785 | #[cfg_attr(test, assert_instr(ucvtf))] |
| 7743 | pub 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) | |
| 7786 | pub 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))] | |
| 7795 | pub 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))] | |
| 7808 | pub 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))] | |
| 7817 | pub 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) | |
| 7745 | 7819 | } |
| 7746 | 7820 | #[doc = "Floating-point convert"] |
| 7747 | 7821 | #[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 { |
| 7806 | 7880 | svcvt_f64_s32_m(svdup_n_f64(0.0), pg, op) |
| 7807 | 7881 | } |
| 7808 | 7882 | #[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))] | |
| 7814 | pub 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))] | |
| 7827 | pub 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))] | |
| 7836 | pub 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"] | |
| 7840 | 7883 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svcvt_f64[_u32]_m)"] |
| 7841 | 7884 | #[inline] |
| 7842 | 7885 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -7868,190 +7911,202 @@ pub fn svcvt_f64_u32_z(pg: svbool_t, op: svuint32_t) -> svfloat64_t { |
| 7868 | 7911 | svcvt_f64_u32_m(svdup_n_f64(0.0), pg, op) |
| 7869 | 7912 | } |
| 7870 | 7913 | #[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)"] | |
| 7872 | 7915 | #[inline] |
| 7873 | 7916 | #[target_feature(enable = "sve")] |
| 7874 | 7917 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7875 | #[cfg_attr(test, assert_instr(ucvtf))] | |
| 7876 | pub fn svcvt_f64_u64_m(inactive: svfloat64_t, pg: svbool_t, op: svuint64_t) -> svfloat64_t { | |
| 7918 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7919 | pub fn svcvt_s32_f32_m(inactive: svint32_t, pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7877 | 7920 | 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; | |
| 7880 | 7926 | } |
| 7881 | unsafe { _svcvt_f64_u64_m(inactive, pg.sve_into(), op.as_signed()) } | |
| 7927 | unsafe { _svcvt_s32_f32_m(inactive, pg.sve_into(), op) } | |
| 7882 | 7928 | } |
| 7883 | 7929 | #[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)"] | |
| 7885 | 7931 | #[inline] |
| 7886 | 7932 | #[target_feature(enable = "sve")] |
| 7887 | 7933 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7888 | #[cfg_attr(test, assert_instr(ucvtf))] | |
| 7889 | pub 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))] | |
| 7935 | pub fn svcvt_s32_f32_x(pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7936 | unsafe { svcvt_s32_f32_m(transmute_unchecked(op), pg, op) } | |
| 7891 | 7937 | } |
| 7892 | 7938 | #[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)"] | |
| 7894 | 7940 | #[inline] |
| 7895 | 7941 | #[target_feature(enable = "sve")] |
| 7896 | 7942 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7897 | #[cfg_attr(test, assert_instr(ucvtf))] | |
| 7898 | pub 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))] | |
| 7944 | pub fn svcvt_s32_f32_z(pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7945 | svcvt_s32_f32_m(svdup_n_s32(0), pg, op) | |
| 7900 | 7946 | } |
| 7901 | 7947 | #[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)"] | |
| 7903 | 7949 | #[inline] |
| 7904 | 7950 | #[target_feature(enable = "sve")] |
| 7905 | 7951 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7906 | 7952 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 7907 | pub fn svcvt_s32_f32_m(inactive: svint32_t, pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7953 | pub fn svcvt_s64_f64_m(inactive: svint64_t, pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 7908 | 7954 | 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; | |
| 7911 | 7960 | } |
| 7912 | unsafe { _svcvt_s32_f32_m(inactive, pg.sve_into(), op) } | |
| 7961 | unsafe { _svcvt_s64_f64_m(inactive, pg.sve_into(), op) } | |
| 7913 | 7962 | } |
| 7914 | 7963 | #[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)"] | |
| 7916 | 7965 | #[inline] |
| 7917 | 7966 | #[target_feature(enable = "sve")] |
| 7918 | 7967 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7919 | 7968 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 7920 | pub fn svcvt_s32_f32_x(pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7921 | unsafe { svcvt_s32_f32_m(transmute_unchecked(op), pg, op) } | |
| 7969 | pub fn svcvt_s64_f64_x(pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 7970 | unsafe { svcvt_s64_f64_m(transmute_unchecked(op), pg, op) } | |
| 7922 | 7971 | } |
| 7923 | 7972 | #[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)"] | |
| 7925 | 7974 | #[inline] |
| 7926 | 7975 | #[target_feature(enable = "sve")] |
| 7927 | 7976 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7928 | 7977 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 7929 | pub fn svcvt_s32_f32_z(pg: svbool_t, op: svfloat32_t) -> svint32_t { | |
| 7930 | svcvt_s32_f32_m(svdup_n_s32(0), pg, op) | |
| 7978 | pub fn svcvt_s64_f64_z(pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 7979 | svcvt_s64_f64_m(svdup_n_s64(0), pg, op) | |
| 7931 | 7980 | } |
| 7932 | 7981 | #[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)"] | |
| 7934 | 7983 | #[inline] |
| 7935 | 7984 | #[target_feature(enable = "sve")] |
| 7936 | 7985 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7937 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7938 | pub fn svcvt_s32_f64_m(inactive: svint32_t, pg: svbool_t, op: svfloat64_t) -> svint32_t { | |
| 7986 | #[cfg_attr(test, assert_instr(fcvtzu))] | |
| 7987 | pub fn svcvt_u32_f32_m(inactive: svuint32_t, pg: svbool_t, op: svfloat32_t) -> svuint32_t { | |
| 7939 | 7988 | 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; | |
| 7942 | 7994 | } |
| 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() } | |
| 7944 | 7996 | } |
| 7945 | 7997 | #[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)"] | |
| 7947 | 7999 | #[inline] |
| 7948 | 8000 | #[target_feature(enable = "sve")] |
| 7949 | 8001 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7950 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7951 | pub 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))] | |
| 8003 | pub fn svcvt_u32_f32_x(pg: svbool_t, op: svfloat32_t) -> svuint32_t { | |
| 8004 | unsafe { svcvt_u32_f32_m(transmute_unchecked(op), pg, op) } | |
| 7953 | 8005 | } |
| 7954 | 8006 | #[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)"] | |
| 7956 | 8008 | #[inline] |
| 7957 | 8009 | #[target_feature(enable = "sve")] |
| 7958 | 8010 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7959 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7960 | pub 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))] | |
| 8012 | pub fn svcvt_u32_f32_z(pg: svbool_t, op: svfloat32_t) -> svuint32_t { | |
| 8013 | svcvt_u32_f32_m(svdup_n_u32(0), pg, op) | |
| 7962 | 8014 | } |
| 7963 | 8015 | #[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)"] | |
| 7965 | 8017 | #[inline] |
| 7966 | 8018 | #[target_feature(enable = "sve")] |
| 7967 | 8019 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7968 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7969 | pub fn svcvt_s64_f32_m(inactive: svint64_t, pg: svbool_t, op: svfloat32_t) -> svint64_t { | |
| 8020 | #[cfg_attr(test, assert_instr(fcvtzu))] | |
| 8021 | pub fn svcvt_u64_f64_m(inactive: svuint64_t, pg: svbool_t, op: svfloat64_t) -> svuint64_t { | |
| 7970 | 8022 | 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; | |
| 7973 | 8028 | } |
| 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() } | |
| 7975 | 8030 | } |
| 7976 | 8031 | #[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)"] | |
| 7978 | 8033 | #[inline] |
| 7979 | 8034 | #[target_feature(enable = "sve")] |
| 7980 | 8035 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7981 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7982 | pub 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))] | |
| 8037 | pub fn svcvt_u64_f64_x(pg: svbool_t, op: svfloat64_t) -> svuint64_t { | |
| 8038 | unsafe { svcvt_u64_f64_m(transmute_unchecked(op), pg, op) } | |
| 7984 | 8039 | } |
| 7985 | 8040 | #[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)"] | |
| 7987 | 8042 | #[inline] |
| 7988 | 8043 | #[target_feature(enable = "sve")] |
| 7989 | 8044 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7990 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 7991 | pub 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))] | |
| 8046 | pub fn svcvt_u64_f64_z(pg: svbool_t, op: svfloat64_t) -> svuint64_t { | |
| 8047 | svcvt_u64_f64_m(svdup_n_u64(0), pg, op) | |
| 7993 | 8048 | } |
| 7994 | 8049 | #[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)"] | |
| 7996 | 8051 | #[inline] |
| 7997 | 8052 | #[target_feature(enable = "sve")] |
| 7998 | 8053 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 7999 | 8054 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 8000 | pub fn svcvt_s64_f64_m(inactive: svint64_t, pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 8055 | pub fn svcvt_s32_f64_m(inactive: svint32_t, pg: svbool_t, op: svfloat64_t) -> svint32_t { | |
| 8001 | 8056 | 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; | |
| 8004 | 8059 | } |
| 8005 | unsafe { _svcvt_s64_f64_m(inactive, pg.sve_into(), op) } | |
| 8060 | unsafe { _svcvt_s32_f64_m(inactive, pg.sve_into(), op) } | |
| 8006 | 8061 | } |
| 8007 | 8062 | #[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)"] | |
| 8009 | 8064 | #[inline] |
| 8010 | 8065 | #[target_feature(enable = "sve")] |
| 8011 | 8066 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 8012 | 8067 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 8013 | pub fn svcvt_s64_f64_x(pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 8014 | unsafe { svcvt_s64_f64_m(transmute_unchecked(op), pg, op) } | |
| 8068 | pub fn svcvt_s32_f64_x(pg: svbool_t, op: svfloat64_t) -> svint32_t { | |
| 8069 | unsafe { svcvt_s32_f64_m(transmute_unchecked(op), pg, op) } | |
| 8015 | 8070 | } |
| 8016 | 8071 | #[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)"] | |
| 8018 | 8073 | #[inline] |
| 8019 | 8074 | #[target_feature(enable = "sve")] |
| 8020 | 8075 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 8021 | 8076 | #[cfg_attr(test, assert_instr(fcvtzs))] |
| 8022 | pub fn svcvt_s64_f64_z(pg: svbool_t, op: svfloat64_t) -> svint64_t { | |
| 8023 | svcvt_s64_f64_m(svdup_n_s64(0), pg, op) | |
| 8077 | pub fn svcvt_s32_f64_z(pg: svbool_t, op: svfloat64_t) -> svint32_t { | |
| 8078 | svcvt_s32_f64_m(svdup_n_s32(0), pg, op) | |
| 8024 | 8079 | } |
| 8025 | 8080 | #[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)"] | |
| 8027 | 8082 | #[inline] |
| 8028 | 8083 | #[target_feature(enable = "sve")] |
| 8029 | 8084 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 8030 | #[cfg_attr(test, assert_instr(fcvtzu))] | |
| 8031 | pub fn svcvt_u32_f32_m(inactive: svuint32_t, pg: svbool_t, op: svfloat32_t) -> svuint32_t { | |
| 8085 | #[cfg_attr(test, assert_instr(fcvtzs))] | |
| 8086 | pub fn svcvt_s64_f32_m(inactive: svint64_t, pg: svbool_t, op: svfloat32_t) -> svint64_t { | |
| 8032 | 8087 | 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; | |
| 8035 | 8090 | } |
| 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) } | |
| 8037 | 8092 | } |
| 8038 | 8093 | #[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)"] | |
| 8040 | 8095 | #[inline] |
| 8041 | 8096 | #[target_feature(enable = "sve")] |
| 8042 | 8097 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 8043 | #[cfg_attr(test, assert_instr(fcvtzu))] | |
| 8044 | pub 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))] | |
| 8099 | pub fn svcvt_s64_f32_x(pg: svbool_t, op: svfloat32_t) -> svint64_t { | |
| 8100 | unsafe { svcvt_s64_f32_m(transmute_unchecked(op), pg, op) } | |
| 8046 | 8101 | } |
| 8047 | 8102 | #[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)"] | |
| 8049 | 8104 | #[inline] |
| 8050 | 8105 | #[target_feature(enable = "sve")] |
| 8051 | 8106 | #[unstable(feature = "stdarch_aarch64_sve", issue = "145052")] |
| 8052 | #[cfg_attr(test, assert_instr(fcvtzu))] | |
| 8053 | pub 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))] | |
| 8108 | pub fn svcvt_s64_f32_z(pg: svbool_t, op: svfloat32_t) -> svint64_t { | |
| 8109 | svcvt_s64_f32_m(svdup_n_s64(0), pg, op) | |
| 8055 | 8110 | } |
| 8056 | 8111 | #[doc = "Floating-point convert"] |
| 8057 | 8112 | #[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 { |
| 8115 | 8170 | pub fn svcvt_u64_f32_z(pg: svbool_t, op: svfloat32_t) -> svuint64_t { |
| 8116 | 8171 | svcvt_u64_f32_m(svdup_n_u64(0), pg, op) |
| 8117 | 8172 | } |
| 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))] | |
| 8124 | pub 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))] | |
| 8137 | pub 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))] | |
| 8146 | pub 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 | } | |
| 8149 | 8173 | #[doc = "Divide"] |
| 8150 | 8174 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svdiv[_f32]_m)"] |
| 8151 | 8175 | #[inline] |
| ... | ... | @@ -10041,7 +10065,7 @@ pub fn svdupq_n_u8( |
| 10041 | 10065 | #[cfg_attr(test, assert_instr(eor))] |
| 10042 | 10066 | pub fn sveor_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 10043 | 10067 | 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")] | |
| 10045 | 10069 | fn _sveor_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t; |
| 10046 | 10070 | } |
| 10047 | 10071 | unsafe { _sveor_b_z(pg, op1, op2) } |
| ... | ... | @@ -10592,7 +10616,7 @@ pub fn svexpa_f32(op: svuint32_t) -> svfloat32_t { |
| 10592 | 10616 | unsafe extern "unadjusted" { |
| 10593 | 10617 | #[cfg_attr( |
| 10594 | 10618 | target_arch = "aarch64", |
| 10595 | link_name = "llvm.aarch64.sve.fexpa.x.nxv4f32 " | |
| 10619 | link_name = "llvm.aarch64.sve.fexpa.x.nxv4f32" | |
| 10596 | 10620 | )] |
| 10597 | 10621 | fn _svexpa_f32(op: svint32_t) -> svfloat32_t; |
| 10598 | 10622 | } |
| ... | ... | @@ -10608,7 +10632,7 @@ pub fn svexpa_f64(op: svuint64_t) -> svfloat64_t { |
| 10608 | 10632 | unsafe extern "unadjusted" { |
| 10609 | 10633 | #[cfg_attr( |
| 10610 | 10634 | target_arch = "aarch64", |
| 10611 | link_name = "llvm.aarch64.sve.fexpa.x.nxv2f64 " | |
| 10635 | link_name = "llvm.aarch64.sve.fexpa.x.nxv2f64" | |
| 10612 | 10636 | )] |
| 10613 | 10637 | fn _svexpa_f64(op: svint64_t) -> svfloat64_t; |
| 10614 | 10638 | } |
| ... | ... | @@ -27372,7 +27396,10 @@ pub fn svmls_lane_f64<const IMM_INDEX: i32>( |
| 27372 | 27396 | #[cfg_attr(test, assert_instr(fmmla))] |
| 27373 | 27397 | pub fn svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svfloat32_t { |
| 27374 | 27398 | 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 | )] | |
| 27376 | 27403 | fn _svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svfloat32_t; |
| 27377 | 27404 | } |
| 27378 | 27405 | unsafe { _svmmla_f32(op1, op2, op3) } |
| ... | ... | @@ -27385,7 +27412,10 @@ pub fn svmmla_f32(op1: svfloat32_t, op2: svfloat32_t, op3: svfloat32_t) -> svflo |
| 27385 | 27412 | #[cfg_attr(test, assert_instr(fmmla))] |
| 27386 | 27413 | pub fn svmmla_f64(op1: svfloat64_t, op2: svfloat64_t, op3: svfloat64_t) -> svfloat64_t { |
| 27387 | 27414 | 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 | )] | |
| 27389 | 27419 | fn _svmmla_f64(op1: svfloat64_t, op2: svfloat64_t, op3: svfloat64_t) -> svfloat64_t; |
| 27390 | 27420 | } |
| 27391 | 27421 | unsafe { _svmmla_f64(op1, op2, op3) } |
| ... | ... | @@ -30261,7 +30291,7 @@ pub fn svnot_u64_z(pg: svbool_t, op: svuint64_t) -> svuint64_t { |
| 30261 | 30291 | #[cfg_attr(test, assert_instr(orn))] |
| 30262 | 30292 | pub fn svorn_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 30263 | 30293 | 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")] | |
| 30265 | 30295 | fn _svorn_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t; |
| 30266 | 30296 | } |
| 30267 | 30297 | 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 { |
| 30274 | 30304 | #[cfg_attr(test, assert_instr(orr))] |
| 30275 | 30305 | pub fn svorr_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 30276 | 30306 | 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")] | |
| 30278 | 30308 | fn _svorr_b_z(pg: svbool_t, op1: svbool_t, op2: svbool_t) -> svbool_t; |
| 30279 | 30309 | } |
| 30280 | 30310 | unsafe { _svorr_b_z(pg, op1, op2) } |
| ... | ... | @@ -34341,10 +34371,7 @@ pub fn svrecps_f64(op1: svfloat64_t, op2: svfloat64_t) -> svfloat64_t { |
| 34341 | 34371 | #[cfg_attr(test, assert_instr(frecpx))] |
| 34342 | 34372 | pub fn svrecpx_f32_m(inactive: svfloat32_t, pg: svbool_t, op: svfloat32_t) -> svfloat32_t { |
| 34343 | 34373 | 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")] | |
| 34348 | 34375 | fn _svrecpx_f32_m(inactive: svfloat32_t, pg: svbool4_t, op: svfloat32_t) -> svfloat32_t; |
| 34349 | 34376 | } |
| 34350 | 34377 | 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 { |
| 34375 | 34402 | #[cfg_attr(test, assert_instr(frecpx))] |
| 34376 | 34403 | pub fn svrecpx_f64_m(inactive: svfloat64_t, pg: svbool_t, op: svfloat64_t) -> svfloat64_t { |
| 34377 | 34404 | 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")] | |
| 34382 | 34406 | fn _svrecpx_f64_m(inactive: svfloat64_t, pg: svbool2_t, op: svfloat64_t) -> svfloat64_t; |
| 34383 | 34407 | } |
| 34384 | 34408 | unsafe { _svrecpx_f64_m(inactive, pg.sve_into(), op) } |
| ... | ... | @@ -35202,19 +35226,6 @@ pub fn svreinterpret_u64_u64(op: svuint64_t) -> svuint64_t { |
| 35202 | 35226 | unsafe { crate::intrinsics::transmute_unchecked(op) } |
| 35203 | 35227 | } |
| 35204 | 35228 | #[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))] | |
| 35210 | pub 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"] | |
| 35218 | 35229 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrev_b16)"] |
| 35219 | 35230 | #[inline] |
| 35220 | 35231 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -35222,10 +35233,10 @@ pub fn svrev_b8(op: svbool_t) -> svbool_t { |
| 35222 | 35233 | #[cfg_attr(test, assert_instr(rev))] |
| 35223 | 35234 | pub fn svrev_b16(op: svbool_t) -> svbool_t { |
| 35224 | 35235 | 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; | |
| 35227 | 35238 | } |
| 35228 | unsafe { _svrev_b16(op.sve_into()).sve_into() } | |
| 35239 | unsafe { _svrev_b16(op.sve_into()) } | |
| 35229 | 35240 | } |
| 35230 | 35241 | #[doc = "Reverse all elements"] |
| 35231 | 35242 | #[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 { |
| 35235 | 35246 | #[cfg_attr(test, assert_instr(rev))] |
| 35236 | 35247 | pub fn svrev_b32(op: svbool_t) -> svbool_t { |
| 35237 | 35248 | 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; | |
| 35240 | 35251 | } |
| 35241 | unsafe { _svrev_b32(op.sve_into()).sve_into() } | |
| 35252 | unsafe { _svrev_b32(op.sve_into()) } | |
| 35242 | 35253 | } |
| 35243 | 35254 | #[doc = "Reverse all elements"] |
| 35244 | 35255 | #[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 { |
| 35248 | 35259 | #[cfg_attr(test, assert_instr(rev))] |
| 35249 | 35260 | pub fn svrev_b64(op: svbool_t) -> svbool_t { |
| 35250 | 35261 | 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; | |
| 35253 | 35264 | } |
| 35254 | unsafe { _svrev_b64(op.sve_into()).sve_into() } | |
| 35265 | unsafe { _svrev_b64(op.sve_into()) } | |
| 35255 | 35266 | } |
| 35256 | 35267 | #[doc = "Reverse all elements"] |
| 35257 | 35268 | #[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 { |
| 35367 | 35378 | pub fn svrev_u64(op: svuint64_t) -> svuint64_t { |
| 35368 | 35379 | unsafe { svrev_s64(op.as_signed()).as_unsigned() } |
| 35369 | 35380 | } |
| 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))] | |
| 35387 | pub 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 | } | |
| 35370 | 35394 | #[doc = "Reverse bytes within elements"] |
| 35371 | 35395 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svrevb[_s16]_m)"] |
| 35372 | 35396 | #[inline] |
| ... | ... | @@ -43312,19 +43336,6 @@ pub fn svusmmla_s32(op1: svint32_t, op2: svuint8_t, op3: svint8_t) -> svint32_t |
| 43312 | 43336 | unsafe { _svusmmla_s32(op1, op2.as_signed(), op3) } |
| 43313 | 43337 | } |
| 43314 | 43338 | #[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))] | |
| 43320 | pub 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"] | |
| 43328 | 43339 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1_b16)"] |
| 43329 | 43340 | #[inline] |
| 43330 | 43341 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -43332,10 +43343,10 @@ pub fn svuzp1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43332 | 43343 | #[cfg_attr(test, assert_instr(uzp1))] |
| 43333 | 43344 | pub fn svuzp1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43334 | 43345 | 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; | |
| 43337 | 43348 | } |
| 43338 | unsafe { _svuzp1_b16(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43349 | unsafe { _svuzp1_b16(op1.sve_into(), op2.sve_into()) } | |
| 43339 | 43350 | } |
| 43340 | 43351 | #[doc = "Concatenate even elements from two inputs"] |
| 43341 | 43352 | #[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 { |
| 43345 | 43356 | #[cfg_attr(test, assert_instr(uzp1))] |
| 43346 | 43357 | pub fn svuzp1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43347 | 43358 | 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; | |
| 43350 | 43361 | } |
| 43351 | unsafe { _svuzp1_b32(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43362 | unsafe { _svuzp1_b32(op1.sve_into(), op2.sve_into()) } | |
| 43352 | 43363 | } |
| 43353 | 43364 | #[doc = "Concatenate even elements from two inputs"] |
| 43354 | 43365 | #[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 { |
| 43358 | 43369 | #[cfg_attr(test, assert_instr(uzp1))] |
| 43359 | 43370 | pub fn svuzp1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43360 | 43371 | 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; | |
| 43363 | 43374 | } |
| 43364 | unsafe { _svuzp1_b64(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43375 | unsafe { _svuzp1_b64(op1.sve_into(), op2.sve_into()) } | |
| 43365 | 43376 | } |
| 43366 | 43377 | #[doc = "Concatenate even elements from two inputs"] |
| 43367 | 43378 | #[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 { |
| 43477 | 43488 | pub fn svuzp1_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 43478 | 43489 | unsafe { svuzp1_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 43479 | 43490 | } |
| 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))] | |
| 43497 | pub 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 | } | |
| 43480 | 43504 | #[doc = "Concatenate even quadwords from two inputs"] |
| 43481 | 43505 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp1q[_f32])"] |
| 43482 | 43506 | #[inline] |
| ... | ... | @@ -43592,19 +43616,6 @@ pub fn svuzp1q_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 43592 | 43616 | unsafe { svuzp1q_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 43593 | 43617 | } |
| 43594 | 43618 | #[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))] | |
| 43600 | pub 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"] | |
| 43608 | 43619 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2_b16)"] |
| 43609 | 43620 | #[inline] |
| 43610 | 43621 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -43612,10 +43623,10 @@ pub fn svuzp2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43612 | 43623 | #[cfg_attr(test, assert_instr(uzp2))] |
| 43613 | 43624 | pub fn svuzp2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43614 | 43625 | 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; | |
| 43617 | 43628 | } |
| 43618 | unsafe { _svuzp2_b16(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43629 | unsafe { _svuzp2_b16(op1.sve_into(), op2.sve_into()) } | |
| 43619 | 43630 | } |
| 43620 | 43631 | #[doc = "Concatenate odd elements from two inputs"] |
| 43621 | 43632 | #[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 { |
| 43625 | 43636 | #[cfg_attr(test, assert_instr(uzp2))] |
| 43626 | 43637 | pub fn svuzp2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43627 | 43638 | 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; | |
| 43630 | 43641 | } |
| 43631 | unsafe { _svuzp2_b32(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43642 | unsafe { _svuzp2_b32(op1.sve_into(), op2.sve_into()) } | |
| 43632 | 43643 | } |
| 43633 | 43644 | #[doc = "Concatenate odd elements from two inputs"] |
| 43634 | 43645 | #[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 { |
| 43638 | 43649 | #[cfg_attr(test, assert_instr(uzp2))] |
| 43639 | 43650 | pub fn svuzp2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 43640 | 43651 | 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; | |
| 43643 | 43654 | } |
| 43644 | unsafe { _svuzp2_b64(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 43655 | unsafe { _svuzp2_b64(op1.sve_into(), op2.sve_into()) } | |
| 43645 | 43656 | } |
| 43646 | 43657 | #[doc = "Concatenate odd elements from two inputs"] |
| 43647 | 43658 | #[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 { |
| 43757 | 43768 | pub fn svuzp2_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 43758 | 43769 | unsafe { svuzp2_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 43759 | 43770 | } |
| 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))] | |
| 43777 | pub 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 | } | |
| 43760 | 43784 | #[doc = "Concatenate odd quadwords from two inputs"] |
| 43761 | 43785 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svuzp2q[_f32])"] |
| 43762 | 43786 | #[inline] |
| ... | ... | @@ -44397,19 +44421,6 @@ pub fn svwrffr(op: svbool_t) { |
| 44397 | 44421 | unsafe { _svwrffr(op) } |
| 44398 | 44422 | } |
| 44399 | 44423 | #[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))] | |
| 44405 | pub 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"] | |
| 44413 | 44424 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1_b16)"] |
| 44414 | 44425 | #[inline] |
| 44415 | 44426 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -44417,10 +44428,10 @@ pub fn svzip1_b8(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44417 | 44428 | #[cfg_attr(test, assert_instr(zip1))] |
| 44418 | 44429 | pub fn svzip1_b16(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44419 | 44430 | 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; | |
| 44422 | 44433 | } |
| 44423 | unsafe { _svzip1_b16(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44434 | unsafe { _svzip1_b16(op1.sve_into(), op2.sve_into()) } | |
| 44424 | 44435 | } |
| 44425 | 44436 | #[doc = "Interleave elements from low halves of two inputs"] |
| 44426 | 44437 | #[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 { |
| 44430 | 44441 | #[cfg_attr(test, assert_instr(zip1))] |
| 44431 | 44442 | pub fn svzip1_b32(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44432 | 44443 | 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; | |
| 44435 | 44446 | } |
| 44436 | unsafe { _svzip1_b32(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44447 | unsafe { _svzip1_b32(op1.sve_into(), op2.sve_into()) } | |
| 44437 | 44448 | } |
| 44438 | 44449 | #[doc = "Interleave elements from low halves of two inputs"] |
| 44439 | 44450 | #[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 { |
| 44443 | 44454 | #[cfg_attr(test, assert_instr(zip1))] |
| 44444 | 44455 | pub fn svzip1_b64(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44445 | 44456 | 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; | |
| 44448 | 44459 | } |
| 44449 | unsafe { _svzip1_b64(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44460 | unsafe { _svzip1_b64(op1.sve_into(), op2.sve_into()) } | |
| 44450 | 44461 | } |
| 44451 | 44462 | #[doc = "Interleave elements from low halves of two inputs"] |
| 44452 | 44463 | #[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 { |
| 44562 | 44573 | pub fn svzip1_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 44563 | 44574 | unsafe { svzip1_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 44564 | 44575 | } |
| 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))] | |
| 44582 | pub 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 | } | |
| 44565 | 44589 | #[doc = "Interleave quadwords from low halves of two inputs"] |
| 44566 | 44590 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip1q[_f32])"] |
| 44567 | 44591 | #[inline] |
| ... | ... | @@ -44677,19 +44701,6 @@ pub fn svzip1q_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 44677 | 44701 | unsafe { svzip1q_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 44678 | 44702 | } |
| 44679 | 44703 | #[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))] | |
| 44685 | pub 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"] | |
| 44693 | 44704 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2_b16)"] |
| 44694 | 44705 | #[inline] |
| 44695 | 44706 | #[target_feature(enable = "sve")] |
| ... | ... | @@ -44697,10 +44708,10 @@ pub fn svzip2_b8(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44697 | 44708 | #[cfg_attr(test, assert_instr(zip2))] |
| 44698 | 44709 | pub fn svzip2_b16(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44699 | 44710 | 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; | |
| 44702 | 44713 | } |
| 44703 | unsafe { _svzip2_b16(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44714 | unsafe { _svzip2_b16(op1.sve_into(), op2.sve_into()) } | |
| 44704 | 44715 | } |
| 44705 | 44716 | #[doc = "Interleave elements from high halves of two inputs"] |
| 44706 | 44717 | #[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 { |
| 44710 | 44721 | #[cfg_attr(test, assert_instr(zip2))] |
| 44711 | 44722 | pub fn svzip2_b32(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44712 | 44723 | 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; | |
| 44715 | 44726 | } |
| 44716 | unsafe { _svzip2_b32(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44727 | unsafe { _svzip2_b32(op1.sve_into(), op2.sve_into()) } | |
| 44717 | 44728 | } |
| 44718 | 44729 | #[doc = "Interleave elements from high halves of two inputs"] |
| 44719 | 44730 | #[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 { |
| 44723 | 44734 | #[cfg_attr(test, assert_instr(zip2))] |
| 44724 | 44735 | pub fn svzip2_b64(op1: svbool_t, op2: svbool_t) -> svbool_t { |
| 44725 | 44736 | 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; | |
| 44728 | 44739 | } |
| 44729 | unsafe { _svzip2_b64(op1.sve_into(), op2.sve_into()).sve_into() } | |
| 44740 | unsafe { _svzip2_b64(op1.sve_into(), op2.sve_into()) } | |
| 44730 | 44741 | } |
| 44731 | 44742 | #[doc = "Interleave elements from high halves of two inputs"] |
| 44732 | 44743 | #[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 { |
| 44842 | 44853 | pub fn svzip2_u64(op1: svuint64_t, op2: svuint64_t) -> svuint64_t { |
| 44843 | 44854 | unsafe { svzip2_s64(op1.as_signed(), op2.as_signed()).as_unsigned() } |
| 44844 | 44855 | } |
| 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))] | |
| 44862 | pub 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 | } | |
| 44845 | 44869 | #[doc = "Interleave quadwords from high halves of two inputs"] |
| 44846 | 44870 | #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svzip2q[_f32])"] |
| 44847 | 44871 | #[inline] |
library/stdarch/crates/core_arch/src/aarch64/sve/mod.rs+10-2| ... | ... | @@ -28,6 +28,14 @@ pub(super) trait SveInto<T>: Sized { |
| 28 | 28 | unsafe fn sve_into(self) -> T; |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | impl<T> SveInto<T> for T { | |
| 32 | #[inline] | |
| 33 | #[target_feature(enable = "sve")] | |
| 34 | unsafe fn sve_into(self) -> T { | |
| 35 | self | |
| 36 | } | |
| 37 | } | |
| 38 | ||
| 31 | 39 | macro_rules! impl_sve_type { |
| 32 | 40 | ($(($v:vis, $elem_type:ty, $name:ident, $elt:literal))*) => ($( |
| 33 | 41 | #[doc = concat!("Scalable vector of type ", stringify!($elem_type))] |
| ... | ... | @@ -130,7 +138,7 @@ macro_rules! impl_internal_sve_predicate { |
| 130 | 138 | #[target_feature(enable = "sve")] |
| 131 | 139 | unsafe fn sve_into(self) -> svbool_t { |
| 132 | 140 | #[allow(improper_ctypes)] |
| 133 | unsafe extern "C" { | |
| 141 | unsafe extern "unadjusted" { | |
| 134 | 142 | #[cfg_attr( |
| 135 | 143 | target_arch = "aarch64", |
| 136 | 144 | link_name = concat!("llvm.aarch64.sve.convert.to.svbool.nxv", $elt, "i1") |
| ... | ... | @@ -147,7 +155,7 @@ macro_rules! impl_internal_sve_predicate { |
| 147 | 155 | #[target_feature(enable = "sve")] |
| 148 | 156 | unsafe fn sve_into(self) -> $name { |
| 149 | 157 | #[allow(improper_ctypes)] |
| 150 | unsafe extern "C" { | |
| 158 | unsafe extern "unadjusted" { | |
| 151 | 159 | #[cfg_attr( |
| 152 | 160 | target_arch = "aarch64", |
| 153 | 161 | 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. | |
| 1 | 2 | //! Hexagon HVX 128-byte vector mode intrinsics |
| 2 | 3 | //! |
| 3 | 4 | //! 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. | |
| 1 | 2 | //! Hexagon HVX 64-byte vector mode intrinsics |
| 2 | 3 | //! |
| 3 | 4 | //! 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" { |
| 62 | 62 | |
| 63 | 63 | /// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) |
| 64 | 64 | #[inline(always)] |
| 65 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 65 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 66 | 66 | pub 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) } | |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | /// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) |
| 71 | 71 | #[inline(always)] |
| 72 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 72 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 73 | 73 | pub 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) } | |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | /// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) |
| 78 | 78 | #[inline(always)] |
| 79 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 79 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 80 | 80 | pub fn crc_w_w_w(a: i32, b: i32) -> i32 { |
| 81 | 81 | unsafe { __crc_w_w_w(a, b) } |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | /// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) |
| 85 | 85 | #[inline(always)] |
| 86 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 86 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 87 | 87 | pub fn crc_w_d_w(a: i64, b: i32) -> i32 { |
| 88 | 88 | unsafe { __crc_w_d_w(a, b) } |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | /// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) |
| 92 | 92 | #[inline(always)] |
| 93 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 93 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 94 | 94 | pub 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) } | |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | /// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) |
| 99 | 99 | #[inline(always)] |
| 100 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 100 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 101 | 101 | pub 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) } | |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | /// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) |
| 106 | 106 | #[inline(always)] |
| 107 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 107 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 108 | 108 | pub fn crcc_w_w_w(a: i32, b: i32) -> i32 { |
| 109 | 109 | unsafe { __crcc_w_w_w(a, b) } |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | /// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) |
| 113 | 113 | #[inline(always)] |
| 114 | #[unstable(feature = "stdarch_loongarch", issue = "117427")] | |
| 114 | #[stable(feature = "stdarch_loongarch_crc", since = "CURRENT_RUSTC_VERSION")] | |
| 115 | 115 | pub fn crcc_w_d_w(a: i64, b: i32) -> i32 { |
| 116 | 116 | unsafe { __crcc_w_d_w(a, b) } |
| 117 | 117 | } |
library/stdarch/crates/core_arch/src/mips/msa.rs+1-1| ... | ... | @@ -45,7 +45,7 @@ types! { |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | #[allow(improper_ctypes)] |
| 48 | unsafe extern "C" { | |
| 48 | unsafe extern "unadjusted" { | |
| 49 | 49 | #[link_name = "llvm.mips.add.a.b"] |
| 50 | 50 | fn msa_add_a_b(a: v16i8, b: v16i8) -> v16i8; |
| 51 | 51 | #[link_name = "llvm.mips.add.a.h"] |
library/stdarch/crates/core_arch/src/nvptx/mod.rs+4-4| ... | ... | @@ -19,9 +19,9 @@ mod packed; |
| 19 | 19 | pub use packed::*; |
| 20 | 20 | |
| 21 | 21 | #[allow(improper_ctypes)] |
| 22 | unsafe extern "C" { | |
| 23 | #[link_name = "llvm.nvvm.barrier0"] | |
| 24 | fn syncthreads() -> (); | |
| 22 | unsafe extern "unadjusted" { | |
| 23 | #[link_name = "llvm.nvvm.barrier.cta.sync.aligned.all"] | |
| 24 | fn syncthreads(a: u32) -> (); | |
| 25 | 25 | #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.x"] |
| 26 | 26 | fn block_dim_x() -> u32; |
| 27 | 27 | #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.y"] |
| ... | ... | @@ -54,7 +54,7 @@ unsafe extern "C" { |
| 54 | 54 | #[inline] |
| 55 | 55 | #[unstable(feature = "stdarch_nvptx", issue = "111199")] |
| 56 | 56 | pub unsafe fn _syncthreads() -> () { |
| 57 | syncthreads() | |
| 57 | syncthreads(0) | |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | /// x-th thread-block dimension. |
library/stdarch/crates/core_arch/src/nvptx/packed.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | use crate::intrinsics::simd::*; |
| 8 | 8 | |
| 9 | 9 | #[allow(improper_ctypes)] |
| 10 | unsafe extern "C" { | |
| 10 | unsafe extern "unadjusted" { | |
| 11 | 11 | #[link_name = "llvm.minimum.v2f16"] |
| 12 | 12 | fn llvm_f16x2_minimum(a: f16x2, b: f16x2) -> f16x2; |
| 13 | 13 | #[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 { |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | #[allow(improper_ctypes)] |
| 99 | unsafe extern "C" { | |
| 99 | unsafe extern "unadjusted" { | |
| 100 | 100 | #[link_name = "llvm.ppc.altivec.lvx"] |
| 101 | 101 | fn lvx(p: *const i8) -> vector_unsigned_int; |
| 102 | 102 |
library/stdarch/crates/core_arch/src/powerpc/vsx.rs+1-1| ... | ... | @@ -52,7 +52,7 @@ impl From<vector_bool_long> for m64x2 { |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | #[allow(improper_ctypes)] |
| 55 | unsafe extern "C" { | |
| 55 | unsafe extern "unadjusted" { | |
| 56 | 56 | #[link_name = "llvm.ppc.altivec.vperm"] |
| 57 | 57 | fn vperm( |
| 58 | 58 | a: vector_signed_int, |
library/stdarch/crates/core_arch/src/powerpc64/vsx.rs+1-1| ... | ... | @@ -17,7 +17,7 @@ use stdarch_test::assert_instr; |
| 17 | 17 | use crate::mem::transmute; |
| 18 | 18 | |
| 19 | 19 | #[allow(improper_ctypes)] |
| 20 | unsafe extern "C" { | |
| 20 | unsafe extern "unadjusted" { | |
| 21 | 21 | #[link_name = "llvm.ppc.vsx.lxvl"] |
| 22 | 22 | fn lxvl(a: *const u8, l: usize) -> vector_signed_int; |
| 23 | 23 |
library/stdarch/crates/core_arch/src/wasm32/memory.rs+4-2| ... | ... | @@ -2,9 +2,11 @@ |
| 2 | 2 | use stdarch_test::assert_instr; |
| 3 | 3 | |
| 4 | 4 | unsafe 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")] | |
| 6 | 7 | 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")] | |
| 8 | 10 | fn llvm_memory_size(mem: u32) -> usize; |
| 9 | 11 | } |
| 10 | 12 |
library/stdarch/crates/core_arch/src/x86/aes.rs+1-1| ... | ... | @@ -13,7 +13,7 @@ use crate::core_arch::x86::__m128i; |
| 13 | 13 | use stdarch_test::assert_instr; |
| 14 | 14 | |
| 15 | 15 | #[allow(improper_ctypes)] |
| 16 | unsafe extern "C" { | |
| 16 | unsafe extern "unadjusted" { | |
| 17 | 17 | #[link_name = "llvm.x86.aesni.aesdec"] |
| 18 | 18 | fn aesdec(a: __m128i, round_key: __m128i) -> __m128i; |
| 19 | 19 | #[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 { |
| 3292 | 3292 | |
| 3293 | 3293 | // LLVM intrinsics used in the above functions |
| 3294 | 3294 | #[allow(improper_ctypes)] |
| 3295 | unsafe extern "C" { | |
| 3295 | unsafe extern "unadjusted" { | |
| 3296 | 3296 | #[link_name = "llvm.x86.avx.round.pd.256"] |
| 3297 | 3297 | fn roundpd256(a: __m256d, b: i32) -> __m256d; |
| 3298 | 3298 | #[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 { |
| 3906 | 3906 | } |
| 3907 | 3907 | |
| 3908 | 3908 | #[allow(improper_ctypes)] |
| 3909 | unsafe extern "C" { | |
| 3909 | unsafe extern "unadjusted" { | |
| 3910 | 3910 | #[link_name = "llvm.x86.avx2.pmadd.wd"] |
| 3911 | 3911 | fn pmaddwd(a: i16x16, b: i16x16) -> i32x8; |
| 3912 | 3912 | #[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::*; |
| 9 | 9 | use stdarch_test::assert_instr; |
| 10 | 10 | |
| 11 | 11 | #[allow(improper_ctypes)] |
| 12 | unsafe extern "C" { | |
| 12 | unsafe extern "unadjusted" { | |
| 13 | 13 | #[link_name = "llvm.x86.avx512bf16.cvtne2ps2bf16.128"] |
| 14 | 14 | fn cvtne2ps2bf16(a: f32x4, b: f32x4) -> i16x8; |
| 15 | 15 | #[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; |
| 27 | 27 | use stdarch_test::assert_instr; |
| 28 | 28 | |
| 29 | 29 | #[allow(improper_ctypes)] |
| 30 | unsafe extern "C" { | |
| 30 | unsafe extern "unadjusted" { | |
| 31 | 31 | #[link_name = "llvm.x86.avx512.vpshufbitqmb.512"] |
| 32 | 32 | fn bitshuffle_512(data: i8x64, indices: i8x64) -> __mmask64; |
| 33 | 33 | #[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: |
| 12764 | 12764 | } |
| 12765 | 12765 | |
| 12766 | 12766 | #[allow(improper_ctypes)] |
| 12767 | unsafe extern "C" { | |
| 12767 | unsafe extern "unadjusted" { | |
| 12768 | 12768 | #[link_name = "llvm.x86.avx512.pmul.hr.sw.512"] |
| 12769 | 12769 | fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32; |
| 12770 | 12770 |
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 { |
| 563 | 563 | } |
| 564 | 564 | |
| 565 | 565 | #[allow(improper_ctypes)] |
| 566 | unsafe extern "C" { | |
| 566 | unsafe extern "unadjusted" { | |
| 567 | 567 | #[link_name = "llvm.x86.avx512.conflict.d.512"] |
| 568 | 568 | fn vpconflictd(a: i32x16) -> i32x16; |
| 569 | 569 | #[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 |
| 7235 | 7235 | } |
| 7236 | 7236 | |
| 7237 | 7237 | #[allow(improper_ctypes)] |
| 7238 | unsafe extern "C" { | |
| 7238 | unsafe extern "unadjusted" { | |
| 7239 | 7239 | #[link_name = "llvm.x86.avx512.sitofp.round.v2f64.v2i64"] |
| 7240 | 7240 | fn vcvtqq2pd_128(a: i64x2, rounding: i32) -> f64x2; |
| 7241 | 7241 | #[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; |
| 44215 | 44215 | pub const _MM_PERM_DDDD: _MM_PERM_ENUM = 0xFF; |
| 44216 | 44216 | |
| 44217 | 44217 | #[allow(improper_ctypes)] |
| 44218 | unsafe extern "C" { | |
| 44218 | unsafe extern "unadjusted" { | |
| 44219 | 44219 | #[link_name = "llvm.x86.avx512.sqrt.ps.512"] |
| 44220 | 44220 | fn vsqrtps(a: f32x16, rounding: i32) -> f32x16; |
| 44221 | 44221 | #[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) |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | #[allow(improper_ctypes)] |
| 350 | unsafe extern "C" { | |
| 350 | unsafe extern "unadjusted" { | |
| 351 | 351 | #[link_name = "llvm.x86.avx512.vpmadd52l.uq.128"] |
| 352 | 352 | fn vpmadd52luq_128(z: __m128i, x: __m128i, y: __m128i) -> __m128i; |
| 353 | 353 | #[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) -> |
| 453 | 453 | } |
| 454 | 454 | |
| 455 | 455 | #[allow(improper_ctypes)] |
| 456 | unsafe extern "C" { | |
| 456 | unsafe extern "unadjusted" { | |
| 457 | 457 | #[link_name = "llvm.x86.avx512.vpermi2var.qi.512"] |
| 458 | 458 | fn vpermi2b(a: i8x64, idx: i8x64, b: i8x64) -> i8x64; |
| 459 | 459 | #[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>( |
| 2383 | 2383 | } |
| 2384 | 2384 | |
| 2385 | 2385 | #[allow(improper_ctypes)] |
| 2386 | unsafe extern "C" { | |
| 2386 | unsafe extern "unadjusted" { | |
| 2387 | 2387 | #[link_name = "llvm.x86.avx512.mask.compress.store.w.512"] |
| 2388 | 2388 | fn vcompressstorew(mem: *mut i8, data: i16x32, mask: u32); |
| 2389 | 2389 | #[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 { |
| 873 | 873 | } |
| 874 | 874 | |
| 875 | 875 | #[allow(improper_ctypes)] |
| 876 | unsafe extern "C" { | |
| 876 | unsafe extern "unadjusted" { | |
| 877 | 877 | #[link_name = "llvm.x86.avx512.vpdpwssd.512"] |
| 878 | 878 | fn vpdpwssd(src: i32x16, a: i16x32, b: i16x32) -> i32x16; |
| 879 | 879 | #[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( |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | #[allow(improper_ctypes)] |
| 113 | unsafe extern "C" { | |
| 113 | unsafe extern "unadjusted" { | |
| 114 | 114 | #[link_name = "llvm.x86.avx512.vp2intersect.d.128"] |
| 115 | 115 | fn vp2intersectd_128(a: i32x4, b: i32x4) -> (u8, u8); |
| 116 | 116 | #[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 { |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | #[allow(improper_ctypes)] |
| 179 | unsafe extern "C" { | |
| 179 | unsafe extern "unadjusted" { | |
| 180 | 180 | #[link_name = "llvm.x86.vbcstnebf162ps128"] |
| 181 | 181 | fn bcstnebf162ps_128(a: *const bf16) -> __m128; |
| 182 | 182 | #[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 { |
| 131 | 131 | x.trailing_zeros() as i32 |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | unsafe extern "C" { | |
| 134 | unsafe extern "unadjusted" { | |
| 135 | 135 | #[link_name = "llvm.x86.bmi.bextr.32"] |
| 136 | 136 | fn x86_bmi_bextr_32(x: u32, y: u32) -> u32; |
| 137 | 137 | } |
library/stdarch/crates/core_arch/src/x86/bmi2.rs+1-1| ... | ... | @@ -67,7 +67,7 @@ pub fn _pext_u32(a: u32, mask: u32) -> u32 { |
| 67 | 67 | unsafe { x86_bmi2_pext_32(a, mask) } |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | unsafe extern "C" { | |
| 70 | unsafe extern "unadjusted" { | |
| 71 | 71 | #[link_name = "llvm.x86.bmi.bzhi.32"] |
| 72 | 72 | fn x86_bmi2_bzhi_32(x: u32, y: u32) -> u32; |
| 73 | 73 | #[link_name = "llvm.x86.bmi.pdep.32"] |
library/stdarch/crates/core_arch/src/x86/fxsr.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | use stdarch_test::assert_instr; |
| 5 | 5 | |
| 6 | 6 | #[allow(improper_ctypes)] |
| 7 | unsafe extern "C" { | |
| 7 | unsafe extern "unadjusted" { | |
| 8 | 8 | #[link_name = "llvm.x86.fxsave"] |
| 9 | 9 | fn fxsave(p: *mut u8); |
| 10 | 10 | #[link_name = "llvm.x86.fxrstor"] |
library/stdarch/crates/core_arch/src/x86/gfni.rs+1-1| ... | ... | @@ -23,7 +23,7 @@ use crate::mem::transmute; |
| 23 | 23 | use stdarch_test::assert_instr; |
| 24 | 24 | |
| 25 | 25 | #[allow(improper_ctypes)] |
| 26 | unsafe extern "C" { | |
| 26 | unsafe extern "unadjusted" { | |
| 27 | 27 | #[link_name = "llvm.x86.vgf2p8affineinvqb.512"] |
| 28 | 28 | fn vgf2p8affineinvqb_512(x: i8x64, a: i8x64, imm8: u8) -> i8x64; |
| 29 | 29 | #[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; |
| 11 | 11 | use stdarch_test::assert_instr; |
| 12 | 12 | |
| 13 | 13 | #[allow(improper_ctypes)] |
| 14 | unsafe extern "C" { | |
| 14 | unsafe extern "unadjusted" { | |
| 15 | 15 | #[link_name = "llvm.x86.pclmulqdq"] |
| 16 | 16 | fn pclmulqdq(a: __m128i, round_key: __m128i, imm8: u8) -> __m128i; |
| 17 | 17 | } |
library/stdarch/crates/core_arch/src/x86/rtm.rs+1-1| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | #[cfg(test)] |
| 17 | 17 | use stdarch_test::assert_instr; |
| 18 | 18 | |
| 19 | unsafe extern "C" { | |
| 19 | unsafe extern "unadjusted" { | |
| 20 | 20 | #[link_name = "llvm.x86.xbegin"] |
| 21 | 21 | fn x86_xbegin() -> i32; |
| 22 | 22 | #[link_name = "llvm.x86.xend"] |
library/stdarch/crates/core_arch/src/x86/sha.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | use crate::core_arch::{simd::*, x86::*}; |
| 2 | 2 | |
| 3 | 3 | #[allow(improper_ctypes)] |
| 4 | unsafe extern "C" { | |
| 4 | unsafe extern "unadjusted" { | |
| 5 | 5 | #[link_name = "llvm.x86.sha1msg1"] |
| 6 | 6 | fn sha1msg1(a: i32x4, b: i32x4) -> i32x4; |
| 7 | 7 | #[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( |
| 1987 | 1987 | } |
| 1988 | 1988 | |
| 1989 | 1989 | #[allow(improper_ctypes)] |
| 1990 | unsafe extern "C" { | |
| 1990 | unsafe extern "unadjusted" { | |
| 1991 | 1991 | #[link_name = "llvm.x86.sse.rcp.ss"] |
| 1992 | 1992 | fn rcpss(a: __m128) -> __m128; |
| 1993 | 1993 | #[link_name = "llvm.x86.sse.rcp.ps"] |
| ... | ... | @@ -2040,7 +2040,7 @@ unsafe extern "C" { |
| 2040 | 2040 | fn stmxcsr(p: *mut i8); |
| 2041 | 2041 | #[link_name = "llvm.x86.sse.ldmxcsr"] |
| 2042 | 2042 | fn ldmxcsr(p: *const i8); |
| 2043 | #[link_name = "llvm.prefetch"] | |
| 2043 | #[link_name = "llvm.prefetch.p0"] | |
| 2044 | 2044 | fn prefetch(p: *const i8, rw: i32, loc: i32, ty: i32); |
| 2045 | 2045 | #[link_name = "llvm.x86.sse.cmp.ss"] |
| 2046 | 2046 | 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 { |
| 3242 | 3242 | } |
| 3243 | 3243 | |
| 3244 | 3244 | #[allow(improper_ctypes)] |
| 3245 | unsafe extern "C" { | |
| 3245 | unsafe extern "unadjusted" { | |
| 3246 | 3246 | #[link_name = "llvm.x86.sse2.pause"] |
| 3247 | 3247 | fn pause(); |
| 3248 | 3248 | #[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 { |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | #[allow(improper_ctypes)] |
| 181 | unsafe extern "C" { | |
| 181 | unsafe extern "unadjusted" { | |
| 182 | 182 | #[link_name = "llvm.x86.sse3.ldu.dq"] |
| 183 | 183 | fn lddqu(mem_addr: *const i8) -> i8x16; |
| 184 | 184 | } |
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 { |
| 1181 | 1181 | } |
| 1182 | 1182 | |
| 1183 | 1183 | #[allow(improper_ctypes)] |
| 1184 | unsafe extern "C" { | |
| 1184 | unsafe extern "unadjusted" { | |
| 1185 | 1185 | #[link_name = "llvm.x86.sse41.insertps"] |
| 1186 | 1186 | fn insertps(a: __m128, b: __m128, imm8: u8) -> __m128; |
| 1187 | 1187 | #[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 { |
| 569 | 569 | } |
| 570 | 570 | |
| 571 | 571 | #[allow(improper_ctypes)] |
| 572 | unsafe extern "C" { | |
| 572 | unsafe extern "unadjusted" { | |
| 573 | 573 | // SSE 4.2 string and text comparison ops |
| 574 | 574 | #[link_name = "llvm.x86.sse42.pcmpestrm128"] |
| 575 | 575 | 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::*}; |
| 6 | 6 | use stdarch_test::assert_instr; |
| 7 | 7 | |
| 8 | 8 | #[allow(improper_ctypes)] |
| 9 | unsafe extern "C" { | |
| 9 | unsafe extern "unadjusted" { | |
| 10 | 10 | #[link_name = "llvm.x86.sse4a.extrq"] |
| 11 | 11 | fn extrq(x: i64x2, y: i8x16) -> i64x2; |
| 12 | 12 | #[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 { |
| 345 | 345 | } |
| 346 | 346 | |
| 347 | 347 | #[allow(improper_ctypes)] |
| 348 | unsafe extern "C" { | |
| 348 | unsafe extern "unadjusted" { | |
| 349 | 349 | #[link_name = "llvm.x86.ssse3.pshuf.b.128"] |
| 350 | 350 | fn pshufb128(a: u8x16, b: u8x16) -> u8x16; |
| 351 | 351 |
library/stdarch/crates/core_arch/src/x86/tbm.rs+1-1| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #[cfg(test)] |
| 14 | 14 | use stdarch_test::assert_instr; |
| 15 | 15 | |
| 16 | unsafe extern "C" { | |
| 16 | unsafe extern "unadjusted" { | |
| 17 | 17 | #[link_name = "llvm.x86.tbm.bextri.u32"] |
| 18 | 18 | fn bextri_u32(a: u32, control: u32) -> u32; |
| 19 | 19 | } |
library/stdarch/crates/core_arch/src/x86/vaes.rs+1-1| ... | ... | @@ -14,7 +14,7 @@ use crate::core_arch::x86::__m512i; |
| 14 | 14 | use stdarch_test::assert_instr; |
| 15 | 15 | |
| 16 | 16 | #[allow(improper_ctypes)] |
| 17 | unsafe extern "C" { | |
| 17 | unsafe extern "unadjusted" { | |
| 18 | 18 | #[link_name = "llvm.x86.aesni.aesenc.256"] |
| 19 | 19 | fn aesenc_256(a: __m256i, round_key: __m256i) -> __m256i; |
| 20 | 20 | #[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; |
| 12 | 12 | use stdarch_test::assert_instr; |
| 13 | 13 | |
| 14 | 14 | #[allow(improper_ctypes)] |
| 15 | unsafe extern "C" { | |
| 15 | unsafe extern "unadjusted" { | |
| 16 | 16 | #[link_name = "llvm.x86.pclmulqdq.256"] |
| 17 | 17 | fn pclmulqdq_256(a: __m256i, round_key: __m256i, imm8: u8) -> __m256i; |
| 18 | 18 | #[link_name = "llvm.x86.pclmulqdq.512"] |
library/stdarch/crates/core_arch/src/x86/xsave.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | use stdarch_test::assert_instr; |
| 6 | 6 | |
| 7 | 7 | #[allow(improper_ctypes)] |
| 8 | unsafe extern "C" { | |
| 8 | unsafe extern "unadjusted" { | |
| 9 | 9 | #[link_name = "llvm.x86.xsave"] |
| 10 | 10 | fn xsave(p: *mut u8, hi: u32, lo: u32); |
| 11 | 11 | #[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 { |
| 527 | 527 | } |
| 528 | 528 | |
| 529 | 529 | #[allow(improper_ctypes)] |
| 530 | unsafe extern "C" { | |
| 530 | unsafe extern "unadjusted" { | |
| 531 | 531 | #[link_name = "llvm.x86.avx512.vcvtss2si64"] |
| 532 | 532 | fn vcvtss2si64(a: f32x4, rounding: i32) -> i64; |
| 533 | 533 | #[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 { |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | #[allow(improper_ctypes)] |
| 214 | unsafe extern "C" { | |
| 214 | unsafe extern "unadjusted" { | |
| 215 | 215 | #[link_name = "llvm.x86.avx512fp16.vcvtsi642sh"] |
| 216 | 216 | fn vcvtsi642sh(a: __m128h, b: i64, rounding: i32) -> __m128h; |
| 217 | 217 | #[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 { |
| 122 | 122 | x.trailing_zeros() as i64 |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | unsafe extern "C" { | |
| 125 | unsafe extern "unadjusted" { | |
| 126 | 126 | #[link_name = "llvm.x86.bmi.bextr.64"] |
| 127 | 127 | fn x86_bmi_bextr_64(x: u64, y: u64) -> u64; |
| 128 | 128 | } |
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 { |
| 69 | 69 | unsafe { x86_bmi2_pext_64(a, mask) } |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | unsafe extern "C" { | |
| 72 | unsafe extern "unadjusted" { | |
| 73 | 73 | #[link_name = "llvm.x86.bmi.bzhi.64"] |
| 74 | 74 | fn x86_bmi2_bzhi_64(x: u64, y: u64) -> u64; |
| 75 | 75 | #[link_name = "llvm.x86.bmi.pdep.64"] |
library/stdarch/crates/core_arch/src/x86_64/fxsr.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | use stdarch_test::assert_instr; |
| 5 | 5 | |
| 6 | 6 | #[allow(improper_ctypes)] |
| 7 | unsafe extern "C" { | |
| 7 | unsafe extern "unadjusted" { | |
| 8 | 8 | #[link_name = "llvm.x86.fxsave64"] |
| 9 | 9 | fn fxsave64(p: *mut u8); |
| 10 | 10 | #[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::*; |
| 6 | 6 | use stdarch_test::assert_instr; |
| 7 | 7 | |
| 8 | 8 | #[allow(improper_ctypes)] |
| 9 | unsafe extern "C" { | |
| 9 | unsafe extern "unadjusted" { | |
| 10 | 10 | #[link_name = "llvm.x86.sse.cvtss2si64"] |
| 11 | 11 | fn cvtss2si64(a: __m128) -> i64; |
| 12 | 12 | #[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::*; |
| 6 | 6 | use stdarch_test::assert_instr; |
| 7 | 7 | |
| 8 | 8 | #[allow(improper_ctypes)] |
| 9 | unsafe extern "C" { | |
| 9 | unsafe extern "unadjusted" { | |
| 10 | 10 | #[link_name = "llvm.x86.sse2.cvtsd2si64"] |
| 11 | 11 | fn cvtsd2si64(a: __m128d) -> i64; |
| 12 | 12 | #[link_name = "llvm.x86.sse2.cvttsd2si64"] |
library/stdarch/crates/core_arch/src/x86_64/sse42.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | use stdarch_test::assert_instr; |
| 5 | 5 | |
| 6 | 6 | #[allow(improper_ctypes)] |
| 7 | unsafe extern "C" { | |
| 7 | unsafe extern "unadjusted" { | |
| 8 | 8 | #[link_name = "llvm.x86.sse42.crc32.64.64"] |
| 9 | 9 | fn crc32_64_64(crc: u64, v: u64) -> u64; |
| 10 | 10 | } |
library/stdarch/crates/core_arch/src/x86_64/tbm.rs+1-1| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #[cfg(test)] |
| 14 | 14 | use stdarch_test::assert_instr; |
| 15 | 15 | |
| 16 | unsafe extern "C" { | |
| 16 | unsafe extern "unadjusted" { | |
| 17 | 17 | #[link_name = "llvm.x86.tbm.bextri.u64"] |
| 18 | 18 | fn bextri_u64(a: u64, control: u64) -> u64; |
| 19 | 19 | } |
library/stdarch/crates/core_arch/src/x86_64/xsave.rs+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | use stdarch_test::assert_instr; |
| 7 | 7 | |
| 8 | 8 | #[allow(improper_ctypes)] |
| 9 | unsafe extern "C" { | |
| 9 | unsafe extern "unadjusted" { | |
| 10 | 10 | #[link_name = "llvm.x86.xsave64"] |
| 11 | 11 | fn xsave64(p: *mut u8, hi: u32, lo: u32); |
| 12 | 12 | #[link_name = "llvm.x86.xrstor64"] |
library/stdarch/crates/intrinsic-test/src/arm/config.rs deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | pub 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 | ||
| 6 | pub const PLATFORM_RUST_DEFINITIONS: &str = ""; | |
| 7 | ||
| 8 | pub 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"))] | |
| 22 | use core_arch::arch::aarch64::*; | |
| 23 | ||
| 24 | #[cfg(target_arch = "arm")] | |
| 25 | use 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; |
| 2 | 2 | use std::ops::{Deref, DerefMut}; |
| 3 | 3 | |
| 4 | 4 | #[derive(Debug, Clone, PartialEq)] |
| 5 | pub struct ArmIntrinsicType(pub IntrinsicType); | |
| 5 | pub struct ArmType(pub IntrinsicType); | |
| 6 | 6 | |
| 7 | impl Deref for ArmIntrinsicType { | |
| 7 | impl Deref for ArmType { | |
| 8 | 8 | type Target = IntrinsicType; |
| 9 | 9 | |
| 10 | 10 | fn deref(&self) -> &Self::Target { |
| ... | ... | @@ -12,7 +12,7 @@ impl Deref for ArmIntrinsicType { |
| 12 | 12 | } |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | impl DerefMut for ArmIntrinsicType { | |
| 15 | impl DerefMut for ArmType { | |
| 16 | 16 | fn deref_mut(&mut self) -> &mut Self::Target { |
| 17 | 17 | &mut self.0 |
| 18 | 18 | } |
library/stdarch/crates/intrinsic-test/src/arm/json_parser.rs+9-11| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | use super::intrinsic::ArmIntrinsicType; | |
| 1 | use super::intrinsic::ArmType; | |
| 2 | use crate::arm::Arm; | |
| 2 | 3 | use crate::arm::types::parse_intrinsic_type; |
| 3 | 4 | use crate::common::argument::{Argument, ArgumentList}; |
| 4 | 5 | use crate::common::constraint::Constraint; |
| ... | ... | @@ -59,7 +60,7 @@ struct JsonIntrinsic { |
| 59 | 60 | |
| 60 | 61 | pub fn get_neon_intrinsics( |
| 61 | 62 | filename: &Path, |
| 62 | ) -> Result<Vec<Intrinsic<ArmIntrinsicType>>, Box<dyn std::error::Error>> { | |
| 63 | ) -> Result<Vec<Intrinsic<Arm>>, Box<dyn std::error::Error>> { | |
| 63 | 64 | let file = std::fs::File::open(filename)?; |
| 64 | 65 | let reader = std::io::BufReader::new(file); |
| 65 | 66 | let json: Vec<JsonIntrinsic> = serde_json::from_reader(reader).expect("Couldn't parse JSON"); |
| ... | ... | @@ -79,10 +80,10 @@ pub fn get_neon_intrinsics( |
| 79 | 80 | |
| 80 | 81 | fn json_to_intrinsic( |
| 81 | 82 | mut intr: JsonIntrinsic, |
| 82 | ) -> Result<Intrinsic<ArmIntrinsicType>, Box<dyn std::error::Error>> { | |
| 83 | ) -> Result<Intrinsic<Arm>, Box<dyn std::error::Error>> { | |
| 83 | 84 | let name = intr.name.replace(['[', ']'], ""); |
| 84 | 85 | |
| 85 | let result_ty = ArmIntrinsicType(parse_intrinsic_type(&intr.return_type.value)?); | |
| 86 | let result_ty = ArmType(parse_intrinsic_type(&intr.return_type.value)?); | |
| 86 | 87 | |
| 87 | 88 | let args = intr |
| 88 | 89 | .arguments |
| ... | ... | @@ -120,12 +121,8 @@ fn json_to_intrinsic( |
| 120 | 121 | } |
| 121 | 122 | }); |
| 122 | 123 | |
| 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); | |
| 129 | 126 | |
| 130 | 127 | // The JSON doesn't list immediates as const |
| 131 | 128 | let IntrinsicType { |
| ... | ... | @@ -138,13 +135,14 @@ fn json_to_intrinsic( |
| 138 | 135 | }) |
| 139 | 136 | .collect(); |
| 140 | 137 | |
| 141 | let arguments = ArgumentList::<ArmIntrinsicType> { args }; | |
| 138 | let arguments = ArgumentList::<Arm> { args }; | |
| 142 | 139 | |
| 143 | 140 | Ok(Intrinsic { |
| 144 | 141 | name, |
| 145 | 142 | arguments, |
| 146 | 143 | results: result_ty, |
| 147 | 144 | arch_tags: intr.architectures, |
| 145 | extension: intr.simd_isa, | |
| 148 | 146 | }) |
| 149 | 147 | } |
| 150 | 148 |
library/stdarch/crates/intrinsic-test/src/arm/mod.rs+98-18| ... | ... | @@ -1,42 +1,48 @@ |
| 1 | mod config; | |
| 2 | 1 | mod intrinsic; |
| 3 | 2 | mod json_parser; |
| 4 | 3 | mod types; |
| 5 | 4 | |
| 6 | use crate::common::SupportedArchitectureTest; | |
| 5 | use crate::common::SupportedArchitecture; | |
| 7 | 6 | use crate::common::cli::{CcArgStyle, ProcessedCli}; |
| 8 | 7 | use crate::common::intrinsic::Intrinsic; |
| 9 | use crate::common::intrinsic_helpers::TypeKind; | |
| 10 | use intrinsic::ArmIntrinsicType; | |
| 8 | use crate::common::intrinsic_helpers::{SimdLen, TypeKind}; | |
| 9 | use intrinsic::ArmType; | |
| 11 | 10 | use json_parser::get_neon_intrinsics; |
| 12 | 11 | |
| 13 | pub struct ArmArchitectureTest { | |
| 14 | intrinsics: Vec<Intrinsic<ArmIntrinsicType>>, | |
| 15 | } | |
| 12 | #[derive(PartialEq)] | |
| 13 | pub struct Arm(Vec<Intrinsic<Arm>>); | |
| 16 | 14 | |
| 17 | impl SupportedArchitectureTest for ArmArchitectureTest { | |
| 18 | type IntrinsicImpl = ArmIntrinsicType; | |
| 15 | impl SupportedArchitecture for Arm { | |
| 16 | type Type = ArmType; | |
| 19 | 17 | |
| 20 | fn intrinsics(&self) -> &[Intrinsic<ArmIntrinsicType>] { | |
| 21 | &self.intrinsics | |
| 18 | fn intrinsics(&self) -> &[Intrinsic<Self>] { | |
| 19 | &self.0 | |
| 22 | 20 | } |
| 23 | 21 | |
| 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 | "#; | |
| 27 | 27 | |
| 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; | |
| 30 | 34 | |
| 31 | fn arch_flags(&self, cli_options: &ProcessedCli) -> Vec<&str> { | |
| 35 | fn c_compiler_flags(&self, cli_options: &ProcessedCli) -> Vec<&str> { | |
| 32 | 36 | // GCC uses an extra `-` in the arch name |
| 33 | 37 | match cli_options.cc_arg_style { |
| 34 | 38 | 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 | |
| 35 | 40 | CcArgStyle::Gcc => vec!["-march=armv8.6-a+crypto+crc+dotprod+fp16+sha3+sm4"], |
| 36 | 41 | } |
| 37 | 42 | } |
| 38 | 43 | |
| 39 | 44 | fn create(cli_options: &ProcessedCli) -> Self { |
| 45 | let big_endian = cli_options.target.starts_with("aarch64_be"); | |
| 40 | 46 | let a32 = cli_options.target.starts_with("armv7"); |
| 41 | 47 | let mut intrinsics = |
| 42 | 48 | get_neon_intrinsics(&cli_options.filename).expect("Error parsing input file"); |
| ... | ... | @@ -54,6 +60,53 @@ impl SupportedArchitectureTest for ArmArchitectureTest { |
| 54 | 60 | // Skip bfloat intrinsics - not currently supported |
| 55 | 61 | .filter(|i| i.results.kind() != TypeKind::BFloat) |
| 56 | 62 | .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_"))) | |
| 57 | 110 | // Skip pointers for now, we would probably need to look at the return |
| 58 | 111 | // type to work out how many elements we need to point to. |
| 59 | 112 | .filter(|i| !i.arguments.iter().any(|a| a.is_ptr())) |
| ... | ... | @@ -63,9 +116,36 @@ impl SupportedArchitectureTest for ArmArchitectureTest { |
| 63 | 116 | .filter(|i| !cli_options.skip.contains(&i.name)) |
| 64 | 117 | // Skip A64-specific intrinsics on A32 |
| 65 | 118 | .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 | }) | |
| 66 | 127 | .take(sample_size) |
| 67 | 128 | .collect::<Vec<_>>(); |
| 68 | 129 | |
| 69 | Self { intrinsics } | |
| 130 | Self(intrinsics) | |
| 70 | 131 | } |
| 71 | 132 | } |
| 133 | ||
| 134 | const 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"))] | |
| 147 | use core_arch::arch::aarch64::*; | |
| 148 | ||
| 149 | #[cfg(target_arch = "arm")] | |
| 150 | use core_arch::arch::arm::*; | |
| 151 | "#; |
library/stdarch/crates/intrinsic-test/src/arm/types.rs+57-35| ... | ... | @@ -1,28 +1,37 @@ |
| 1 | use super::intrinsic::ArmIntrinsicType; | |
| 2 | use crate::common::intrinsic_helpers::{ | |
| 3 | IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind, | |
| 4 | }; | |
| 1 | use super::intrinsic::ArmType; | |
| 2 | use crate::common::intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind}; | |
| 5 | 3 | |
| 6 | impl IntrinsicTypeDefinition for ArmIntrinsicType { | |
| 4 | impl TypeDefinition for ArmType { | |
| 7 | 5 | /// Gets a string containing the typename for this type in C format. |
| 8 | 6 | fn c_type(&self) -> String { |
| 9 | 7 | let prefix = self.kind.c_prefix(); |
| 10 | 8 | |
| 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}") | |
| 23 | 13 | } |
| 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:#?}"), | |
| 26 | 35 | } |
| 27 | 36 | } |
| 28 | 37 | |
| ... | ... | @@ -30,26 +39,39 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { |
| 30 | 39 | let rust_prefix = self.kind.rust_prefix(); |
| 31 | 40 | let c_prefix = self.kind.c_prefix(); |
| 32 | 41 | |
| 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}") | |
| 45 | 48 | } |
| 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:#?}"), | |
| 48 | 70 | } |
| 49 | 71 | } |
| 50 | 72 | |
| 51 | 73 | /// Determines the load function for this type. |
| 52 | fn get_load_function(&self) -> String { | |
| 74 | fn load_function(&self) -> String { | |
| 53 | 75 | if let IntrinsicType { |
| 54 | 76 | kind: k, |
| 55 | 77 | bit_len: Some(bl), |
| ... | ... | @@ -73,7 +95,7 @@ impl IntrinsicTypeDefinition for ArmIntrinsicType { |
| 73 | 95 | len = vec_len.unwrap_or(1), |
| 74 | 96 | ) |
| 75 | 97 | } else { |
| 76 | todo!("get_load_function IntrinsicType: {self:#?}") | |
| 98 | todo!("load_function IntrinsicType: {self:#?}") | |
| 77 | 99 | } |
| 78 | 100 | } |
| 79 | 101 | } |
library/stdarch/crates/intrinsic-test/src/common/argument.rs+15-14| ... | ... | @@ -1,30 +1,31 @@ |
| 1 | 1 | use itertools::Itertools; |
| 2 | 2 | |
| 3 | use crate::common::SupportedArchitecture; | |
| 3 | 4 | use crate::common::intrinsic_helpers::TypeKind; |
| 4 | 5 | use crate::common::values::test_values_array_name; |
| 5 | 6 | |
| 6 | 7 | use super::PASSES; |
| 7 | 8 | use super::constraint::Constraint; |
| 8 | use super::intrinsic_helpers::IntrinsicTypeDefinition; | |
| 9 | use super::intrinsic_helpers::TypeDefinition; | |
| 9 | 10 | |
| 10 | 11 | /// An argument for the intrinsic. |
| 11 | 12 | #[derive(Debug, PartialEq, Clone)] |
| 12 | pub struct Argument<T: IntrinsicTypeDefinition> { | |
| 13 | pub struct Argument<A: SupportedArchitecture> { | |
| 13 | 14 | /// The argument's index in the intrinsic function call. |
| 14 | 15 | pub pos: usize, |
| 15 | 16 | /// The argument name. |
| 16 | 17 | pub name: String, |
| 17 | 18 | /// The type of the argument. |
| 18 | pub ty: T, | |
| 19 | pub ty: A::Type, | |
| 19 | 20 | /// Any constraints that are on this argument |
| 20 | 21 | pub constraint: Option<Constraint>, |
| 21 | 22 | } |
| 22 | 23 | |
| 23 | impl<T> Argument<T> | |
| 24 | impl<A> Argument<A> | |
| 24 | 25 | where |
| 25 | T: IntrinsicTypeDefinition, | |
| 26 | A: SupportedArchitecture, | |
| 26 | 27 | { |
| 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 { | |
| 28 | 29 | Argument { |
| 29 | 30 | pos, |
| 30 | 31 | name, |
| ... | ... | @@ -63,13 +64,13 @@ where |
| 63 | 64 | |
| 64 | 65 | /// Arguments of an intrinsic - including parameters that end up being const generics. |
| 65 | 66 | #[derive(Debug, PartialEq, Clone)] |
| 66 | pub struct ArgumentList<T: IntrinsicTypeDefinition> { | |
| 67 | pub args: Vec<Argument<T>>, | |
| 67 | pub struct ArgumentList<A: SupportedArchitecture> { | |
| 68 | pub args: Vec<Argument<A>>, | |
| 68 | 69 | } |
| 69 | 70 | |
| 70 | impl<T> ArgumentList<T> | |
| 71 | impl<A> ArgumentList<A> | |
| 71 | 72 | where |
| 72 | T: IntrinsicTypeDefinition, | |
| 73 | A: SupportedArchitecture, | |
| 73 | 74 | { |
| 74 | 75 | /// Returns a string with the arguments in `self` as a parameter list for a wrapper fn |
| 75 | 76 | /// definition in C (e.g. `$ty1 $arg1, $ty2 $arg2`). |
| ... | ... | @@ -179,14 +180,14 @@ where |
| 179 | 180 | .map(|(idx, arg)| { |
| 180 | 181 | if arg.is_simd() { |
| 181 | 182 | 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 _);", | |
| 183 | 184 | name = arg.generate_name(), |
| 184 | 185 | vals_name = test_values_array_name(&arg.ty), |
| 185 | load = arg.ty.get_load_function(), | |
| 186 | load = arg.ty.load_function(), | |
| 186 | 187 | ) |
| 187 | 188 | } else { |
| 188 | 189 | format!( |
| 189 | "let {name} = {vals_name}[(i+{idx}) % {PASSES}];\n", | |
| 190 | "let {name} = {vals_name}[(i+{idx}) % {PASSES}];", | |
| 190 | 191 | name = arg.generate_name(), |
| 191 | 192 | vals_name = test_values_array_name(&arg.ty), |
| 192 | 193 | ) |
| ... | ... | @@ -196,7 +197,7 @@ where |
| 196 | 197 | } |
| 197 | 198 | |
| 198 | 199 | /// 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>> { | |
| 200 | 201 | self.args.iter() |
| 201 | 202 | } |
| 202 | 203 | } |
library/stdarch/crates/intrinsic-test/src/common/gen_c.rs+6-11| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | use itertools::Itertools; |
| 2 | 2 | |
| 3 | use crate::common::intrinsic::Intrinsic; | |
| 3 | use crate::common::{SupportedArchitecture, intrinsic::Intrinsic}; | |
| 4 | 4 | |
| 5 | use super::intrinsic_helpers::IntrinsicTypeDefinition; | |
| 5 | use super::intrinsic_helpers::TypeDefinition; | |
| 6 | 6 | |
| 7 | 7 | /// Generates a C source file containing wrapper functions around each specialisation of each |
| 8 | 8 | /// intrinsic (that is, intrinsics with specific values for the the immediate arguments). Each |
| ... | ... | @@ -14,20 +14,15 @@ use super::intrinsic_helpers::IntrinsicTypeDefinition; |
| 14 | 14 | /// *__dst = __crc32cd(a, b); |
| 15 | 15 | /// } |
| 16 | 16 | /// ``` |
| 17 | pub fn write_wrapper_c<T: IntrinsicTypeDefinition>( | |
| 17 | pub fn write_wrapper_c<A: SupportedArchitecture>( | |
| 18 | 18 | w: &mut impl std::io::Write, |
| 19 | notice: &str, | |
| 20 | platform_headers: &[&str], | |
| 21 | intrinsics: &[Intrinsic<T>], | |
| 19 | intrinsics: &[Intrinsic<A>], | |
| 22 | 20 | ) -> std::io::Result<()> { |
| 23 | write!(w, "{notice}")?; | |
| 21 | write!(w, "{}", A::NOTICE)?; | |
| 24 | 22 | |
| 25 | 23 | writeln!(w, "#include <stdint.h>")?; |
| 26 | 24 | writeln!(w, "#include <stddef.h>")?; |
| 27 | ||
| 28 | for header in platform_headers { | |
| 29 | writeln!(w, "#include <{header}>")?; | |
| 30 | } | |
| 25 | writeln!(w, "{}", A::C_PRELUDE)?; | |
| 31 | 26 | |
| 32 | 27 | for intrinsic in intrinsics { |
| 33 | 28 | 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; |
| 2 | 2 | |
| 3 | 3 | use itertools::Itertools; |
| 4 | 4 | |
| 5 | use super::intrinsic_helpers::IntrinsicTypeDefinition; | |
| 6 | use crate::common::PASSES; | |
| 5 | use super::intrinsic_helpers::TypeDefinition; | |
| 7 | 6 | use crate::common::cli::{CcArgStyle, ProcessedCli}; |
| 8 | 7 | use crate::common::intrinsic::Intrinsic; |
| 9 | use crate::common::intrinsic_helpers::TypeKind; | |
| 10 | 8 | use crate::common::values::{test_values_array_name, test_values_array_static}; |
| 9 | use crate::common::{PASSES, SupportedArchitecture}; | |
| 11 | 10 | |
| 12 | 11 | /// Rust definitions that are included verbatim in the generated source. In particular, defines |
| 13 | 12 | /// a wrapper around float types that defines `NaN`s to be equal reflexively to enable |
| ... | ... | @@ -32,12 +31,6 @@ macro_rules! wrap_partialeq { |
| 32 | 31 | wrap_partialeq!(NanEqF16(f16), NanEqF32(f32), NanEqF64(f64)); |
| 33 | 32 | "#; |
| 34 | 33 | |
| 35 | macro_rules! concatln { | |
| 36 | ($($lines:expr),* $(,)?) => { | |
| 37 | concat!($( $lines, "\n" ),*) | |
| 38 | }; | |
| 39 | } | |
| 40 | ||
| 41 | 34 | /// Run rustfmt on the generated source code |
| 42 | 35 | pub fn run_rustfmt(source_path: &str) { |
| 43 | 36 | let output = Command::new("rustfmt") |
| ... | ... | @@ -65,11 +58,14 @@ pub fn write_bin_cargo_toml( |
| 65 | 58 | w: &mut impl std::io::Write, |
| 66 | 59 | module_count: usize, |
| 67 | 60 | ) -> 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] | |
| 65 | members = [{members}] | |
| 66 | "#, | |
| 67 | members = (0..module_count).format_with(",", |i, fmt| fmt(&format_args!("\"mod_{i}\""))) | |
| 68 | ) | |
| 73 | 69 | } |
| 74 | 70 | |
| 75 | 71 | /// 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( |
| 77 | 73 | pub fn write_lib_cargo_toml(w: &mut impl std::io::Write, name: &str) -> std::io::Result<()> { |
| 78 | 74 | write!( |
| 79 | 75 | 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] | |
| 78 | name = "{name}" | |
| 79 | version = "{version}" | |
| 80 | authors = [{authors}] | |
| 81 | license = "{license}" | |
| 82 | edition = "2018" | |
| 83 | ||
| 84 | [dependencies] | |
| 85 | core_arch = {{ path = "../../crates/core_arch" }} | |
| 86 | ||
| 87 | [build-dependencies] | |
| 88 | cc = "1" | |
| 89 | "#, | |
| 95 | 90 | version = env!("CARGO_PKG_VERSION"), |
| 96 | 91 | authors = env!("CARGO_PKG_AUTHORS") |
| 97 | 92 | .split(":") |
| ... | ... | @@ -102,30 +97,30 @@ pub fn write_lib_cargo_toml(w: &mut impl std::io::Write, name: &str) -> std::io: |
| 102 | 97 | |
| 103 | 98 | /// Writes a Rust source file into `w` with common definitions, static arrays with test values, |
| 104 | 99 | /// declarations of C wrapper functions for FFI and Rust test functions. |
| 105 | pub fn write_lib_rs<T: IntrinsicTypeDefinition>( | |
| 100 | pub fn write_lib_rs<A: SupportedArchitecture>( | |
| 106 | 101 | w: &mut impl std::io::Write, |
| 107 | notice: &str, | |
| 108 | cfg: &str, | |
| 109 | definitions: &str, | |
| 110 | 102 | i: usize, |
| 111 | intrinsics: &[Intrinsic<T>], | |
| 103 | intrinsics: &[Intrinsic<A>], | |
| 112 | 104 | ) -> 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 | )?; | |
| 129 | 124 | |
| 130 | 125 | let mut seen = std::collections::HashSet::new(); |
| 131 | 126 | |
| ... | ... | @@ -157,9 +152,9 @@ pub fn write_lib_rs<T: IntrinsicTypeDefinition>( |
| 157 | 152 | /// (first loop) `PASSES` number of times (second loop). For a given iteration of a given |
| 158 | 153 | /// specialisation, test values are loaded for each argument and passed to the Rust intrinsic |
| 159 | 154 | /// and the C wrapper function, and the results are compared. |
| 160 | fn generate_rust_test_loop<T: IntrinsicTypeDefinition>( | |
| 155 | fn generate_rust_test_loop<A: SupportedArchitecture>( | |
| 161 | 156 | w: &mut impl std::io::Write, |
| 162 | intrinsic: &Intrinsic<T>, | |
| 157 | intrinsic: &Intrinsic<A>, | |
| 163 | 158 | ) -> std::io::Result<()> { |
| 164 | 159 | let intrinsic_name = &intrinsic.name; |
| 165 | 160 | |
| ... | ... | @@ -199,67 +194,45 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>( |
| 199 | 194 | writeln!(w, " ];")?; |
| 200 | 195 | } |
| 201 | 196 | |
| 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 | ||
| 225 | 197 | write!( |
| 226 | 198 | 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#" | |
| 200 | for (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 | "#, | |
| 243 | 215 | loaded_args = intrinsic.arguments.load_values_rust(), |
| 244 | 216 | rust_args = intrinsic.arguments.as_call_param_rust(), |
| 245 | 217 | 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(), | |
| 249 | 219 | ) |
| 250 | 220 | } |
| 251 | 221 | |
| 252 | 222 | /// Writes a test function for an given intrinsic to `w`, with a body generated by |
| 253 | 223 | /// `generate_rust_test_loop`. |
| 254 | fn create_rust_test<T: IntrinsicTypeDefinition>( | |
| 224 | fn create_rust_test<A: SupportedArchitecture>( | |
| 255 | 225 | w: &mut impl std::io::Write, |
| 256 | intrinsic: &Intrinsic<T>, | |
| 226 | intrinsic: &Intrinsic<A>, | |
| 257 | 227 | ) -> std::io::Result<()> { |
| 258 | 228 | trace!("generating `{}`", intrinsic.name); |
| 259 | 229 | |
| 260 | 230 | write!( |
| 261 | 231 | w, |
| 262 | concatln!("#[test]", "fn test_{intrinsic_name}() {{"), | |
| 232 | r#" | |
| 233 | #[test] | |
| 234 | fn test_{intrinsic_name}() {{ | |
| 235 | "#, | |
| 263 | 236 | intrinsic_name = intrinsic.name, |
| 264 | 237 | )?; |
| 265 | 238 | |
| ... | ... | @@ -272,26 +245,25 @@ fn create_rust_test<T: IntrinsicTypeDefinition>( |
| 272 | 245 | |
| 273 | 246 | /// Writes an `extern "C"` block with function declarations for each of the C wrapper functions into |
| 274 | 247 | /// `w`. |
| 275 | pub fn write_bindings_rust<T: IntrinsicTypeDefinition>( | |
| 248 | pub fn write_bindings_rust<A: SupportedArchitecture>( | |
| 276 | 249 | w: &mut impl std::io::Write, |
| 277 | 250 | i: usize, |
| 278 | intrinsics: &[Intrinsic<T>], | |
| 251 | intrinsics: &[Intrinsic<A>], | |
| 279 | 252 | ) -> std::io::Result<()> { |
| 280 | 253 | write!( |
| 281 | 254 | 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}")] | |
| 258 | unsafe extern "C" {{ | |
| 259 | "#, | |
| 288 | 260 | )?; |
| 289 | 261 | |
| 290 | 262 | for intrinsic in intrinsics { |
| 291 | 263 | intrinsic.iter_specializations(|imm_values| { |
| 292 | 264 | writeln!( |
| 293 | 265 | w, |
| 294 | " fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});", | |
| 266 | "fn {name}_wrapper{imm_arglist}(__dst: *mut {return_ty}{arglist});", | |
| 295 | 267 | return_ty = intrinsic.results.rust_type(), |
| 296 | 268 | name = intrinsic.name, |
| 297 | 269 | imm_arglist = imm_values |
| ... | ... | @@ -326,32 +298,22 @@ pub fn write_build_rs( |
| 326 | 298 | |
| 327 | 299 | write!( |
| 328 | 300 | 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#" | |
| 302 | fn 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}\""))), | |
| 356 | 318 | ) |
| 357 | 319 | } |
library/stdarch/crates/intrinsic-test/src/common/intrinsic.rs+8-7| ... | ... | @@ -1,22 +1,23 @@ |
| 1 | use crate::common::constraint::Constraint; | |
| 2 | ||
| 3 | 1 | use super::argument::ArgumentList; |
| 4 | use super::intrinsic_helpers::IntrinsicTypeDefinition; | |
| 2 | use crate::common::{SupportedArchitecture, constraint::Constraint}; | |
| 5 | 3 | |
| 6 | 4 | /// An intrinsic |
| 7 | 5 | #[derive(Debug, PartialEq, Clone)] |
| 8 | pub struct Intrinsic<T: IntrinsicTypeDefinition> { | |
| 6 | pub struct Intrinsic<A: SupportedArchitecture> { | |
| 9 | 7 | /// The function name of this intrinsic. |
| 10 | 8 | pub name: String, |
| 11 | 9 | |
| 12 | 10 | /// Any arguments for this intrinsic. |
| 13 | pub arguments: ArgumentList<T>, | |
| 11 | pub arguments: ArgumentList<A>, | |
| 14 | 12 | |
| 15 | 13 | /// The return type of this intrinsic. |
| 16 | pub results: T, | |
| 14 | pub results: A::Type, | |
| 17 | 15 | |
| 18 | 16 | /// Any architecture-specific tags. |
| 19 | 17 | pub arch_tags: Vec<String>, |
| 18 | ||
| 19 | /// Specific extension that the intrinsic is from | |
| 20 | pub extension: String, | |
| 20 | 21 | } |
| 21 | 22 | |
| 22 | 23 | /// Invokes `f` for each combination of the values in the constraint ranges. |
| ... | ... | @@ -40,7 +41,7 @@ fn recurse_specializations<'a, E>( |
| 40 | 41 | } |
| 41 | 42 | } |
| 42 | 43 | |
| 43 | impl<T: IntrinsicTypeDefinition> Intrinsic<T> { | |
| 44 | impl<A: SupportedArchitecture> Intrinsic<A> { | |
| 44 | 45 | /// Invokes `f` for "specialisation" of the intrinsic - a specific instantiation of the |
| 45 | 46 | /// constant generics of the intrinsic. `f` takes a slice where the `i`th element corresponds |
| 46 | 47 | /// 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 @@ |
| 1 | 1 | use std::cmp; |
| 2 | 2 | use std::fmt; |
| 3 | use std::ops::Deref; | |
| 3 | use std::ops::DerefMut; | |
| 4 | 4 | use std::str::FromStr; |
| 5 | 5 | |
| 6 | 6 | #[derive(Debug, PartialEq, Copy, Clone)] |
| ... | ... | @@ -90,9 +90,13 @@ impl TypeKind { |
| 90 | 90 | } |
| 91 | 91 | } |
| 92 | 92 | |
| 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. | |
| 94 | 95 | pub fn rust_prefix(&self) -> &str { |
| 95 | 96 | match self { |
| 97 | Self::Bool => "bool", | |
| 98 | Self::SvPattern => "svpattern", | |
| 99 | Self::SvPrefetchOp => "svprfop", | |
| 96 | 100 | Self::BFloat => "bf", |
| 97 | 101 | Self::Float => "f", |
| 98 | 102 | Self::Int(Sign::Signed) => "i", |
| ... | ... | @@ -101,7 +105,7 @@ impl TypeKind { |
| 101 | 105 | Self::Char(Sign::Unsigned) => "u", |
| 102 | 106 | Self::Char(Sign::Signed) => "i", |
| 103 | 107 | Self::Mask => "u", |
| 104 | _ => unreachable!("Unused type kind: {self:#?}"), | |
| 108 | _ => unreachable!("type kind without Rust prefix: {self:#?}"), | |
| 105 | 109 | } |
| 106 | 110 | } |
| 107 | 111 | } |
| ... | ... | @@ -195,9 +199,19 @@ impl IntrinsicType { |
| 195 | 199 | } |
| 196 | 200 | } |
| 197 | 201 | |
| 198 | pub trait IntrinsicTypeDefinition: Deref<Target = IntrinsicType> { | |
| 202 | pub trait TypeDefinition: Clone + DerefMut<Target = IntrinsicType> { | |
| 199 | 203 | /// 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 | } | |
| 201 | 215 | |
| 202 | 216 | /// Gets a string containing the typename for this type in C. |
| 203 | 217 | fn c_type(&self) -> String; |
| ... | ... | @@ -208,14 +222,49 @@ pub trait IntrinsicTypeDefinition: Deref<Target = IntrinsicType> { |
| 208 | 222 | /// Gets a string containing the name of the scalar type corresponding to this type if it is a |
| 209 | 223 | /// vector. |
| 210 | 224 | 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() | |
| 220 | 229 | } |
| 221 | 230 | } |
| 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. | |
| 234 | pub(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#" | |
| 263 | assert_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::{ |
| 10 | 10 | run_rustfmt, write_bin_cargo_toml, write_build_rs, write_lib_cargo_toml, write_lib_rs, |
| 11 | 11 | }, |
| 12 | 12 | intrinsic::Intrinsic, |
| 13 | intrinsic_helpers::IntrinsicTypeDefinition, | |
| 13 | intrinsic_helpers::TypeDefinition, | |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | 16 | pub mod argument; |
| ... | ... | @@ -29,21 +29,19 @@ pub(crate) const PASSES: u32 = 20; |
| 29 | 29 | |
| 30 | 30 | /// Architectures must support this trait |
| 31 | 31 | /// to be successfully tested. |
| 32 | pub trait SupportedArchitectureTest { | |
| 33 | type IntrinsicImpl: IntrinsicTypeDefinition + Sync; | |
| 32 | pub trait SupportedArchitecture: Sized { | |
| 33 | type Type: TypeDefinition + std::fmt::Debug + PartialEq + Sync; | |
| 34 | 34 | |
| 35 | fn intrinsics(&self) -> &[Intrinsic<Self::IntrinsicImpl>]; | |
| 35 | fn intrinsics(&self) -> &[Intrinsic<Self>]; | |
| 36 | 36 | |
| 37 | 37 | fn create(cli_options: &ProcessedCli) -> Self; |
| 38 | 38 | |
| 39 | 39 | const NOTICE: &str; |
| 40 | 40 | |
| 41 | const PLATFORM_C_HEADERS: &[&str]; | |
| 41 | const C_PRELUDE: &str; | |
| 42 | const RUST_PRELUDE: &str; | |
| 42 | 43 | |
| 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>; | |
| 47 | 45 | |
| 48 | 46 | fn generate_c_file(&self) { |
| 49 | 47 | let (max_chunk_size, _chunk_count) = manual_chunk(self.intrinsics().len()); |
| ... | ... | @@ -55,14 +53,14 @@ pub trait SupportedArchitectureTest { |
| 55 | 53 | .map(|(i, chunk)| { |
| 56 | 54 | let c_filename = format!("c_programs/wrapper_{i}.c"); |
| 57 | 55 | 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) | |
| 59 | 57 | }) |
| 60 | 58 | .collect::<io::Result<()>>() |
| 61 | 59 | .unwrap(); |
| 62 | 60 | } |
| 63 | 61 | |
| 64 | 62 | 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); | |
| 66 | 64 | |
| 67 | 65 | std::fs::create_dir_all("rust_programs").unwrap(); |
| 68 | 66 | |
| ... | ... | @@ -81,14 +79,7 @@ pub trait SupportedArchitectureTest { |
| 81 | 79 | trace!("generating `{rust_filename}`"); |
| 82 | 80 | let mut file = File::create(&rust_filename)?; |
| 83 | 81 | |
| 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)?; | |
| 92 | 83 | run_rustfmt(&rust_filename); |
| 93 | 84 | |
| 94 | 85 | 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 _; |
| 2 | 2 | |
| 3 | 3 | use crate::common::{ |
| 4 | 4 | PASSES, |
| 5 | intrinsic_helpers::{IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind}, | |
| 5 | intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind}, | |
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | 8 | /// Maximum size of a SVE vector |
| ... | ... | @@ -18,13 +18,13 @@ pub const MAX_SVE_BITS: u32 = 2048; |
| 18 | 18 | /// 0x80, 0x3b, 0xff, |
| 19 | 19 | /// ]; |
| 20 | 20 | /// ``` |
| 21 | pub fn test_values_array_static<T: IntrinsicTypeDefinition>( | |
| 21 | pub fn test_values_array_static<T: TypeDefinition>( | |
| 22 | 22 | w: &mut impl std::io::Write, |
| 23 | 23 | ty: &T, |
| 24 | 24 | ) -> std::io::Result<()> { |
| 25 | 25 | writeln!( |
| 26 | 26 | w, |
| 27 | "static {name}: [{ty}; {load_size}] = {values};\n", | |
| 27 | "static {name}: [{ty}; {load_size}] = {values};", | |
| 28 | 28 | name = test_values_array_name(ty), |
| 29 | 29 | ty = ty.rust_scalar_type(), |
| 30 | 30 | load_size = test_values_array_length(&ty), |
| ... | ... | @@ -34,7 +34,7 @@ pub fn test_values_array_static<T: IntrinsicTypeDefinition>( |
| 34 | 34 | |
| 35 | 35 | /// Returns a string with the name of the static variable containing test values for intrinsic |
| 36 | 36 | /// arguments of this type. |
| 37 | pub fn test_values_array_name<T: IntrinsicTypeDefinition>(ty: &T) -> String { | |
| 37 | pub fn test_values_array_name<T: TypeDefinition>(ty: &T) -> String { | |
| 38 | 38 | format!( |
| 39 | 39 | "{ty}_{load_size}", |
| 40 | 40 | ty = ty.rust_scalar_type().to_uppercase(), |
library/stdarch/crates/intrinsic-test/src/main.rs+6-12| ... | ... | @@ -5,10 +5,10 @@ mod arm; |
| 5 | 5 | mod common; |
| 6 | 6 | mod x86; |
| 7 | 7 | |
| 8 | use arm::ArmArchitectureTest; | |
| 9 | use common::SupportedArchitectureTest; | |
| 8 | use arm::Arm; | |
| 9 | use common::SupportedArchitecture; | |
| 10 | 10 | use common::cli::{Cli, ProcessedCli}; |
| 11 | use x86::X86ArchitectureTest; | |
| 11 | use x86::X86; | |
| 12 | 12 | |
| 13 | 13 | fn main() { |
| 14 | 14 | pretty_env_logger::init(); |
| ... | ... | @@ -18,21 +18,15 @@ fn main() { |
| 18 | 18 | if processed_cli_options.target.starts_with("arm") |
| 19 | 19 | | processed_cli_options.target.starts_with("aarch64") |
| 20 | 20 | { |
| 21 | run( | |
| 22 | ArmArchitectureTest::create(&processed_cli_options), | |
| 23 | processed_cli_options, | |
| 24 | ) | |
| 21 | run(Arm::create(&processed_cli_options), processed_cli_options) | |
| 25 | 22 | } 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) | |
| 30 | 24 | } else { |
| 31 | 25 | unimplemented!("Unsupported target {}", processed_cli_options.target) |
| 32 | 26 | } |
| 33 | 27 | } |
| 34 | 28 | |
| 35 | fn run(test_environment: impl SupportedArchitectureTest, processed_cli_options: ProcessedCli) { | |
| 29 | fn run(test_environment: impl SupportedArchitecture, processed_cli_options: ProcessedCli) { | |
| 36 | 30 | info!("building C binaries"); |
| 37 | 31 | test_environment.generate_c_file(); |
| 38 | 32 |
library/stdarch/crates/intrinsic-test/src/x86/config.rs deleted-138| ... | ... | @@ -1,138 +0,0 @@ |
| 1 | pub 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 | ||
| 6 | pub const PLATFORM_RUST_DEFINITIONS: &str = r#" | |
| 7 | use core_arch::arch::x86_64::*; | |
| 8 | ||
| 9 | #[inline] | |
| 10 | unsafe fn _mm_loadu_ph_to___m128i(mem_addr: *const f16) -> __m128i { | |
| 11 | _mm_castph_si128(_mm_loadu_ph(mem_addr)) | |
| 12 | } | |
| 13 | ||
| 14 | #[inline] | |
| 15 | unsafe fn _mm256_loadu_ph_to___m256i(mem_addr: *const f16) -> __m256i { | |
| 16 | _mm256_castph_si256(_mm256_loadu_ph(mem_addr)) | |
| 17 | } | |
| 18 | ||
| 19 | #[inline] | |
| 20 | unsafe 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] | |
| 26 | unsafe fn _mm_loadu_ps_to___m128h(mem_addr: *const f32) -> __m128h { | |
| 27 | _mm_castps_ph(_mm_loadu_ps(mem_addr)) | |
| 28 | } | |
| 29 | ||
| 30 | #[inline] | |
| 31 | unsafe fn _mm256_loadu_ps_to___m256h(mem_addr: *const f32) -> __m256h { | |
| 32 | _mm256_castps_ph(_mm256_loadu_ps(mem_addr)) | |
| 33 | } | |
| 34 | ||
| 35 | #[inline] | |
| 36 | unsafe fn _mm512_loadu_ps_to___m512h(mem_addr: *const f32) -> __m512h { | |
| 37 | _mm512_castps_ph(_mm512_loadu_ps(mem_addr)) | |
| 38 | } | |
| 39 | ||
| 40 | #[inline] | |
| 41 | unsafe fn _mm_loadu_epi16_to___m128d(mem_addr: *const i16) -> __m128d { | |
| 42 | _mm_castsi128_pd(_mm_loadu_epi16(mem_addr)) | |
| 43 | } | |
| 44 | ||
| 45 | #[inline] | |
| 46 | unsafe fn _mm256_loadu_epi16_to___m256d(mem_addr: *const i16) -> __m256d { | |
| 47 | _mm256_castsi256_pd(_mm256_loadu_epi16(mem_addr)) | |
| 48 | } | |
| 49 | ||
| 50 | #[inline] | |
| 51 | unsafe fn _mm512_loadu_epi16_to___m512d(mem_addr: *const i16) -> __m512d { | |
| 52 | _mm512_castsi512_pd(_mm512_loadu_epi16(mem_addr)) | |
| 53 | } | |
| 54 | ||
| 55 | #[inline] | |
| 56 | unsafe fn _mm_loadu_epi32_to___m128d(mem_addr: *const i32) -> __m128d { | |
| 57 | _mm_castsi128_pd(_mm_loadu_epi32(mem_addr)) | |
| 58 | } | |
| 59 | ||
| 60 | #[inline] | |
| 61 | unsafe fn _mm256_loadu_epi32_to___m256d(mem_addr: *const i32) -> __m256d { | |
| 62 | _mm256_castsi256_pd(_mm256_loadu_epi32(mem_addr)) | |
| 63 | } | |
| 64 | ||
| 65 | #[inline] | |
| 66 | unsafe fn _mm512_loadu_epi32_to___m512d(mem_addr: *const i32) -> __m512d { | |
| 67 | _mm512_castsi512_pd(_mm512_loadu_epi32(mem_addr)) | |
| 68 | } | |
| 69 | ||
| 70 | #[inline] | |
| 71 | unsafe fn _mm_loadu_epi64_to___m128d(mem_addr: *const i64) -> __m128d { | |
| 72 | _mm_castsi128_pd(_mm_loadu_epi64(mem_addr)) | |
| 73 | } | |
| 74 | ||
| 75 | #[inline] | |
| 76 | unsafe fn _mm256_loadu_epi64_to___m256d(mem_addr: *const i64) -> __m256d { | |
| 77 | _mm256_castsi256_pd(_mm256_loadu_epi64(mem_addr)) | |
| 78 | } | |
| 79 | ||
| 80 | #[inline] | |
| 81 | unsafe 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] | |
| 87 | unsafe fn _mm_loadu_epi16_to___m128(mem_addr: *const i16) -> __m128 { | |
| 88 | _mm_castsi128_ps(_mm_loadu_epi16(mem_addr)) | |
| 89 | } | |
| 90 | ||
| 91 | #[inline] | |
| 92 | unsafe fn _mm256_loadu_epi16_to___m256(mem_addr: *const i16) -> __m256 { | |
| 93 | _mm256_castsi256_ps(_mm256_loadu_epi16(mem_addr)) | |
| 94 | } | |
| 95 | ||
| 96 | #[inline] | |
| 97 | unsafe fn _mm512_loadu_epi16_to___m512(mem_addr: *const i16) -> __m512 { | |
| 98 | _mm512_castsi512_ps(_mm512_loadu_epi16(mem_addr)) | |
| 99 | } | |
| 100 | ||
| 101 | #[inline] | |
| 102 | unsafe fn _mm_loadu_epi32_to___m128(mem_addr: *const i32) -> __m128 { | |
| 103 | _mm_castsi128_ps(_mm_loadu_epi32(mem_addr)) | |
| 104 | } | |
| 105 | ||
| 106 | #[inline] | |
| 107 | unsafe fn _mm256_loadu_epi32_to___m256(mem_addr: *const i32) -> __m256 { | |
| 108 | _mm256_castsi256_ps(_mm256_loadu_epi32(mem_addr)) | |
| 109 | } | |
| 110 | ||
| 111 | #[inline] | |
| 112 | unsafe fn _mm512_loadu_epi32_to___m512(mem_addr: *const i32) -> __m512 { | |
| 113 | _mm512_castsi512_ps(_mm512_loadu_epi32(mem_addr)) | |
| 114 | } | |
| 115 | ||
| 116 | #[inline] | |
| 117 | unsafe fn _mm_loadu_epi64_to___m128(mem_addr: *const i64) -> __m128 { | |
| 118 | _mm_castsi128_ps(_mm_loadu_epi64(mem_addr)) | |
| 119 | } | |
| 120 | ||
| 121 | #[inline] | |
| 122 | unsafe fn _mm256_loadu_epi64_to___m256(mem_addr: *const i64) -> __m256 { | |
| 123 | _mm256_castsi256_ps(_mm256_loadu_epi64(mem_addr)) | |
| 124 | } | |
| 125 | ||
| 126 | #[inline] | |
| 127 | unsafe fn _mm512_loadu_epi64_to___m512(mem_addr: *const i64) -> __m512 { | |
| 128 | _mm512_castsi512_ps(_mm512_loadu_epi64(mem_addr)) | |
| 129 | } | |
| 130 | ||
| 131 | "#; | |
| 132 | ||
| 133 | pub 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 @@ |
| 1 | mod config; | |
| 2 | 1 | mod constraint; |
| 3 | 2 | mod intrinsic; |
| 4 | 3 | mod types; |
| 5 | 4 | mod xml_parser; |
| 6 | 5 | |
| 7 | use crate::common::SupportedArchitectureTest; | |
| 6 | use crate::common::SupportedArchitecture; | |
| 8 | 7 | use crate::common::cli::ProcessedCli; |
| 9 | 8 | use crate::common::intrinsic::Intrinsic; |
| 10 | 9 | use crate::common::intrinsic_helpers::TypeKind; |
| 11 | 10 | use intrinsic::X86IntrinsicType; |
| 12 | 11 | use xml_parser::get_xml_intrinsics; |
| 13 | 12 | |
| 14 | pub struct X86ArchitectureTest { | |
| 15 | intrinsics: Vec<Intrinsic<X86IntrinsicType>>, | |
| 13 | pub struct X86 { | |
| 14 | intrinsics: Vec<Intrinsic<X86>>, | |
| 16 | 15 | } |
| 17 | 16 | |
| 18 | impl SupportedArchitectureTest for X86ArchitectureTest { | |
| 19 | type IntrinsicImpl = X86IntrinsicType; | |
| 17 | impl SupportedArchitecture for X86 { | |
| 18 | type Type = X86IntrinsicType; | |
| 20 | 19 | |
| 21 | fn intrinsics(&self) -> &[Intrinsic<X86IntrinsicType>] { | |
| 20 | fn intrinsics(&self) -> &[Intrinsic<Self>] { | |
| 22 | 21 | &self.intrinsics |
| 23 | 22 | } |
| 24 | 23 | |
| 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 | "#; | |
| 26 | 29 | |
| 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; | |
| 28 | 34 | |
| 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> { | |
| 33 | 36 | vec![ |
| 34 | 37 | "-maes", |
| 35 | 38 | "-mf16c", |
| ... | ... | @@ -97,3 +100,134 @@ impl SupportedArchitectureTest for X86ArchitectureTest { |
| 97 | 100 | Self { intrinsics } |
| 98 | 101 | } |
| 99 | 102 | } |
| 103 | ||
| 104 | const 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 | ||
| 110 | use core_arch::arch::x86_64::*; | |
| 111 | ||
| 112 | #[inline] | |
| 113 | unsafe fn _mm_loadu_ph_to___m128i(mem_addr: *const f16) -> __m128i { | |
| 114 | _mm_castph_si128(_mm_loadu_ph(mem_addr)) | |
| 115 | } | |
| 116 | ||
| 117 | #[inline] | |
| 118 | unsafe fn _mm256_loadu_ph_to___m256i(mem_addr: *const f16) -> __m256i { | |
| 119 | _mm256_castph_si256(_mm256_loadu_ph(mem_addr)) | |
| 120 | } | |
| 121 | ||
| 122 | #[inline] | |
| 123 | unsafe 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] | |
| 129 | unsafe fn _mm_loadu_ps_to___m128h(mem_addr: *const f32) -> __m128h { | |
| 130 | _mm_castps_ph(_mm_loadu_ps(mem_addr)) | |
| 131 | } | |
| 132 | ||
| 133 | #[inline] | |
| 134 | unsafe fn _mm256_loadu_ps_to___m256h(mem_addr: *const f32) -> __m256h { | |
| 135 | _mm256_castps_ph(_mm256_loadu_ps(mem_addr)) | |
| 136 | } | |
| 137 | ||
| 138 | #[inline] | |
| 139 | unsafe fn _mm512_loadu_ps_to___m512h(mem_addr: *const f32) -> __m512h { | |
| 140 | _mm512_castps_ph(_mm512_loadu_ps(mem_addr)) | |
| 141 | } | |
| 142 | ||
| 143 | #[inline] | |
| 144 | unsafe fn _mm_loadu_epi16_to___m128d(mem_addr: *const i16) -> __m128d { | |
| 145 | _mm_castsi128_pd(_mm_loadu_epi16(mem_addr)) | |
| 146 | } | |
| 147 | ||
| 148 | #[inline] | |
| 149 | unsafe fn _mm256_loadu_epi16_to___m256d(mem_addr: *const i16) -> __m256d { | |
| 150 | _mm256_castsi256_pd(_mm256_loadu_epi16(mem_addr)) | |
| 151 | } | |
| 152 | ||
| 153 | #[inline] | |
| 154 | unsafe fn _mm512_loadu_epi16_to___m512d(mem_addr: *const i16) -> __m512d { | |
| 155 | _mm512_castsi512_pd(_mm512_loadu_epi16(mem_addr)) | |
| 156 | } | |
| 157 | ||
| 158 | #[inline] | |
| 159 | unsafe fn _mm_loadu_epi32_to___m128d(mem_addr: *const i32) -> __m128d { | |
| 160 | _mm_castsi128_pd(_mm_loadu_epi32(mem_addr)) | |
| 161 | } | |
| 162 | ||
| 163 | #[inline] | |
| 164 | unsafe fn _mm256_loadu_epi32_to___m256d(mem_addr: *const i32) -> __m256d { | |
| 165 | _mm256_castsi256_pd(_mm256_loadu_epi32(mem_addr)) | |
| 166 | } | |
| 167 | ||
| 168 | #[inline] | |
| 169 | unsafe fn _mm512_loadu_epi32_to___m512d(mem_addr: *const i32) -> __m512d { | |
| 170 | _mm512_castsi512_pd(_mm512_loadu_epi32(mem_addr)) | |
| 171 | } | |
| 172 | ||
| 173 | #[inline] | |
| 174 | unsafe fn _mm_loadu_epi64_to___m128d(mem_addr: *const i64) -> __m128d { | |
| 175 | _mm_castsi128_pd(_mm_loadu_epi64(mem_addr)) | |
| 176 | } | |
| 177 | ||
| 178 | #[inline] | |
| 179 | unsafe fn _mm256_loadu_epi64_to___m256d(mem_addr: *const i64) -> __m256d { | |
| 180 | _mm256_castsi256_pd(_mm256_loadu_epi64(mem_addr)) | |
| 181 | } | |
| 182 | ||
| 183 | #[inline] | |
| 184 | unsafe 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] | |
| 190 | unsafe fn _mm_loadu_epi16_to___m128(mem_addr: *const i16) -> __m128 { | |
| 191 | _mm_castsi128_ps(_mm_loadu_epi16(mem_addr)) | |
| 192 | } | |
| 193 | ||
| 194 | #[inline] | |
| 195 | unsafe fn _mm256_loadu_epi16_to___m256(mem_addr: *const i16) -> __m256 { | |
| 196 | _mm256_castsi256_ps(_mm256_loadu_epi16(mem_addr)) | |
| 197 | } | |
| 198 | ||
| 199 | #[inline] | |
| 200 | unsafe fn _mm512_loadu_epi16_to___m512(mem_addr: *const i16) -> __m512 { | |
| 201 | _mm512_castsi512_ps(_mm512_loadu_epi16(mem_addr)) | |
| 202 | } | |
| 203 | ||
| 204 | #[inline] | |
| 205 | unsafe fn _mm_loadu_epi32_to___m128(mem_addr: *const i32) -> __m128 { | |
| 206 | _mm_castsi128_ps(_mm_loadu_epi32(mem_addr)) | |
| 207 | } | |
| 208 | ||
| 209 | #[inline] | |
| 210 | unsafe fn _mm256_loadu_epi32_to___m256(mem_addr: *const i32) -> __m256 { | |
| 211 | _mm256_castsi256_ps(_mm256_loadu_epi32(mem_addr)) | |
| 212 | } | |
| 213 | ||
| 214 | #[inline] | |
| 215 | unsafe fn _mm512_loadu_epi32_to___m512(mem_addr: *const i32) -> __m512 { | |
| 216 | _mm512_castsi512_ps(_mm512_loadu_epi32(mem_addr)) | |
| 217 | } | |
| 218 | ||
| 219 | #[inline] | |
| 220 | unsafe fn _mm_loadu_epi64_to___m128(mem_addr: *const i64) -> __m128 { | |
| 221 | _mm_castsi128_ps(_mm_loadu_epi64(mem_addr)) | |
| 222 | } | |
| 223 | ||
| 224 | #[inline] | |
| 225 | unsafe fn _mm256_loadu_epi64_to___m256(mem_addr: *const i64) -> __m256 { | |
| 226 | _mm256_castsi256_ps(_mm256_loadu_epi64(mem_addr)) | |
| 227 | } | |
| 228 | ||
| 229 | #[inline] | |
| 230 | unsafe 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; |
| 3 | 3 | use itertools::Itertools; |
| 4 | 4 | |
| 5 | 5 | use super::intrinsic::X86IntrinsicType; |
| 6 | use crate::common::intrinsic_helpers::{ | |
| 7 | IntrinsicType, IntrinsicTypeDefinition, Sign, SimdLen, TypeKind, | |
| 8 | }; | |
| 6 | use crate::common::intrinsic_helpers::{IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind}; | |
| 9 | 7 | use crate::x86::xml_parser::Parameter; |
| 10 | 8 | |
| 11 | impl IntrinsicTypeDefinition for X86IntrinsicType { | |
| 9 | impl TypeDefinition for X86IntrinsicType { | |
| 12 | 10 | /// Gets a string containing the type in C format. |
| 13 | 11 | /// This function assumes that this value is present in the metadata hashmap. |
| 14 | 12 | fn c_type(&self) -> String { |
| ... | ... | @@ -50,7 +48,7 @@ impl IntrinsicTypeDefinition for X86IntrinsicType { |
| 50 | 48 | } |
| 51 | 49 | |
| 52 | 50 | /// Determines the load function for this type. |
| 53 | fn get_load_function(&self) -> String { | |
| 51 | fn load_function(&self) -> String { | |
| 54 | 52 | let type_value = self.param.type_data.clone(); |
| 55 | 53 | if type_value.len() == 0 { |
| 56 | 54 | 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 @@ |
| 1 | 1 | use crate::common::argument::{Argument, ArgumentList}; |
| 2 | 2 | use crate::common::intrinsic::Intrinsic; |
| 3 | 3 | use crate::common::intrinsic_helpers::TypeKind; |
| 4 | use crate::x86::X86; | |
| 4 | 5 | use crate::x86::constraint::map_constraints; |
| 5 | 6 | |
| 6 | 7 | use regex::Regex; |
| ... | ... | @@ -56,13 +57,13 @@ pub struct Parameter { |
| 56 | 57 | |
| 57 | 58 | pub fn get_xml_intrinsics( |
| 58 | 59 | filename: &Path, |
| 59 | ) -> Result<Vec<Intrinsic<X86IntrinsicType>>, Box<dyn std::error::Error>> { | |
| 60 | ) -> Result<Vec<Intrinsic<X86>>, Box<dyn std::error::Error>> { | |
| 60 | 61 | let file = std::fs::File::open(filename)?; |
| 61 | 62 | let reader = std::io::BufReader::new(file); |
| 62 | 63 | let data: Data = |
| 63 | 64 | quick_xml::de::from_reader(reader).expect("failed to deserialize the source XML file"); |
| 64 | 65 | |
| 65 | let parsed_intrinsics: Vec<Intrinsic<X86IntrinsicType>> = data | |
| 66 | let parsed_intrinsics: Vec<Intrinsic<X86>> = data | |
| 66 | 67 | .intrinsics |
| 67 | 68 | .into_iter() |
| 68 | 69 | .filter(|intrinsic| { |
| ... | ... | @@ -84,9 +85,7 @@ pub fn get_xml_intrinsics( |
| 84 | 85 | Ok(parsed_intrinsics) |
| 85 | 86 | } |
| 86 | 87 | |
| 87 | fn xml_to_intrinsic( | |
| 88 | intr: XMLIntrinsic, | |
| 89 | ) -> Result<Intrinsic<X86IntrinsicType>, Box<dyn std::error::Error>> { | |
| 88 | fn xml_to_intrinsic(intr: XMLIntrinsic) -> Result<Intrinsic<X86>, Box<dyn std::error::Error>> { | |
| 90 | 89 | let name = intr.name; |
| 91 | 90 | let result = X86IntrinsicType::from_param(&intr.return_data); |
| 92 | 91 | let args_check = intr.parameters.into_iter().enumerate().map(|(i, param)| { |
| ... | ... | @@ -100,12 +99,7 @@ fn xml_to_intrinsic( |
| 100 | 99 | param.imm_width |
| 101 | 100 | }; |
| 102 | 101 | 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); | |
| 109 | 103 | Some(arg) |
| 110 | 104 | } |
| 111 | 105 | }); |
| ... | ... | @@ -125,8 +119,8 @@ fn xml_to_intrinsic( |
| 125 | 119 | // if one of the args has etype="MASK" and type="__m<int>d", |
| 126 | 120 | // then set the bit_len and simd_len accordingly |
| 127 | 121 | 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()); | |
| 130 | 124 | let pos = args_test.position(|arg| is_mask(arg) && is_vector(arg)); |
| 131 | 125 | if let Some(index) = pos { |
| 132 | 126 | args[index].ty.bit_len = args[0].ty.bit_len; |
| ... | ... | @@ -134,7 +128,7 @@ fn xml_to_intrinsic( |
| 134 | 128 | |
| 135 | 129 | args.iter_mut().for_each(|arg| arg.ty.update_simd_len()); |
| 136 | 130 | |
| 137 | let arguments = ArgumentList::<X86IntrinsicType> { args }; | |
| 131 | let arguments = ArgumentList::<X86> { args }; | |
| 138 | 132 | |
| 139 | 133 | if let Err(message) = result { |
| 140 | 134 | return Err(Box::from(message)); |
| ... | ... | @@ -145,5 +139,6 @@ fn xml_to_intrinsic( |
| 145 | 139 | arguments, |
| 146 | 140 | results: result.unwrap(), |
| 147 | 141 | arch_tags: intr.cpuid, |
| 142 | extension: intr.tech, | |
| 148 | 143 | }) |
| 149 | 144 | } |
library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml+2-2| ... | ... | @@ -13951,7 +13951,7 @@ intrinsics: |
| 13951 | 13951 | - 'b: {neon_type[1]}' |
| 13952 | 13952 | - 'n: i32' |
| 13953 | 13953 | links: |
| 13954 | - link: "llvm.aarch64.neon.vluti4q.lane.{neon_type[1]}" | |
| 13954 | - link: "llvm.aarch64.neon.vluti4q.lane.{neon_type[0]}" | |
| 13955 | 13955 | arch: aarch64,arm64ec |
| 13956 | 13956 | - FnCall: ['_vluti4{neon_type[0].lane_nox}', [a, b, LANE]] |
| 13957 | 13957 | |
| ... | ... | @@ -14002,7 +14002,7 @@ intrinsics: |
| 14002 | 14002 | - 'b: {neon_type[1]}' |
| 14003 | 14003 | - 'n: i32' |
| 14004 | 14004 | links: |
| 14005 | - link: "llvm.aarch64.neon.vluti4q.laneq.{neon_type[1]}" | |
| 14005 | - link: "llvm.aarch64.neon.vluti4q.laneq.{neon_type[0]}" | |
| 14006 | 14006 | arch: aarch64,arm64ec |
| 14007 | 14007 | - FnCall: ['_vluti4{neon_type[0].laneq_nox}', [a, b, LANE]] |
| 14008 | 14008 |
library/stdarch/crates/stdarch-gen-arm/spec/sve/aarch64.spec.yml+77-27| ... | ... | @@ -115,7 +115,7 @@ intrinsics: |
| 115 | 115 | assert_instr: [[fcmla, "IMM_INDEX = 0, IMM_ROTATION = 90"]] |
| 116 | 116 | compose: |
| 117 | 117 | - LLVMLink: |
| 118 | name: fcmla.lane.x.{sve_type} | |
| 118 | name: fcmla.lane.{sve_type} | |
| 119 | 119 | arguments: |
| 120 | 120 | - "op1: {sve_type}" |
| 121 | 121 | - "op2: {sve_type}" |
| ... | ... | @@ -1021,7 +1021,7 @@ intrinsics: |
| 1021 | 1021 | doc: Interleave elements from low halves of two inputs |
| 1022 | 1022 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1023 | 1023 | 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] | |
| 1025 | 1025 | assert_instr: [zip1] |
| 1026 | 1026 | compose: |
| 1027 | 1027 | - LLVMLink: { name: "zip1.{sve_type}" } |
| ... | ... | @@ -1031,10 +1031,13 @@ intrinsics: |
| 1031 | 1031 | doc: Interleave elements from low halves of two inputs |
| 1032 | 1032 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1033 | 1033 | return_type: "{sve_type}" |
| 1034 | types: [b8, b16, b32, b64] | |
| 1034 | types: [b16, b32, b64] | |
| 1035 | 1035 | assert_instr: [zip1] |
| 1036 | 1036 | 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" | |
| 1038 | 1041 | |
| 1039 | 1042 | - name: svzip1q[_{type}] |
| 1040 | 1043 | attr: [*sve-unstable] |
| ... | ... | @@ -1052,7 +1055,7 @@ intrinsics: |
| 1052 | 1055 | doc: Interleave elements from high halves of two inputs |
| 1053 | 1056 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1054 | 1057 | 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] | |
| 1056 | 1059 | assert_instr: [zip2] |
| 1057 | 1060 | compose: |
| 1058 | 1061 | - LLVMLink: { name: "zip2.{sve_type}" } |
| ... | ... | @@ -1062,10 +1065,13 @@ intrinsics: |
| 1062 | 1065 | doc: Interleave elements from high halves of two inputs |
| 1063 | 1066 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1064 | 1067 | return_type: "{sve_type}" |
| 1065 | types: [b8, b16, b32, b64] | |
| 1068 | types: [b16, b32, b64] | |
| 1066 | 1069 | assert_instr: [zip2] |
| 1067 | 1070 | 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" | |
| 1069 | 1075 | |
| 1070 | 1076 | - name: svzip2q[_{type}] |
| 1071 | 1077 | attr: [*sve-unstable] |
| ... | ... | @@ -1083,7 +1089,7 @@ intrinsics: |
| 1083 | 1089 | doc: Concatenate even elements from two inputs |
| 1084 | 1090 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1085 | 1091 | 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] | |
| 1087 | 1093 | assert_instr: [uzp1] |
| 1088 | 1094 | compose: |
| 1089 | 1095 | - LLVMLink: { name: "uzp1.{sve_type}" } |
| ... | ... | @@ -1093,10 +1099,13 @@ intrinsics: |
| 1093 | 1099 | doc: Concatenate even elements from two inputs |
| 1094 | 1100 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1095 | 1101 | return_type: "{sve_type}" |
| 1096 | types: [b8, b16, b32, b64] | |
| 1102 | types: [b16, b32, b64] | |
| 1097 | 1103 | assert_instr: [uzp1] |
| 1098 | 1104 | 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" | |
| 1100 | 1109 | |
| 1101 | 1110 | - name: svuzp1q[_{type}] |
| 1102 | 1111 | attr: [*sve-unstable] |
| ... | ... | @@ -1114,7 +1123,7 @@ intrinsics: |
| 1114 | 1123 | doc: Concatenate odd elements from two inputs |
| 1115 | 1124 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1116 | 1125 | 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] | |
| 1118 | 1127 | assert_instr: [uzp2] |
| 1119 | 1128 | compose: |
| 1120 | 1129 | - LLVMLink: { name: "uzp2.{sve_type}" } |
| ... | ... | @@ -1124,10 +1133,13 @@ intrinsics: |
| 1124 | 1133 | doc: Concatenate odd elements from two inputs |
| 1125 | 1134 | arguments: ["op1: {sve_type}", "op2: {sve_type}"] |
| 1126 | 1135 | return_type: "{sve_type}" |
| 1127 | types: [b8, b16, b32, b64] | |
| 1136 | types: [b16, b32, b64] | |
| 1128 | 1137 | assert_instr: [uzp2] |
| 1129 | 1138 | 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" | |
| 1131 | 1143 | |
| 1132 | 1144 | - name: svuzp2q[_{type}] |
| 1133 | 1145 | attr: [*sve-unstable] |
| ... | ... | @@ -1207,7 +1219,7 @@ intrinsics: |
| 1207 | 1219 | doc: Reverse all elements |
| 1208 | 1220 | arguments: ["op: {sve_type}"] |
| 1209 | 1221 | 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] | |
| 1211 | 1223 | assert_instr: [rev] |
| 1212 | 1224 | compose: |
| 1213 | 1225 | - LLVMLink: { name: "llvm.vector.reverse.{sve_type}" } |
| ... | ... | @@ -1217,10 +1229,13 @@ intrinsics: |
| 1217 | 1229 | doc: Reverse all elements |
| 1218 | 1230 | arguments: ["op: {sve_type}"] |
| 1219 | 1231 | return_type: "{sve_type}" |
| 1220 | types: [b8, b16, b32, b64] | |
| 1232 | types: [b16, b32, b64] | |
| 1221 | 1233 | assert_instr: [rev] |
| 1222 | 1234 | 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" | |
| 1224 | 1239 | |
| 1225 | 1240 | - name: svrevb[_{type}]{_mxz} |
| 1226 | 1241 | attr: [*sve-unstable] |
| ... | ... | @@ -4179,7 +4194,8 @@ intrinsics: |
| 4179 | 4194 | ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"] |
| 4180 | 4195 | return_type: "{sve_type[0]}" |
| 4181 | 4196 | types: |
| 4182 | - [[f32, f64], [i32, u32, i64, u64]] | |
| 4197 | - [f32, [i64, u64]] | |
| 4198 | - [f64, [i32, u32]] | |
| 4183 | 4199 | zeroing_method: { drop: inactive } |
| 4184 | 4200 | substitutions: |
| 4185 | 4201 | convert_from: { match_kind: "{type[1]}", default: s, unsigned: u } |
| ... | ... | @@ -4187,6 +4203,23 @@ intrinsics: |
| 4187 | 4203 | compose: |
| 4188 | 4204 | - LLVMLink: |
| 4189 | 4205 | 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]}" | |
| 4190 | 4223 | |
| 4191 | 4224 | - name: svcvt_{type[0]}[_{type[1]}]{_mxz} |
| 4192 | 4225 | attr: [*sve-unstable] |
| ... | ... | @@ -4195,13 +4228,30 @@ intrinsics: |
| 4195 | 4228 | ["inactive: {sve_type[0]}", "pg: {max_predicate}", "op: {sve_type[1]}"] |
| 4196 | 4229 | return_type: "{sve_type[0]}" |
| 4197 | 4230 | types: |
| 4198 | - [[i32, u32, i64, u64], [f32, f64]] | |
| 4231 | - [[i32, u32], f64] | |
| 4232 | - [[i64, u64], f32] | |
| 4199 | 4233 | zeroing_method: { drop: inactive } |
| 4200 | 4234 | substitutions: |
| 4201 | 4235 | convert_to: { match_kind: "{type[0]}", default: s, unsigned: u } |
| 4202 | 4236 | assert_instr: ["fcvtz{convert_to}"] |
| 4203 | 4237 | compose: |
| 4204 | 4238 | - 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]}" } | |
| 4205 | 4255 | |
| 4206 | 4256 | - name: svcvt_{type[0]}[_{type[1]}]{_mxz} |
| 4207 | 4257 | attr: [*sve-unstable] |
| ... | ... | @@ -4356,7 +4406,7 @@ intrinsics: |
| 4356 | 4406 | return_type: svbool_t |
| 4357 | 4407 | assert_instr: [and] |
| 4358 | 4408 | compose: |
| 4359 | - LLVMLink: { name: "and.z.nvx16i1" } | |
| 4409 | - LLVMLink: { name: "and.z.nxv16i1" } | |
| 4360 | 4410 | |
| 4361 | 4411 | - name: svmov[_b]_z |
| 4362 | 4412 | attr: [*sve-unstable] |
| ... | ... | @@ -4386,7 +4436,7 @@ intrinsics: |
| 4386 | 4436 | return_type: svbool_t |
| 4387 | 4437 | assert_instr: [bic] |
| 4388 | 4438 | compose: |
| 4389 | - LLVMLink: { name: "bic.z.nvx16i1" } | |
| 4439 | - LLVMLink: { name: "bic.z.nxv16i1" } | |
| 4390 | 4440 | |
| 4391 | 4441 | - name: sveor[{_n}_{type}]{_mxz} |
| 4392 | 4442 | attr: [*sve-unstable] |
| ... | ... | @@ -4417,7 +4467,7 @@ intrinsics: |
| 4417 | 4467 | return_type: svbool_t |
| 4418 | 4468 | assert_instr: [eor] |
| 4419 | 4469 | compose: |
| 4420 | - LLVMLink: { name: "eor.z.nvx16i1" } | |
| 4470 | - LLVMLink: { name: "eor.z.nxv16i1" } | |
| 4421 | 4471 | |
| 4422 | 4472 | - name: svnot[_{type}]{_mxz} |
| 4423 | 4473 | attr: [*sve-unstable] |
| ... | ... | @@ -4497,7 +4547,7 @@ intrinsics: |
| 4497 | 4547 | return_type: svbool_t |
| 4498 | 4548 | assert_instr: [orr] |
| 4499 | 4549 | compose: |
| 4500 | - LLVMLink: { name: "orr.z.nvx16i1" } | |
| 4550 | - LLVMLink: { name: "orr.z.nxv16i1" } | |
| 4501 | 4551 | |
| 4502 | 4552 | - name: svorn[_b]_z |
| 4503 | 4553 | attr: [*sve-unstable] |
| ... | ... | @@ -4506,7 +4556,7 @@ intrinsics: |
| 4506 | 4556 | return_type: svbool_t |
| 4507 | 4557 | assert_instr: [orn] |
| 4508 | 4558 | compose: |
| 4509 | - LLVMLink: { name: "orn.z.nvx16i1" } | |
| 4559 | - LLVMLink: { name: "orn.z.nxv16i1" } | |
| 4510 | 4560 | |
| 4511 | 4561 | - name: svlsl[{_n}_{type[0]}]{_mxz} |
| 4512 | 4562 | attr: [*sve-unstable] |
| ... | ... | @@ -4749,7 +4799,7 @@ intrinsics: |
| 4749 | 4799 | assert_instr: [frecpx] |
| 4750 | 4800 | zeroing_method: { drop: inactive } |
| 4751 | 4801 | compose: |
| 4752 | - LLVMLink: { name: "frecpx.x.{sve_type}" } | |
| 4802 | - LLVMLink: { name: "frecpx.{sve_type}" } | |
| 4753 | 4803 | |
| 4754 | 4804 | - name: svrsqrte[_{type}] |
| 4755 | 4805 | attr: [*sve-unstable] |
| ... | ... | @@ -5115,7 +5165,7 @@ intrinsics: |
| 5115 | 5165 | types: [[f32, u32], [f64, u64]] |
| 5116 | 5166 | assert_instr: [fexpa] |
| 5117 | 5167 | compose: |
| 5118 | - LLVMLink: { name: "fexpa.x.{sve_type[0]} " } | |
| 5168 | - LLVMLink: { name: "fexpa.x.{sve_type[0]}" } | |
| 5119 | 5169 | |
| 5120 | 5170 | - name: svscale[{_n}_{type[0]}]{_mxz} |
| 5121 | 5171 | attr: [*sve-unstable] |
| ... | ... | @@ -5139,7 +5189,7 @@ intrinsics: |
| 5139 | 5189 | types: [f32] |
| 5140 | 5190 | assert_instr: [fmmla] |
| 5141 | 5191 | compose: |
| 5142 | - LLVMLink: { name: "fmmla.{sve_type}" } | |
| 5192 | - LLVMLink: { name: "fmmla.{sve_type}.{sve_type}" } | |
| 5143 | 5193 | |
| 5144 | 5194 | - name: svmmla[_{type}] |
| 5145 | 5195 | attr: [*sve-unstable] |
| ... | ... | @@ -5150,7 +5200,7 @@ intrinsics: |
| 5150 | 5200 | types: [f64] |
| 5151 | 5201 | assert_instr: [fmmla] |
| 5152 | 5202 | compose: |
| 5153 | - LLVMLink: { name: "fmmla.{sve_type}" } | |
| 5203 | - LLVMLink: { name: "fmmla.{sve_type}.{sve_type}" } | |
| 5154 | 5204 | |
| 5155 | 5205 | - name: svmmla[_{type[0]}] |
| 5156 | 5206 | attr: [*sve-unstable] |
library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs+1| ... | ... | @@ -1604,6 +1604,7 @@ impl Intrinsic { |
| 1604 | 1604 | (Some(BaseTypeKind::Float), Some(BaseTypeKind::Float)) => ex, |
| 1605 | 1605 | (Some(BaseTypeKind::UInt), Some(BaseTypeKind::UInt)) => ex, |
| 1606 | 1606 | (Some(BaseTypeKind::Poly), Some(BaseTypeKind::Poly)) => ex, |
| 1607 | (Some(BaseTypeKind::Bool), Some(BaseTypeKind::Bool)) => ex, | |
| 1607 | 1608 | |
| 1608 | 1609 | (None, None) => ex, |
| 1609 | 1610 | _ => unreachable!( |
library/stdarch/crates/stdarch-gen-common/Cargo.toml created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | [package] | |
| 2 | name = "stdarch-gen-common" | |
| 3 | version = "0.1.0" | |
| 4 | edition = "2024" | |
| 5 | ||
| 6 | [dependencies] | |
| 7 | tempfile = "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 | ||
| 3 | use std::error::Error as StdError; | |
| 4 | use std::fmt; | |
| 5 | use std::fs; | |
| 6 | use std::io; | |
| 7 | use std::io::Read; | |
| 8 | use 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. | |
| 13 | pub 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)] | |
| 17 | pub 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 | ||
| 32 | impl 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)] | |
| 51 | pub 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)] | |
| 58 | pub 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 | ||
| 69 | impl 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 | ||
| 87 | impl 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 | ||
| 97 | impl From<io::Error> for Error { | |
| 98 | fn from(e: io::Error) -> Self { | |
| 99 | Error::Io(e) | |
| 100 | } | |
| 101 | } | |
| 102 | ||
| 103 | pub 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. | |
| 123 | pub fn run_generator<F, E>(committed: &Path, mode: Mode, generate: F) -> Result<()> | |
| 124 | where | |
| 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. | |
| 149 | fn 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). | |
| 174 | fn 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 | ||
| 187 | fn 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 | ||
| 214 | fn 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")))] | |
| 233 | mod 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" |
| 7 | 7 | |
| 8 | 8 | [dependencies] |
| 9 | 9 | regex = "1.10" |
| 10 | stdarch-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}; |
| 21 | 21 | use std::fs::File; |
| 22 | 22 | use std::io::Write; |
| 23 | 23 | use std::path::Path; |
| 24 | use stdarch_gen_common::{run_generator, Mode, GENERATED_MARKER}; | |
| 24 | 25 | |
| 25 | 26 | /// Mappings from HVX intrinsics to architecture-independent SIMD intrinsics. |
| 26 | 27 | /// These intrinsics have equivalent semantics and can be lowered to the generic form. |
| ... | ... | @@ -1609,6 +1610,7 @@ fn generate_module_file( |
| 1609 | 1610 | let mut output = |
| 1610 | 1611 | File::create(output_path).map_err(|e| format!("Failed to create output: {}", e))?; |
| 1611 | 1612 | |
| 1613 | writeln!(output, "{}", GENERATED_MARKER).map_err(|e| e.to_string())?; | |
| 1612 | 1614 | writeln!(output, "{}", generate_module_doc(mode)).map_err(|e| e.to_string())?; |
| 1613 | 1615 | writeln!(output, "{}", generate_types(mode)).map_err(|e| e.to_string())?; |
| 1614 | 1616 | writeln!(output, "{}", generate_extern_block(intrinsics, mode)).map_err(|e| e.to_string())?; |
| ... | ... | @@ -1691,23 +1693,21 @@ fn main() -> Result<(), String> { |
| 1691 | 1693 | } |
| 1692 | 1694 | |
| 1693 | 1695 | // 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())?; | |
| 1711 | 1711 | |
| 1712 | 1712 | println!("\n=== Results ==="); |
| 1713 | 1713 | println!( |
library/stdarch/crates/stdarch-gen-loongarch/Cargo.toml+1-1| ... | ... | @@ -7,4 +7,4 @@ edition = "2024" |
| 7 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
| 8 | 8 | |
| 9 | 9 | [dependencies] |
| 10 | rand = "0.8.5" | |
| 10 | rand = "0.9.3" |
library/stdarch/examples/Cargo.toml+1-1| ... | ... | @@ -13,7 +13,7 @@ default-run = "hex" |
| 13 | 13 | [dependencies] |
| 14 | 14 | core_arch = { path = "../crates/core_arch" } |
| 15 | 15 | quickcheck = "1.0" |
| 16 | rand = "0.8" | |
| 16 | rand = "0.9.3" | |
| 17 | 17 | |
| 18 | 18 | [[bin]] |
| 19 | 19 | name = "hex" |
library/stdarch/examples/connect5.rs+2-2| ... | ... | @@ -33,8 +33,8 @@ |
| 33 | 33 | #![cfg_attr(target_arch = "x86_64", feature(stdarch_internal))] |
| 34 | 34 | #![feature(stmt_expr_attributes)] |
| 35 | 35 | |
| 36 | use rand::rng; | |
| 36 | 37 | use rand::seq::SliceRandom; |
| 37 | use rand::thread_rng; | |
| 38 | 38 | |
| 39 | 39 | use std::cmp; |
| 40 | 40 | use std::time::Instant; |
| ... | ... | @@ -374,7 +374,7 @@ impl List { |
| 374 | 374 | } |
| 375 | 375 | |
| 376 | 376 | pub fn shuffle(&mut self) { |
| 377 | let mut rng = thread_rng(); | |
| 377 | let mut rng = rng(); | |
| 378 | 378 | let num = self.p_size as usize; |
| 379 | 379 | |
| 380 | 380 | self.p_move[..num].shuffle(&mut rng); |
library/stdarch/examples/hex.rs+2-2| ... | ... | @@ -354,9 +354,9 @@ mod benches { |
| 354 | 354 | len: usize, |
| 355 | 355 | f: for<'a> unsafe fn(&[u8], &'a mut [u8]) -> Result<&'a str, usize>, |
| 356 | 356 | ) { |
| 357 | let mut rng = rand::thread_rng(); | |
| 357 | let mut rng = rand::rng(); | |
| 358 | 358 | let input = std::iter::repeat(()) |
| 359 | .map(|()| rng.r#gen::<u8>()) | |
| 359 | .map(|()| rng.r#random::<u8>()) | |
| 360 | 360 | .take(len) |
| 361 | 361 | .collect::<Vec<_>>(); |
| 362 | 362 | let mut dst = vec![0; input.len() * 2]; |
library/stdarch/intrinsics_data/arm_intrinsics.json+396| ... | ... | @@ -51174,6 +51174,12 @@ |
| 51174 | 51174 | "svfloat16x2_t tuple", |
| 51175 | 51175 | "uint64_t imm_index" |
| 51176 | 51176 | ], |
| 51177 | "Arguments_Preparation": { | |
| 51178 | "imm_index": { | |
| 51179 | "minimum": 0, | |
| 51180 | "maximum": 1 | |
| 51181 | } | |
| 51182 | }, | |
| 51177 | 51183 | "return_type": { |
| 51178 | 51184 | "value": "svfloat16_t" |
| 51179 | 51185 | }, |
| ... | ... | @@ -51188,6 +51194,12 @@ |
| 51188 | 51194 | "svfloat32x2_t tuple", |
| 51189 | 51195 | "uint64_t imm_index" |
| 51190 | 51196 | ], |
| 51197 | "Arguments_Preparation": { | |
| 51198 | "imm_index": { | |
| 51199 | "minimum": 0, | |
| 51200 | "maximum": 1 | |
| 51201 | } | |
| 51202 | }, | |
| 51191 | 51203 | "return_type": { |
| 51192 | 51204 | "value": "svfloat32_t" |
| 51193 | 51205 | }, |
| ... | ... | @@ -51202,6 +51214,12 @@ |
| 51202 | 51214 | "svfloat64x2_t tuple", |
| 51203 | 51215 | "uint64_t imm_index" |
| 51204 | 51216 | ], |
| 51217 | "Arguments_Preparation": { | |
| 51218 | "imm_index": { | |
| 51219 | "minimum": 0, | |
| 51220 | "maximum": 1 | |
| 51221 | } | |
| 51222 | }, | |
| 51205 | 51223 | "return_type": { |
| 51206 | 51224 | "value": "svfloat64_t" |
| 51207 | 51225 | }, |
| ... | ... | @@ -51216,6 +51234,12 @@ |
| 51216 | 51234 | "svint16x2_t tuple", |
| 51217 | 51235 | "uint64_t imm_index" |
| 51218 | 51236 | ], |
| 51237 | "Arguments_Preparation": { | |
| 51238 | "imm_index": { | |
| 51239 | "minimum": 0, | |
| 51240 | "maximum": 1 | |
| 51241 | } | |
| 51242 | }, | |
| 51219 | 51243 | "return_type": { |
| 51220 | 51244 | "value": "svint16_t" |
| 51221 | 51245 | }, |
| ... | ... | @@ -51230,6 +51254,12 @@ |
| 51230 | 51254 | "svint32x2_t tuple", |
| 51231 | 51255 | "uint64_t imm_index" |
| 51232 | 51256 | ], |
| 51257 | "Arguments_Preparation": { | |
| 51258 | "imm_index": { | |
| 51259 | "minimum": 0, | |
| 51260 | "maximum": 1 | |
| 51261 | } | |
| 51262 | }, | |
| 51233 | 51263 | "return_type": { |
| 51234 | 51264 | "value": "svint32_t" |
| 51235 | 51265 | }, |
| ... | ... | @@ -51244,6 +51274,12 @@ |
| 51244 | 51274 | "svint64x2_t tuple", |
| 51245 | 51275 | "uint64_t imm_index" |
| 51246 | 51276 | ], |
| 51277 | "Arguments_Preparation": { | |
| 51278 | "imm_index": { | |
| 51279 | "minimum": 0, | |
| 51280 | "maximum": 1 | |
| 51281 | } | |
| 51282 | }, | |
| 51247 | 51283 | "return_type": { |
| 51248 | 51284 | "value": "svint64_t" |
| 51249 | 51285 | }, |
| ... | ... | @@ -51258,6 +51294,12 @@ |
| 51258 | 51294 | "svint8x2_t tuple", |
| 51259 | 51295 | "uint64_t imm_index" |
| 51260 | 51296 | ], |
| 51297 | "Arguments_Preparation": { | |
| 51298 | "imm_index": { | |
| 51299 | "minimum": 0, | |
| 51300 | "maximum": 1 | |
| 51301 | } | |
| 51302 | }, | |
| 51261 | 51303 | "return_type": { |
| 51262 | 51304 | "value": "svint8_t" |
| 51263 | 51305 | }, |
| ... | ... | @@ -51272,6 +51314,12 @@ |
| 51272 | 51314 | "svuint16x2_t tuple", |
| 51273 | 51315 | "uint64_t imm_index" |
| 51274 | 51316 | ], |
| 51317 | "Arguments_Preparation": { | |
| 51318 | "imm_index": { | |
| 51319 | "minimum": 0, | |
| 51320 | "maximum": 1 | |
| 51321 | } | |
| 51322 | }, | |
| 51275 | 51323 | "return_type": { |
| 51276 | 51324 | "value": "svuint16_t" |
| 51277 | 51325 | }, |
| ... | ... | @@ -51286,6 +51334,12 @@ |
| 51286 | 51334 | "svuint32x2_t tuple", |
| 51287 | 51335 | "uint64_t imm_index" |
| 51288 | 51336 | ], |
| 51337 | "Arguments_Preparation": { | |
| 51338 | "imm_index": { | |
| 51339 | "minimum": 0, | |
| 51340 | "maximum": 1 | |
| 51341 | } | |
| 51342 | }, | |
| 51289 | 51343 | "return_type": { |
| 51290 | 51344 | "value": "svuint32_t" |
| 51291 | 51345 | }, |
| ... | ... | @@ -51300,6 +51354,12 @@ |
| 51300 | 51354 | "svuint64x2_t tuple", |
| 51301 | 51355 | "uint64_t imm_index" |
| 51302 | 51356 | ], |
| 51357 | "Arguments_Preparation": { | |
| 51358 | "imm_index": { | |
| 51359 | "minimum": 0, | |
| 51360 | "maximum": 1 | |
| 51361 | } | |
| 51362 | }, | |
| 51303 | 51363 | "return_type": { |
| 51304 | 51364 | "value": "svuint64_t" |
| 51305 | 51365 | }, |
| ... | ... | @@ -51314,6 +51374,12 @@ |
| 51314 | 51374 | "svuint8x2_t tuple", |
| 51315 | 51375 | "uint64_t imm_index" |
| 51316 | 51376 | ], |
| 51377 | "Arguments_Preparation": { | |
| 51378 | "imm_index": { | |
| 51379 | "minimum": 0, | |
| 51380 | "maximum": 1 | |
| 51381 | } | |
| 51382 | }, | |
| 51317 | 51383 | "return_type": { |
| 51318 | 51384 | "value": "svuint8_t" |
| 51319 | 51385 | }, |
| ... | ... | @@ -51328,6 +51394,12 @@ |
| 51328 | 51394 | "svfloat16x3_t tuple", |
| 51329 | 51395 | "uint64_t imm_index" |
| 51330 | 51396 | ], |
| 51397 | "Arguments_Preparation": { | |
| 51398 | "imm_index": { | |
| 51399 | "minimum": 0, | |
| 51400 | "maximum": 2 | |
| 51401 | } | |
| 51402 | }, | |
| 51331 | 51403 | "return_type": { |
| 51332 | 51404 | "value": "svfloat16_t" |
| 51333 | 51405 | }, |
| ... | ... | @@ -51342,6 +51414,12 @@ |
| 51342 | 51414 | "svfloat32x3_t tuple", |
| 51343 | 51415 | "uint64_t imm_index" |
| 51344 | 51416 | ], |
| 51417 | "Arguments_Preparation": { | |
| 51418 | "imm_index": { | |
| 51419 | "minimum": 0, | |
| 51420 | "maximum": 2 | |
| 51421 | } | |
| 51422 | }, | |
| 51345 | 51423 | "return_type": { |
| 51346 | 51424 | "value": "svfloat32_t" |
| 51347 | 51425 | }, |
| ... | ... | @@ -51356,6 +51434,12 @@ |
| 51356 | 51434 | "svfloat64x3_t tuple", |
| 51357 | 51435 | "uint64_t imm_index" |
| 51358 | 51436 | ], |
| 51437 | "Arguments_Preparation": { | |
| 51438 | "imm_index": { | |
| 51439 | "minimum": 0, | |
| 51440 | "maximum": 2 | |
| 51441 | } | |
| 51442 | }, | |
| 51359 | 51443 | "return_type": { |
| 51360 | 51444 | "value": "svfloat64_t" |
| 51361 | 51445 | }, |
| ... | ... | @@ -51370,6 +51454,12 @@ |
| 51370 | 51454 | "svint16x3_t tuple", |
| 51371 | 51455 | "uint64_t imm_index" |
| 51372 | 51456 | ], |
| 51457 | "Arguments_Preparation": { | |
| 51458 | "imm_index": { | |
| 51459 | "minimum": 0, | |
| 51460 | "maximum": 2 | |
| 51461 | } | |
| 51462 | }, | |
| 51373 | 51463 | "return_type": { |
| 51374 | 51464 | "value": "svint16_t" |
| 51375 | 51465 | }, |
| ... | ... | @@ -51384,6 +51474,12 @@ |
| 51384 | 51474 | "svint32x3_t tuple", |
| 51385 | 51475 | "uint64_t imm_index" |
| 51386 | 51476 | ], |
| 51477 | "Arguments_Preparation": { | |
| 51478 | "imm_index": { | |
| 51479 | "minimum": 0, | |
| 51480 | "maximum": 2 | |
| 51481 | } | |
| 51482 | }, | |
| 51387 | 51483 | "return_type": { |
| 51388 | 51484 | "value": "svint32_t" |
| 51389 | 51485 | }, |
| ... | ... | @@ -51398,6 +51494,12 @@ |
| 51398 | 51494 | "svint64x3_t tuple", |
| 51399 | 51495 | "uint64_t imm_index" |
| 51400 | 51496 | ], |
| 51497 | "Arguments_Preparation": { | |
| 51498 | "imm_index": { | |
| 51499 | "minimum": 0, | |
| 51500 | "maximum": 2 | |
| 51501 | } | |
| 51502 | }, | |
| 51401 | 51503 | "return_type": { |
| 51402 | 51504 | "value": "svint64_t" |
| 51403 | 51505 | }, |
| ... | ... | @@ -51412,6 +51514,12 @@ |
| 51412 | 51514 | "svint8x3_t tuple", |
| 51413 | 51515 | "uint64_t imm_index" |
| 51414 | 51516 | ], |
| 51517 | "Arguments_Preparation": { | |
| 51518 | "imm_index": { | |
| 51519 | "minimum": 0, | |
| 51520 | "maximum": 2 | |
| 51521 | } | |
| 51522 | }, | |
| 51415 | 51523 | "return_type": { |
| 51416 | 51524 | "value": "svint8_t" |
| 51417 | 51525 | }, |
| ... | ... | @@ -51426,6 +51534,12 @@ |
| 51426 | 51534 | "svuint16x3_t tuple", |
| 51427 | 51535 | "uint64_t imm_index" |
| 51428 | 51536 | ], |
| 51537 | "Arguments_Preparation": { | |
| 51538 | "imm_index": { | |
| 51539 | "minimum": 0, | |
| 51540 | "maximum": 2 | |
| 51541 | } | |
| 51542 | }, | |
| 51429 | 51543 | "return_type": { |
| 51430 | 51544 | "value": "svuint16_t" |
| 51431 | 51545 | }, |
| ... | ... | @@ -51440,6 +51554,12 @@ |
| 51440 | 51554 | "svuint32x3_t tuple", |
| 51441 | 51555 | "uint64_t imm_index" |
| 51442 | 51556 | ], |
| 51557 | "Arguments_Preparation": { | |
| 51558 | "imm_index": { | |
| 51559 | "minimum": 0, | |
| 51560 | "maximum": 2 | |
| 51561 | } | |
| 51562 | }, | |
| 51443 | 51563 | "return_type": { |
| 51444 | 51564 | "value": "svuint32_t" |
| 51445 | 51565 | }, |
| ... | ... | @@ -51454,6 +51574,12 @@ |
| 51454 | 51574 | "svuint64x3_t tuple", |
| 51455 | 51575 | "uint64_t imm_index" |
| 51456 | 51576 | ], |
| 51577 | "Arguments_Preparation": { | |
| 51578 | "imm_index": { | |
| 51579 | "minimum": 0, | |
| 51580 | "maximum": 2 | |
| 51581 | } | |
| 51582 | }, | |
| 51457 | 51583 | "return_type": { |
| 51458 | 51584 | "value": "svuint64_t" |
| 51459 | 51585 | }, |
| ... | ... | @@ -51468,6 +51594,12 @@ |
| 51468 | 51594 | "svuint8x3_t tuple", |
| 51469 | 51595 | "uint64_t imm_index" |
| 51470 | 51596 | ], |
| 51597 | "Arguments_Preparation": { | |
| 51598 | "imm_index": { | |
| 51599 | "minimum": 0, | |
| 51600 | "maximum": 2 | |
| 51601 | } | |
| 51602 | }, | |
| 51471 | 51603 | "return_type": { |
| 51472 | 51604 | "value": "svuint8_t" |
| 51473 | 51605 | }, |
| ... | ... | @@ -51482,6 +51614,12 @@ |
| 51482 | 51614 | "svfloat16x4_t tuple", |
| 51483 | 51615 | "uint64_t imm_index" |
| 51484 | 51616 | ], |
| 51617 | "Arguments_Preparation": { | |
| 51618 | "imm_index": { | |
| 51619 | "minimum": 0, | |
| 51620 | "maximum": 3 | |
| 51621 | } | |
| 51622 | }, | |
| 51485 | 51623 | "return_type": { |
| 51486 | 51624 | "value": "svfloat16_t" |
| 51487 | 51625 | }, |
| ... | ... | @@ -51496,6 +51634,12 @@ |
| 51496 | 51634 | "svfloat32x4_t tuple", |
| 51497 | 51635 | "uint64_t imm_index" |
| 51498 | 51636 | ], |
| 51637 | "Arguments_Preparation": { | |
| 51638 | "imm_index": { | |
| 51639 | "minimum": 0, | |
| 51640 | "maximum": 3 | |
| 51641 | } | |
| 51642 | }, | |
| 51499 | 51643 | "return_type": { |
| 51500 | 51644 | "value": "svfloat32_t" |
| 51501 | 51645 | }, |
| ... | ... | @@ -51510,6 +51654,12 @@ |
| 51510 | 51654 | "svfloat64x4_t tuple", |
| 51511 | 51655 | "uint64_t imm_index" |
| 51512 | 51656 | ], |
| 51657 | "Arguments_Preparation": { | |
| 51658 | "imm_index": { | |
| 51659 | "minimum": 0, | |
| 51660 | "maximum": 3 | |
| 51661 | } | |
| 51662 | }, | |
| 51513 | 51663 | "return_type": { |
| 51514 | 51664 | "value": "svfloat64_t" |
| 51515 | 51665 | }, |
| ... | ... | @@ -51524,6 +51674,12 @@ |
| 51524 | 51674 | "svint16x4_t tuple", |
| 51525 | 51675 | "uint64_t imm_index" |
| 51526 | 51676 | ], |
| 51677 | "Arguments_Preparation": { | |
| 51678 | "imm_index": { | |
| 51679 | "minimum": 0, | |
| 51680 | "maximum": 3 | |
| 51681 | } | |
| 51682 | }, | |
| 51527 | 51683 | "return_type": { |
| 51528 | 51684 | "value": "svint16_t" |
| 51529 | 51685 | }, |
| ... | ... | @@ -51538,6 +51694,12 @@ |
| 51538 | 51694 | "svint32x4_t tuple", |
| 51539 | 51695 | "uint64_t imm_index" |
| 51540 | 51696 | ], |
| 51697 | "Arguments_Preparation": { | |
| 51698 | "imm_index": { | |
| 51699 | "minimum": 0, | |
| 51700 | "maximum": 3 | |
| 51701 | } | |
| 51702 | }, | |
| 51541 | 51703 | "return_type": { |
| 51542 | 51704 | "value": "svint32_t" |
| 51543 | 51705 | }, |
| ... | ... | @@ -51552,6 +51714,12 @@ |
| 51552 | 51714 | "svint64x4_t tuple", |
| 51553 | 51715 | "uint64_t imm_index" |
| 51554 | 51716 | ], |
| 51717 | "Arguments_Preparation": { | |
| 51718 | "imm_index": { | |
| 51719 | "minimum": 0, | |
| 51720 | "maximum": 3 | |
| 51721 | } | |
| 51722 | }, | |
| 51555 | 51723 | "return_type": { |
| 51556 | 51724 | "value": "svint64_t" |
| 51557 | 51725 | }, |
| ... | ... | @@ -51566,6 +51734,12 @@ |
| 51566 | 51734 | "svint8x4_t tuple", |
| 51567 | 51735 | "uint64_t imm_index" |
| 51568 | 51736 | ], |
| 51737 | "Arguments_Preparation": { | |
| 51738 | "imm_index": { | |
| 51739 | "minimum": 0, | |
| 51740 | "maximum": 3 | |
| 51741 | } | |
| 51742 | }, | |
| 51569 | 51743 | "return_type": { |
| 51570 | 51744 | "value": "svint8_t" |
| 51571 | 51745 | }, |
| ... | ... | @@ -51580,6 +51754,12 @@ |
| 51580 | 51754 | "svuint16x4_t tuple", |
| 51581 | 51755 | "uint64_t imm_index" |
| 51582 | 51756 | ], |
| 51757 | "Arguments_Preparation": { | |
| 51758 | "imm_index": { | |
| 51759 | "minimum": 0, | |
| 51760 | "maximum": 3 | |
| 51761 | } | |
| 51762 | }, | |
| 51583 | 51763 | "return_type": { |
| 51584 | 51764 | "value": "svuint16_t" |
| 51585 | 51765 | }, |
| ... | ... | @@ -51594,6 +51774,12 @@ |
| 51594 | 51774 | "svuint32x4_t tuple", |
| 51595 | 51775 | "uint64_t imm_index" |
| 51596 | 51776 | ], |
| 51777 | "Arguments_Preparation": { | |
| 51778 | "imm_index": { | |
| 51779 | "minimum": 0, | |
| 51780 | "maximum": 3 | |
| 51781 | } | |
| 51782 | }, | |
| 51597 | 51783 | "return_type": { |
| 51598 | 51784 | "value": "svuint32_t" |
| 51599 | 51785 | }, |
| ... | ... | @@ -51608,6 +51794,12 @@ |
| 51608 | 51794 | "svuint64x4_t tuple", |
| 51609 | 51795 | "uint64_t imm_index" |
| 51610 | 51796 | ], |
| 51797 | "Arguments_Preparation": { | |
| 51798 | "imm_index": { | |
| 51799 | "minimum": 0, | |
| 51800 | "maximum": 3 | |
| 51801 | } | |
| 51802 | }, | |
| 51611 | 51803 | "return_type": { |
| 51612 | 51804 | "value": "svuint64_t" |
| 51613 | 51805 | }, |
| ... | ... | @@ -51622,6 +51814,12 @@ |
| 51622 | 51814 | "svuint8x4_t tuple", |
| 51623 | 51815 | "uint64_t imm_index" |
| 51624 | 51816 | ], |
| 51817 | "Arguments_Preparation": { | |
| 51818 | "imm_index": { | |
| 51819 | "minimum": 0, | |
| 51820 | "maximum": 3 | |
| 51821 | } | |
| 51822 | }, | |
| 51625 | 51823 | "return_type": { |
| 51626 | 51824 | "value": "svuint8_t" |
| 51627 | 51825 | }, |
| ... | ... | @@ -162999,6 +163197,12 @@ |
| 162999 | 163197 | "uint64_t imm_index", |
| 163000 | 163198 | "svfloat16_t x" |
| 163001 | 163199 | ], |
| 163200 | "Arguments_Preparation": { | |
| 163201 | "imm_index": { | |
| 163202 | "minimum": 0, | |
| 163203 | "maximum": 1 | |
| 163204 | } | |
| 163205 | }, | |
| 163002 | 163206 | "return_type": { |
| 163003 | 163207 | "value": "svfloat16x2_t" |
| 163004 | 163208 | }, |
| ... | ... | @@ -163014,6 +163218,12 @@ |
| 163014 | 163218 | "uint64_t imm_index", |
| 163015 | 163219 | "svfloat32_t x" |
| 163016 | 163220 | ], |
| 163221 | "Arguments_Preparation": { | |
| 163222 | "imm_index": { | |
| 163223 | "minimum": 0, | |
| 163224 | "maximum": 1 | |
| 163225 | } | |
| 163226 | }, | |
| 163017 | 163227 | "return_type": { |
| 163018 | 163228 | "value": "svfloat32x2_t" |
| 163019 | 163229 | }, |
| ... | ... | @@ -163029,6 +163239,12 @@ |
| 163029 | 163239 | "uint64_t imm_index", |
| 163030 | 163240 | "svfloat64_t x" |
| 163031 | 163241 | ], |
| 163242 | "Arguments_Preparation": { | |
| 163243 | "imm_index": { | |
| 163244 | "minimum": 0, | |
| 163245 | "maximum": 1 | |
| 163246 | } | |
| 163247 | }, | |
| 163032 | 163248 | "return_type": { |
| 163033 | 163249 | "value": "svfloat64x2_t" |
| 163034 | 163250 | }, |
| ... | ... | @@ -163044,6 +163260,12 @@ |
| 163044 | 163260 | "uint64_t imm_index", |
| 163045 | 163261 | "svint16_t x" |
| 163046 | 163262 | ], |
| 163263 | "Arguments_Preparation": { | |
| 163264 | "imm_index": { | |
| 163265 | "minimum": 0, | |
| 163266 | "maximum": 1 | |
| 163267 | } | |
| 163268 | }, | |
| 163047 | 163269 | "return_type": { |
| 163048 | 163270 | "value": "svint16x2_t" |
| 163049 | 163271 | }, |
| ... | ... | @@ -163059,6 +163281,12 @@ |
| 163059 | 163281 | "uint64_t imm_index", |
| 163060 | 163282 | "svint32_t x" |
| 163061 | 163283 | ], |
| 163284 | "Arguments_Preparation": { | |
| 163285 | "imm_index": { | |
| 163286 | "minimum": 0, | |
| 163287 | "maximum": 1 | |
| 163288 | } | |
| 163289 | }, | |
| 163062 | 163290 | "return_type": { |
| 163063 | 163291 | "value": "svint32x2_t" |
| 163064 | 163292 | }, |
| ... | ... | @@ -163074,6 +163302,12 @@ |
| 163074 | 163302 | "uint64_t imm_index", |
| 163075 | 163303 | "svint64_t x" |
| 163076 | 163304 | ], |
| 163305 | "Arguments_Preparation": { | |
| 163306 | "imm_index": { | |
| 163307 | "minimum": 0, | |
| 163308 | "maximum": 1 | |
| 163309 | } | |
| 163310 | }, | |
| 163077 | 163311 | "return_type": { |
| 163078 | 163312 | "value": "svint64x2_t" |
| 163079 | 163313 | }, |
| ... | ... | @@ -163089,6 +163323,12 @@ |
| 163089 | 163323 | "uint64_t imm_index", |
| 163090 | 163324 | "svint8_t x" |
| 163091 | 163325 | ], |
| 163326 | "Arguments_Preparation": { | |
| 163327 | "imm_index": { | |
| 163328 | "minimum": 0, | |
| 163329 | "maximum": 1 | |
| 163330 | } | |
| 163331 | }, | |
| 163092 | 163332 | "return_type": { |
| 163093 | 163333 | "value": "svint8x2_t" |
| 163094 | 163334 | }, |
| ... | ... | @@ -163104,6 +163344,12 @@ |
| 163104 | 163344 | "uint64_t imm_index", |
| 163105 | 163345 | "svuint16_t x" |
| 163106 | 163346 | ], |
| 163347 | "Arguments_Preparation": { | |
| 163348 | "imm_index": { | |
| 163349 | "minimum": 0, | |
| 163350 | "maximum": 1 | |
| 163351 | } | |
| 163352 | }, | |
| 163107 | 163353 | "return_type": { |
| 163108 | 163354 | "value": "svuint16x2_t" |
| 163109 | 163355 | }, |
| ... | ... | @@ -163119,6 +163365,12 @@ |
| 163119 | 163365 | "uint64_t imm_index", |
| 163120 | 163366 | "svuint32_t x" |
| 163121 | 163367 | ], |
| 163368 | "Arguments_Preparation": { | |
| 163369 | "imm_index": { | |
| 163370 | "minimum": 0, | |
| 163371 | "maximum": 1 | |
| 163372 | } | |
| 163373 | }, | |
| 163122 | 163374 | "return_type": { |
| 163123 | 163375 | "value": "svuint32x2_t" |
| 163124 | 163376 | }, |
| ... | ... | @@ -163134,6 +163386,12 @@ |
| 163134 | 163386 | "uint64_t imm_index", |
| 163135 | 163387 | "svuint64_t x" |
| 163136 | 163388 | ], |
| 163389 | "Arguments_Preparation": { | |
| 163390 | "imm_index": { | |
| 163391 | "minimum": 0, | |
| 163392 | "maximum": 1 | |
| 163393 | } | |
| 163394 | }, | |
| 163137 | 163395 | "return_type": { |
| 163138 | 163396 | "value": "svuint64x2_t" |
| 163139 | 163397 | }, |
| ... | ... | @@ -163149,6 +163407,12 @@ |
| 163149 | 163407 | "uint64_t imm_index", |
| 163150 | 163408 | "svuint8_t x" |
| 163151 | 163409 | ], |
| 163410 | "Arguments_Preparation": { | |
| 163411 | "imm_index": { | |
| 163412 | "minimum": 0, | |
| 163413 | "maximum": 1 | |
| 163414 | } | |
| 163415 | }, | |
| 163152 | 163416 | "return_type": { |
| 163153 | 163417 | "value": "svuint8x2_t" |
| 163154 | 163418 | }, |
| ... | ... | @@ -163164,6 +163428,12 @@ |
| 163164 | 163428 | "uint64_t imm_index", |
| 163165 | 163429 | "svfloat16_t x" |
| 163166 | 163430 | ], |
| 163431 | "Arguments_Preparation": { | |
| 163432 | "imm_index": { | |
| 163433 | "minimum": 0, | |
| 163434 | "maximum": 2 | |
| 163435 | } | |
| 163436 | }, | |
| 163167 | 163437 | "return_type": { |
| 163168 | 163438 | "value": "svfloat16x3_t" |
| 163169 | 163439 | }, |
| ... | ... | @@ -163179,6 +163449,12 @@ |
| 163179 | 163449 | "uint64_t imm_index", |
| 163180 | 163450 | "svfloat32_t x" |
| 163181 | 163451 | ], |
| 163452 | "Arguments_Preparation": { | |
| 163453 | "imm_index": { | |
| 163454 | "minimum": 0, | |
| 163455 | "maximum": 2 | |
| 163456 | } | |
| 163457 | }, | |
| 163182 | 163458 | "return_type": { |
| 163183 | 163459 | "value": "svfloat32x3_t" |
| 163184 | 163460 | }, |
| ... | ... | @@ -163194,6 +163470,12 @@ |
| 163194 | 163470 | "uint64_t imm_index", |
| 163195 | 163471 | "svfloat64_t x" |
| 163196 | 163472 | ], |
| 163473 | "Arguments_Preparation": { | |
| 163474 | "imm_index": { | |
| 163475 | "minimum": 0, | |
| 163476 | "maximum": 2 | |
| 163477 | } | |
| 163478 | }, | |
| 163197 | 163479 | "return_type": { |
| 163198 | 163480 | "value": "svfloat64x3_t" |
| 163199 | 163481 | }, |
| ... | ... | @@ -163209,6 +163491,12 @@ |
| 163209 | 163491 | "uint64_t imm_index", |
| 163210 | 163492 | "svint16_t x" |
| 163211 | 163493 | ], |
| 163494 | "Arguments_Preparation": { | |
| 163495 | "imm_index": { | |
| 163496 | "minimum": 0, | |
| 163497 | "maximum": 2 | |
| 163498 | } | |
| 163499 | }, | |
| 163212 | 163500 | "return_type": { |
| 163213 | 163501 | "value": "svint16x3_t" |
| 163214 | 163502 | }, |
| ... | ... | @@ -163224,6 +163512,12 @@ |
| 163224 | 163512 | "uint64_t imm_index", |
| 163225 | 163513 | "svint32_t x" |
| 163226 | 163514 | ], |
| 163515 | "Arguments_Preparation": { | |
| 163516 | "imm_index": { | |
| 163517 | "minimum": 0, | |
| 163518 | "maximum": 2 | |
| 163519 | } | |
| 163520 | }, | |
| 163227 | 163521 | "return_type": { |
| 163228 | 163522 | "value": "svint32x3_t" |
| 163229 | 163523 | }, |
| ... | ... | @@ -163239,6 +163533,12 @@ |
| 163239 | 163533 | "uint64_t imm_index", |
| 163240 | 163534 | "svint64_t x" |
| 163241 | 163535 | ], |
| 163536 | "Arguments_Preparation": { | |
| 163537 | "imm_index": { | |
| 163538 | "minimum": 0, | |
| 163539 | "maximum": 2 | |
| 163540 | } | |
| 163541 | }, | |
| 163242 | 163542 | "return_type": { |
| 163243 | 163543 | "value": "svint64x3_t" |
| 163244 | 163544 | }, |
| ... | ... | @@ -163254,6 +163554,12 @@ |
| 163254 | 163554 | "uint64_t imm_index", |
| 163255 | 163555 | "svint8_t x" |
| 163256 | 163556 | ], |
| 163557 | "Arguments_Preparation": { | |
| 163558 | "imm_index": { | |
| 163559 | "minimum": 0, | |
| 163560 | "maximum": 2 | |
| 163561 | } | |
| 163562 | }, | |
| 163257 | 163563 | "return_type": { |
| 163258 | 163564 | "value": "svint8x3_t" |
| 163259 | 163565 | }, |
| ... | ... | @@ -163269,6 +163575,12 @@ |
| 163269 | 163575 | "uint64_t imm_index", |
| 163270 | 163576 | "svuint16_t x" |
| 163271 | 163577 | ], |
| 163578 | "Arguments_Preparation": { | |
| 163579 | "imm_index": { | |
| 163580 | "minimum": 0, | |
| 163581 | "maximum": 2 | |
| 163582 | } | |
| 163583 | }, | |
| 163272 | 163584 | "return_type": { |
| 163273 | 163585 | "value": "svuint16x3_t" |
| 163274 | 163586 | }, |
| ... | ... | @@ -163284,6 +163596,12 @@ |
| 163284 | 163596 | "uint64_t imm_index", |
| 163285 | 163597 | "svuint32_t x" |
| 163286 | 163598 | ], |
| 163599 | "Arguments_Preparation": { | |
| 163600 | "imm_index": { | |
| 163601 | "minimum": 0, | |
| 163602 | "maximum": 2 | |
| 163603 | } | |
| 163604 | }, | |
| 163287 | 163605 | "return_type": { |
| 163288 | 163606 | "value": "svuint32x3_t" |
| 163289 | 163607 | }, |
| ... | ... | @@ -163299,6 +163617,12 @@ |
| 163299 | 163617 | "uint64_t imm_index", |
| 163300 | 163618 | "svuint64_t x" |
| 163301 | 163619 | ], |
| 163620 | "Arguments_Preparation": { | |
| 163621 | "imm_index": { | |
| 163622 | "minimum": 0, | |
| 163623 | "maximum": 2 | |
| 163624 | } | |
| 163625 | }, | |
| 163302 | 163626 | "return_type": { |
| 163303 | 163627 | "value": "svuint64x3_t" |
| 163304 | 163628 | }, |
| ... | ... | @@ -163314,6 +163638,12 @@ |
| 163314 | 163638 | "uint64_t imm_index", |
| 163315 | 163639 | "svuint8_t x" |
| 163316 | 163640 | ], |
| 163641 | "Arguments_Preparation": { | |
| 163642 | "imm_index": { | |
| 163643 | "minimum": 0, | |
| 163644 | "maximum": 2 | |
| 163645 | } | |
| 163646 | }, | |
| 163317 | 163647 | "return_type": { |
| 163318 | 163648 | "value": "svuint8x3_t" |
| 163319 | 163649 | }, |
| ... | ... | @@ -163329,6 +163659,12 @@ |
| 163329 | 163659 | "uint64_t imm_index", |
| 163330 | 163660 | "svfloat16_t x" |
| 163331 | 163661 | ], |
| 163662 | "Arguments_Preparation": { | |
| 163663 | "imm_index": { | |
| 163664 | "minimum": 0, | |
| 163665 | "maximum": 3 | |
| 163666 | } | |
| 163667 | }, | |
| 163332 | 163668 | "return_type": { |
| 163333 | 163669 | "value": "svfloat16x4_t" |
| 163334 | 163670 | }, |
| ... | ... | @@ -163344,6 +163680,12 @@ |
| 163344 | 163680 | "uint64_t imm_index", |
| 163345 | 163681 | "svfloat32_t x" |
| 163346 | 163682 | ], |
| 163683 | "Arguments_Preparation": { | |
| 163684 | "imm_index": { | |
| 163685 | "minimum": 0, | |
| 163686 | "maximum": 3 | |
| 163687 | } | |
| 163688 | }, | |
| 163347 | 163689 | "return_type": { |
| 163348 | 163690 | "value": "svfloat32x4_t" |
| 163349 | 163691 | }, |
| ... | ... | @@ -163359,6 +163701,12 @@ |
| 163359 | 163701 | "uint64_t imm_index", |
| 163360 | 163702 | "svfloat64_t x" |
| 163361 | 163703 | ], |
| 163704 | "Arguments_Preparation": { | |
| 163705 | "imm_index": { | |
| 163706 | "minimum": 0, | |
| 163707 | "maximum": 3 | |
| 163708 | } | |
| 163709 | }, | |
| 163362 | 163710 | "return_type": { |
| 163363 | 163711 | "value": "svfloat64x4_t" |
| 163364 | 163712 | }, |
| ... | ... | @@ -163374,6 +163722,12 @@ |
| 163374 | 163722 | "uint64_t imm_index", |
| 163375 | 163723 | "svint16_t x" |
| 163376 | 163724 | ], |
| 163725 | "Arguments_Preparation": { | |
| 163726 | "imm_index": { | |
| 163727 | "minimum": 0, | |
| 163728 | "maximum": 3 | |
| 163729 | } | |
| 163730 | }, | |
| 163377 | 163731 | "return_type": { |
| 163378 | 163732 | "value": "svint16x4_t" |
| 163379 | 163733 | }, |
| ... | ... | @@ -163389,6 +163743,12 @@ |
| 163389 | 163743 | "uint64_t imm_index", |
| 163390 | 163744 | "svint32_t x" |
| 163391 | 163745 | ], |
| 163746 | "Arguments_Preparation": { | |
| 163747 | "imm_index": { | |
| 163748 | "minimum": 0, | |
| 163749 | "maximum": 3 | |
| 163750 | } | |
| 163751 | }, | |
| 163392 | 163752 | "return_type": { |
| 163393 | 163753 | "value": "svint32x4_t" |
| 163394 | 163754 | }, |
| ... | ... | @@ -163404,6 +163764,12 @@ |
| 163404 | 163764 | "uint64_t imm_index", |
| 163405 | 163765 | "svint64_t x" |
| 163406 | 163766 | ], |
| 163767 | "Arguments_Preparation": { | |
| 163768 | "imm_index": { | |
| 163769 | "minimum": 0, | |
| 163770 | "maximum": 3 | |
| 163771 | } | |
| 163772 | }, | |
| 163407 | 163773 | "return_type": { |
| 163408 | 163774 | "value": "svint64x4_t" |
| 163409 | 163775 | }, |
| ... | ... | @@ -163419,6 +163785,12 @@ |
| 163419 | 163785 | "uint64_t imm_index", |
| 163420 | 163786 | "svint8_t x" |
| 163421 | 163787 | ], |
| 163788 | "Arguments_Preparation": { | |
| 163789 | "imm_index": { | |
| 163790 | "minimum": 0, | |
| 163791 | "maximum": 3 | |
| 163792 | } | |
| 163793 | }, | |
| 163422 | 163794 | "return_type": { |
| 163423 | 163795 | "value": "svint8x4_t" |
| 163424 | 163796 | }, |
| ... | ... | @@ -163434,6 +163806,12 @@ |
| 163434 | 163806 | "uint64_t imm_index", |
| 163435 | 163807 | "svuint16_t x" |
| 163436 | 163808 | ], |
| 163809 | "Arguments_Preparation": { | |
| 163810 | "imm_index": { | |
| 163811 | "minimum": 0, | |
| 163812 | "maximum": 3 | |
| 163813 | } | |
| 163814 | }, | |
| 163437 | 163815 | "return_type": { |
| 163438 | 163816 | "value": "svuint16x4_t" |
| 163439 | 163817 | }, |
| ... | ... | @@ -163449,6 +163827,12 @@ |
| 163449 | 163827 | "uint64_t imm_index", |
| 163450 | 163828 | "svuint32_t x" |
| 163451 | 163829 | ], |
| 163830 | "Arguments_Preparation": { | |
| 163831 | "imm_index": { | |
| 163832 | "minimum": 0, | |
| 163833 | "maximum": 3 | |
| 163834 | } | |
| 163835 | }, | |
| 163452 | 163836 | "return_type": { |
| 163453 | 163837 | "value": "svuint32x4_t" |
| 163454 | 163838 | }, |
| ... | ... | @@ -163464,6 +163848,12 @@ |
| 163464 | 163848 | "uint64_t imm_index", |
| 163465 | 163849 | "svuint64_t x" |
| 163466 | 163850 | ], |
| 163851 | "Arguments_Preparation": { | |
| 163852 | "imm_index": { | |
| 163853 | "minimum": 0, | |
| 163854 | "maximum": 3 | |
| 163855 | } | |
| 163856 | }, | |
| 163467 | 163857 | "return_type": { |
| 163468 | 163858 | "value": "svuint64x4_t" |
| 163469 | 163859 | }, |
| ... | ... | @@ -163479,6 +163869,12 @@ |
| 163479 | 163869 | "uint64_t imm_index", |
| 163480 | 163870 | "svuint8_t x" |
| 163481 | 163871 | ], |
| 163872 | "Arguments_Preparation": { | |
| 163873 | "imm_index": { | |
| 163874 | "minimum": 0, | |
| 163875 | "maximum": 3 | |
| 163876 | } | |
| 163877 | }, | |
| 163482 | 163878 | "return_type": { |
| 163483 | 163879 | "value": "svuint8x4_t" |
| 163484 | 163880 | }, |
library/stdarch/rust-version+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 045b17737dab5fcc28e4cbee0cfe2ce4ed363b32 | |
| 1 | 8e150217bafcaaaa0c45bf685c55fd56cec48598 |
src/librustdoc/formats/cache.rs+28-17| ... | ... | @@ -233,6 +233,30 @@ impl Cache { |
| 233 | 233 | } |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | impl 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 | ||
| 236 | 260 | impl DocFolder for CacheBuilder<'_, '_> { |
| 237 | 261 | fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { |
| 238 | 262 | if item.item_id.is_local() { |
| ... | ... | @@ -418,22 +442,9 @@ impl DocFolder for CacheBuilder<'_, '_> { |
| 418 | 442 | // Note: matching twice to restrict the lifetime of the `i` borrow. |
| 419 | 443 | let mut dids = FxIndexSet::default(); |
| 420 | 444 | 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); | |
| 437 | 448 | } |
| 438 | 449 | clean::DynTrait(ref bounds, _) |
| 439 | 450 | | clean::BorrowedRef { type_: clean::DynTrait(ref bounds, _), .. } => { |
| ... | ... | @@ -452,7 +463,7 @@ impl DocFolder for CacheBuilder<'_, '_> { |
| 452 | 463 | && let Some(generics) = trait_.generics() |
| 453 | 464 | { |
| 454 | 465 | for bound in generics { |
| 455 | dids.extend(bound.def_id(self.cache)); | |
| 466 | self.extend_with_fundamental_dids(bound, &mut dids); | |
| 456 | 467 | } |
| 457 | 468 | } |
| 458 | 469 | let impl_item = Impl { impl_item: item }; |
src/rustdoc-json-types/Cargo.toml+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "rustdoc-json-types" |
| 3 | 3 | version = "0.1.0" |
| 4 | edition = "2021" | |
| 4 | edition = "2024" | |
| 5 | 5 | |
| 6 | 6 | [lib] |
| 7 | 7 | path = "lib.rs" |
src/tools/jsondocck/Cargo.toml+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "jsondocck" |
| 3 | 3 | version = "0.1.0" |
| 4 | edition = "2021" | |
| 4 | edition = "2024" | |
| 5 | 5 | |
| 6 | 6 | [dependencies] |
| 7 | 7 | jsonpath-rust = "1.0.0" |
src/tools/jsondoclint/Cargo.toml+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "jsondoclint" |
| 3 | 3 | version = "0.1.0" |
| 4 | edition = "2021" | |
| 4 | edition = "2024" | |
| 5 | 5 | |
| 6 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
| 7 | 7 |
src/tools/miri/README.md+33-20| ... | ... | @@ -171,6 +171,38 @@ available (which affects `cfg(target_feature)`), and it tells Miri to consider t |
| 171 | 171 | that the interpreted program runs on as having the feature available (meaning the code is allowed to |
| 172 | 172 | invoke the corresponding intrinsics). |
| 173 | 173 | |
| 174 | ### Nextest integration | |
| 175 | ||
| 176 | Miri can be combined with [`cargo-nextest`](https://nexte.st): | |
| 177 | ||
| 178 | ``` | |
| 179 | cargo install --locked cargo-nextest | |
| 180 | cargo miri nextest run | |
| 181 | ``` | |
| 182 | ||
| 183 | Nextest 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 | ||
| 192 | However, there is also a big caveat: Miri will [re-compile the test crate every time it is | |
| 193 | invoked](https://github.com/rust-lang/miri/issues/5013), which means a crate with N tests will be | |
| 194 | compiled N+1 times. If the test crate takes a long time to build, this can outweigh the benefits of | |
| 195 | parallelization. | |
| 196 | ||
| 197 | For more information about nextest, see the [`cargo-nextest` Miri | |
| 198 | documentation](https://nexte.st/book/miri.html). | |
| 199 | ||
| 200 | Note: Nextest's one-test-per-process model means that `cargo miri test` is able to detect data | |
| 201 | races where two tests race on a shared resource, but `cargo miri nextest run` will not detect | |
| 202 | such races. | |
| 203 | ||
| 204 | Note: `cargo-nextest` [does not support doctests](https://github.com/nextest-rs/nextest/issues/16). | |
| 205 | ||
| 174 | 206 | ### Testing multiple different executions |
| 175 | 207 | |
| 176 | 208 | Certain 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 |
| 184 | 216 | MIRIFLAGS="-Zmiri-many-seeds=0..16" cargo miri test |
| 185 | 217 | ``` |
| 186 | 218 | |
| 219 | Miri will test the given range of seeds with parallel interpreter instances. | |
| 187 | 220 | The default of 64 different seeds can be quite slow, so you often want to specify a smaller range. |
| 188 | 221 | |
| 189 | 222 | ### Running Miri on CI |
| ... | ... | @@ -243,26 +276,6 @@ However, even for targets that we do support, the degree of support for accessin |
| 243 | 276 | (such as the file system) differs between targets: generally, Linux targets have the best support, |
| 244 | 277 | and macOS targets are usually on par. Windows is supported less well. |
| 245 | 278 | |
| 246 | ### Running tests in parallel | |
| 247 | ||
| 248 | Though it implements Rust threading, Miri itself is a single-threaded interpreter | |
| 249 | (it works like a multi-threaded OS on a single-core CPU). | |
| 250 | This means that when running `cargo miri test`, you will probably see a dramatic | |
| 251 | increase in the amount of time it takes to run your whole test suite due to the | |
| 252 | inherent interpreter slowdown and a loss of parallelism. | |
| 253 | ||
| 254 | You 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). | |
| 256 | This works because `cargo-nextest` collects a list of all tests then launches a | |
| 257 | separate `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 | ||
| 260 | Note: This one-test-per-process model means that `cargo miri test` is able to detect data | |
| 261 | races where two tests race on a shared resource, but `cargo miri nextest run` will not detect | |
| 262 | such races. | |
| 263 | ||
| 264 | Note: `cargo-nextest` does not support doctests, see https://github.com/nextest-rs/nextest/issues/16 | |
| 265 | ||
| 266 | 279 | ### Directly invoking the `miri` driver |
| 267 | 280 | |
| 268 | 281 | The 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: |
| 36 | 36 | This will print the path to the generated sysroot (and nothing else) on stdout. |
| 37 | 37 | stderr will still contain progress information about how the build is doing. |
| 38 | 38 | |
| 39 | For 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 | |
| 39 | 42 | "; |
| 40 | 43 | |
| 41 | 44 | fn show_help() { |
src/tools/miri/ci/ci.sh+1| ... | ... | @@ -168,6 +168,7 @@ case $HOST_TARGET in |
| 168 | 168 | MANY_SEEDS=16 TEST_TARGET=x86_64-unknown-freebsd run_tests |
| 169 | 169 | MANY_SEEDS=16 TEST_TARGET=i686-unknown-freebsd run_tests |
| 170 | 170 | 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 | |
| 171 | 172 | ;; |
| 172 | 173 | armv7-unknown-linux-gnueabihf) |
| 173 | 174 | # Host |
src/tools/miri/priroda/src/main.rs+62-11| ... | ... | @@ -6,6 +6,7 @@ extern crate rustc_data_structures; |
| 6 | 6 | extern crate rustc_driver; |
| 7 | 7 | extern crate rustc_hir; |
| 8 | 8 | extern crate rustc_hir_analysis; |
| 9 | extern crate rustc_index; | |
| 9 | 10 | extern crate rustc_interface; |
| 10 | 11 | extern crate rustc_log; |
| 11 | 12 | extern crate rustc_middle; |
| ... | ... | @@ -19,13 +20,15 @@ use std::path::PathBuf; |
| 19 | 20 | use miri::*; |
| 20 | 21 | use rustc_driver::Compilation; |
| 21 | 22 | use rustc_hir::attrs::CrateType; |
| 23 | use rustc_index::IndexVec; | |
| 22 | 24 | use rustc_interface::interface; |
| 23 | 25 | use rustc_middle::mir; |
| 26 | use rustc_middle::mir::{Local, VarDebugInfoContents}; | |
| 24 | 27 | use rustc_middle::ty::TyCtxt; |
| 25 | 28 | use rustc_session::EarlyDiagCtxt; |
| 26 | 29 | use rustc_session::config::ErrorOutputType; |
| 27 | use rustc_span::Span; | |
| 28 | 30 | use rustc_span::source_map::SourceMap; |
| 31 | use rustc_span::{Span, Symbol}; | |
| 29 | 32 | |
| 30 | 33 | fn find_sysroot() -> String { |
| 31 | 34 | std::env::var("MIRI_SYSROOT") |
| ... | ... | @@ -129,6 +132,11 @@ struct PrirodaContext<'tcx> { |
| 129 | 132 | last_location: Option<SourceLocation>, |
| 130 | 133 | } |
| 131 | 134 | |
| 135 | struct LocalDesc { | |
| 136 | name: Option<Symbol>, | |
| 137 | local: Local, | |
| 138 | ty: String, | |
| 139 | } | |
| 132 | 140 | /// Controls when execution returns to the frontend. |
| 133 | 141 | enum ResumeMode { |
| 134 | 142 | /// Stop at the next visible MIR instruction. |
| ... | ... | @@ -336,15 +344,49 @@ impl<'tcx> PrirodaContext<'tcx> { |
| 336 | 344 | } |
| 337 | 345 | } |
| 338 | 346 | |
| 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. | |
| 340 | 348 | /// |
| 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> { | |
| 344 | 352 | let Some(frame) = self.ecx.active_thread_stack().last() else { |
| 345 | 353 | return Vec::new(); |
| 346 | 354 | }; |
| 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 | |
| 348 | 390 | } |
| 349 | 391 | } |
| 350 | 392 | |
| ... | ... | @@ -366,7 +408,7 @@ enum BreakpointSetResult { |
| 366 | 408 | enum CommandResult { |
| 367 | 409 | ExecutionStopped(StepResult), |
| 368 | 410 | BreakpointResult(BreakpointSetResult), |
| 369 | Locals(Vec<String>), | |
| 411 | Locals(Vec<LocalDesc>), | |
| 370 | 412 | // FIXME: distinguish terminating the debugger session from disconnecting a |
| 371 | 413 | // frontend and terminating the interpreted program once multiple frontends exist. |
| 372 | 414 | TerminateSession, |
| ... | ... | @@ -403,12 +445,21 @@ impl Cli { |
| 403 | 445 | |
| 404 | 446 | BreakpointSetResult::Duplicate => println!("Duplicate breakpoint"), |
| 405 | 447 | }, |
| 406 | CommandResult::Locals(names) => | |
| 407 | if names.is_empty() { | |
| 448 | CommandResult::Locals(locals_desc) => | |
| 449 | if locals_desc.is_empty() { | |
| 408 | 450 | println!("no locals"); |
| 409 | 451 | } 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 | ); | |
| 412 | 463 | } |
| 413 | 464 | }, |
| 414 | 465 | CommandResult::TerminateSession => { |
src/tools/miri/priroda/tests/ui/locals_in_function.stdout+6-2| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | (priroda) breakpoint added: {MANIFEST_DIR}/tests/ui/locals_in_function.rs:5 |
| 2 | 2 | (priroda) Hit breakpoint |
| 3 | 3 | {MANIFEST_DIR}/tests/ui/locals_in_function.rs:5 |
| 4 | (priroda) x | |
| 5 | y | |
| 4 | (priroda) Name: None, Id: _0, Ty: () | |
| 5 | Name: x, Id: _1, Ty: i32 | |
| 6 | Name: y, Id: _2, Ty: bool | |
| 7 | Name: None, Id: _3, Ty: (i32, bool) | |
| 8 | Name: None, Id: _4, Ty: i32 | |
| 9 | Name: None, Id: _5, Ty: bool | |
| 6 | 10 | (priroda) quitting |
src/tools/miri/rust-version+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 01f54e80e888b66d6486a3a95d481b87353016df | |
| 1 | 16761606d606b6ec4d0c88fc9251670742ad9fd2 |
src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs+3-1| ... | ... | @@ -574,7 +574,9 @@ impl<'tcx> Tree { |
| 574 | 574 | // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`). |
| 575 | 575 | // Related to https://github.com/rust-lang/rust/issues/55005. |
| 576 | 576 | && !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! | |
| 578 | 580 | && perm.accessed |
| 579 | 581 | { |
| 580 | 582 | Err(TbError { |
src/tools/miri/src/helpers.rs+7-1| ... | ... | @@ -129,7 +129,13 @@ pub fn iter_exported_symbols<'tcx>( |
| 129 | 129 | || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) |
| 130 | 130 | || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) |
| 131 | 131 | }; |
| 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 { | |
| 133 | 139 | f(LOCAL_CRATE, def_id.into())?; |
| 134 | 140 | } |
| 135 | 141 | } |
src/tools/miri/src/shims/aarch64.rs+39| ... | ... | @@ -146,6 +146,45 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 146 | 146 | } |
| 147 | 147 | } |
| 148 | 148 | |
| 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 | ||
| 149 | 188 | // Vector table lookup: each index selects a byte from the 16-byte table, out-of-range -> 0. |
| 150 | 189 | // Used to implement vtbl1_u8 function. |
| 151 | 190 | // 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> { |
| 789 | 789 | } |
| 790 | 790 | |
| 791 | 791 | // LLVM intrinsics |
| 792 | "llvm.prefetch" => { | |
| 792 | "llvm.prefetch.p0" => { | |
| 793 | 793 | let [p, rw, loc, ty] = |
| 794 | 794 | this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; |
| 795 | 795 |
src/tools/miri/src/shims/unix/foreign_items.rs+33-5| ... | ... | @@ -840,18 +840,46 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 840 | 840 | } |
| 841 | 841 | |
| 842 | 842 | "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 | )?; | |
| 845 | 849 | let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; |
| 846 | 850 | let ptr = this.mmap(addr, length, prot, flags, fd, offset)?; |
| 847 | 851 | this.write_scalar(ptr, dest)?; |
| 848 | 852 | } |
| 849 | 853 | "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 | )?; | |
| 852 | 860 | let result = this.munmap(addr, length)?; |
| 853 | 861 | this.write_scalar(result, dest)?; |
| 854 | 862 | } |
| 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 | } | |
| 855 | 883 | |
| 856 | 884 | "reallocarray" => { |
| 857 | 885 | // Currently this function does not exist on all Unixes, e.g. on macOS. |
| ... | ... | @@ -1410,7 +1438,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1410 | 1438 | let [_, _] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; |
| 1411 | 1439 | this.write_null(dest)?; |
| 1412 | 1440 | } |
| 1413 | "sigaction" | "mprotect" if this.frame_in_std() => { | |
| 1441 | "sigaction" if this.frame_in_std() => { | |
| 1414 | 1442 | let [_, _, _] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; |
| 1415 | 1443 | this.write_null(dest)?; |
| 1416 | 1444 | } |
src/tools/miri/src/shims/unix/mem.rs+105-20| ... | ... | @@ -53,9 +53,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 53 | 53 | return interp_ok(Scalar::from_maybe_pointer(Pointer::without_provenance(addr), this)); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | let prot_read = this.eval_libc_i32("PROT_READ"); | |
| 57 | let prot_write = this.eval_libc_i32("PROT_WRITE"); | |
| 58 | ||
| 59 | 56 | // First, we do some basic argument validation as required by mmap |
| 60 | 57 | if (flags & (map_private | map_shared)).count_ones() != 1 { |
| 61 | 58 | this.set_last_error(LibcError("EINVAL"))?; |
| ... | ... | @@ -80,13 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 80 | 77 | ); |
| 81 | 78 | } |
| 82 | 79 | |
| 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)?; | |
| 90 | 81 | |
| 91 | 82 | // Miri does not support shared mappings, or any of the other extensions that for example |
| 92 | 83 | // Linux has added to the flags arguments. |
| ... | ... | @@ -103,14 +94,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 103 | 94 | } |
| 104 | 95 | |
| 105 | 96 | 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 { | |
| 107 | 98 | this.set_last_error(LibcError("EINVAL"))?; |
| 108 | 99 | return interp_ok(this.eval_libc("MAP_FAILED")); |
| 109 | 100 | }; |
| 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 | } | |
| 114 | 101 | |
| 115 | 102 | let ptr = this.allocate_ptr( |
| 116 | 103 | Size::from_bytes(map_length), |
| ... | ... | @@ -135,13 +122,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 135 | 122 | return this.set_errno_and_return_neg1_i32(LibcError("EINVAL")); |
| 136 | 123 | } |
| 137 | 124 | |
| 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 { | |
| 139 | 126 | return this.set_errno_and_return_neg1_i32(LibcError("EINVAL")); |
| 140 | 127 | }; |
| 141 | if length > this.target_usize_max() { | |
| 142 | this.set_last_error(LibcError("EINVAL"))?; | |
| 143 | return interp_ok(this.eval_libc("MAP_FAILED")); | |
| 144 | } | |
| 145 | 128 | |
| 146 | 129 | let length = Size::from_bytes(length); |
| 147 | 130 | this.deallocate_ptr( |
| ... | ... | @@ -152,4 +135,106 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 152 | 135 | |
| 153 | 136 | interp_ok(Scalar::from_i32(0)) |
| 154 | 137 | } |
| 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 | ||
| 221 | fn 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 | ||
| 227 | fn 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(()) | |
| 155 | 240 | } |
src/tools/miri/src/shims/unix/socket.rs+28-8| ... | ... | @@ -1487,9 +1487,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1487 | 1487 | // Only shutting down the write end doesn't cause an EPOLLHUP event |
| 1488 | 1488 | // and thus we won't set the `write_closed` readiness for it here. |
| 1489 | 1489 | 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: | |
| 1491 | 1491 | // <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; | |
| 1493 | 1493 | |
| 1494 | 1494 | drop(readiness); |
| 1495 | 1495 | |
| ... | ... | @@ -1697,12 +1697,16 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1697 | 1697 | ) -> InterpResult<'tcx, Result<usize, IoError>> { |
| 1698 | 1698 | let this = self.eval_context_mut(); |
| 1699 | 1699 | |
| 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 { | |
| 1701 | 1702 | panic!("try_non_block_send must only be called when the socket is connected") |
| 1702 | 1703 | }; |
| 1703 | 1704 | |
| 1704 | 1705 | // This is a *non-blocking* write. |
| 1705 | 1706 | let result = this.write_to_host(stream, length, buffer_ptr)?; |
| 1707 | ||
| 1708 | drop(state); | |
| 1709 | ||
| 1706 | 1710 | match result { |
| 1707 | 1711 | Err(IoError::HostError(e)) |
| 1708 | 1712 | if matches!(e.kind(), io::ErrorKind::NotConnected | io::ErrorKind::WouldBlock) => |
| ... | ... | @@ -1715,8 +1719,13 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1715 | 1719 | // would be returned on UNIX-like systems. We thus remap this error to an EWOULDBLOCK. |
| 1716 | 1720 | interp_ok(Err(IoError::HostError(io::ErrorKind::WouldBlock.into()))) |
| 1717 | 1721 | } |
| 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 | |
| 1720 | 1729 | // short write means that the write buffer is full. We update the readiness |
| 1721 | 1730 | // accordingly, which means that next time we see "writable" we will report an epoll |
| 1722 | 1731 | // edge. Some applications (e.g. tokio) rely on this behavior; see |
| ... | ... | @@ -1820,7 +1829,8 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1820 | 1829 | ) -> InterpResult<'tcx, Result<usize, IoError>> { |
| 1821 | 1830 | let this = self.eval_context_mut(); |
| 1822 | 1831 | |
| 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 { | |
| 1824 | 1834 | panic!("try_non_block_recv must only be called when the socket is connected") |
| 1825 | 1835 | }; |
| 1826 | 1836 | |
| ... | ... | @@ -1832,6 +1842,9 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1832 | 1842 | length, |
| 1833 | 1843 | buffer_ptr, |
| 1834 | 1844 | )?; |
| 1845 | ||
| 1846 | drop(state); | |
| 1847 | ||
| 1835 | 1848 | match result { |
| 1836 | 1849 | Err(IoError::HostError(e)) |
| 1837 | 1850 | if matches!(e.kind(), io::ErrorKind::NotConnected | io::ErrorKind::WouldBlock) => |
| ... | ... | @@ -1844,9 +1857,16 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { |
| 1844 | 1857 | // would be returned on UNIX-like systems. We thus remap this error to an EWOULDBLOCK. |
| 1845 | 1858 | interp_ok(Err(IoError::HostError(io::ErrorKind::WouldBlock.into()))) |
| 1846 | 1859 | } |
| 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 | { | |
| 1848 | 1866 | // 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.) | |
| 1850 | 1870 | // On Unix hosts using the `epoll` and `kqueue` backends, a short read means that the |
| 1851 | 1871 | // read buffer is empty. We update the readiness accordingly, which means that next time |
| 1852 | 1872 | // 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; |
| 35 | 35 | #[inline] |
| 36 | 36 | fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { |
| 37 | 37 | 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, | |
| 39 | 45 | os => throw_unsup_format!("`pthread_mutexattr` is not supported on {os}"), |
| 40 | 46 | }) |
| 41 | 47 | } |
| ... | ... | @@ -135,8 +141,8 @@ impl SyncObj for PthreadMutex { |
| 135 | 141 | fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> { |
| 136 | 142 | let offset = match &ecx.tcx.sess.target.os { |
| 137 | 143 | 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, | |
| 140 | 146 | os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"), |
| 141 | 147 | }; |
| 142 | 148 | let offset = Size::from_bytes(offset); |
| ... | ... | @@ -163,7 +169,7 @@ fn mutex_init_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, Size> |
| 163 | 169 | check_static_initializer("PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP"); |
| 164 | 170 | check_static_initializer("PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP"); |
| 165 | 171 | } |
| 166 | Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android => { | |
| 172 | Os::Illumos | Os::Solaris | Os::MacOs | Os::FreeBsd | Os::Android | Os::NetBsd => { | |
| 167 | 173 | // No non-standard initializers. |
| 168 | 174 | } |
| 169 | 175 | 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>( |
| 879 | 879 | assert_eq!(left.layout.size, dest.layout.size); |
| 880 | 880 | |
| 881 | 881 | let (num_chunks, op_items_per_chunk, left) = split_simd_to_128bit_chunks(ecx, left)?; |
| 882 | assert!(num_chunks <= 2); | |
| 883 | ||
| 882 | 884 | let (_, _, right) = split_simd_to_128bit_chunks(ecx, right)?; |
| 883 | 885 | let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(ecx, dest)?; |
| 884 | 886 | |
| 885 | 887 | assert_eq!(op_items_per_chunk, dest_items_per_chunk.strict_mul(2)); |
| 886 | 888 | |
| 887 | 889 | 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); | |
| 894 | 890 | |
| 895 | 891 | for i in 0..num_chunks { |
| 896 | 892 | let left = ecx.project_index(&left, i)?; |
| 897 | 893 | let right = ecx.project_index(&right, i)?; |
| 898 | 894 | let dest = ecx.project_index(&dest, i)?; |
| 899 | 895 | |
| 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 | ||
| 900 | 906 | 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); | |
| 902 | 908 | let mut res: u16 = 0; |
| 903 | 909 | for k in 0..4 { |
| 904 | 910 | let left = ecx |
| 905 | 911 | .read_scalar(&ecx.project_index(&left, left_offset.strict_add(k))?)? |
| 906 | 912 | .to_u8()?; |
| 907 | 913 | 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))?)? | |
| 909 | 915 | .to_u8()?; |
| 910 | 916 | res = res.strict_add(left.abs_diff(right).into()); |
| 911 | 917 | } |
src/tools/miri/test-cargo-miri/run-test.py+4-3| ... | ... | @@ -170,9 +170,10 @@ def test_cargo_miri_test(): |
| 170 | 170 | "test.empty.ref", |
| 171 | 171 | env={'MIRIFLAGS': "-Zmiri-disable-isolation"}, |
| 172 | 172 | ) |
| 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"}, | |
| 176 | 177 | ) |
| 177 | 178 | test("`cargo miri test` (custom target dir)", |
| 178 | 179 | cargo_miri("test") + ["--target-dir=custom-test"], |
src/tools/miri/test-cargo-miri/test.proc-macro.stderr.ref deleted-2| ... | ... | @@ -1,2 +0,0 @@ |
| 1 | warning: unit tests of `proc-macro` crates are executed outside Miri | |
| 2 | warning: 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 | ||
| 2 | running 0 tests | |
| 3 | ||
| 4 | test 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 @@ |
| 1 | warning: unit tests of `proc-macro` crates are executed outside Miri | |
| 2 | warning: 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 | ||
| 2 | running 2 tests | |
| 3 | .. | |
| 4 | test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 5 | ||
| 6 | imported main | |
| 7 | ||
| 8 | running 6 tests | |
| 9 | ...i.. | |
| 10 | test result: ok. 5 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 11 | ||
| 12 | ||
| 13 | running 0 tests | |
| 14 | ||
| 15 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 16 | ||
| 17 | ||
| 18 | running 0 tests | |
| 19 | ||
| 20 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 21 | ||
| 22 | ||
| 23 | running 0 tests | |
| 24 | ||
| 25 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 26 | ||
| 27 | ||
| 28 | running 0 tests | |
| 29 | ||
| 30 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 31 | ||
| 32 | ||
| 33 | running 0 tests | |
| 34 | ||
| 35 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 36 | ||
| 37 | ||
| 38 | running 0 tests | |
| 39 | ||
| 40 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 41 | ||
| 42 | ||
| 43 | running 0 tests | |
| 44 | ||
| 45 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 46 | ||
| 47 | ||
| 48 | running 0 tests | |
| 49 | ||
| 50 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 51 | ||
| 52 | ||
| 53 | running 0 tests | |
| 54 | ||
| 55 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 56 | ||
| 57 | subcrate testing | |
| 58 | ||
| 59 | running 0 tests | |
| 60 | ||
| 61 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 62 | ||
| 63 | ||
| 64 | running 5 tests | |
| 65 | ..... | |
| 66 | test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 67 | ||
| 68 | all doctests ran in $TIME; merged doctests compilation took $TIME | |
| 69 | ||
| 70 | running 0 tests | |
| 71 | ||
| 72 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 73 | ||
| 74 | ||
| 75 | running 0 tests | |
| 76 | ||
| 77 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 78 | ||
| 79 | ||
| 80 | running 0 tests | |
| 81 | ||
| 82 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 83 | ||
| 84 | ||
| 85 | running 0 tests | |
| 86 | ||
| 87 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 88 | ||
| 89 | ||
| 90 | running 0 tests | |
| 91 | ||
| 92 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 93 | ||
| 94 | ||
| 95 | running 0 tests | |
| 96 | ||
| 97 | test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME | |
| 98 | ||
| 99 | ||
| 100 | running 1 test | |
| 101 | . | |
| 102 | test 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 = [ |
| 290 | 290 | name = "miri-test-deps" |
| 291 | 291 | version = "0.1.0" |
| 292 | 292 | dependencies = [ |
| 293 | "cfg-if", | |
| 294 | 293 | "futures", |
| 295 | 294 | "getrandom 0.1.16", |
| 296 | 295 | "getrandom 0.2.17", |
src/tools/miri/tests/deps/Cargo.toml-1| ... | ... | @@ -10,7 +10,6 @@ edition = "2021" |
| 10 | 10 | # all dependencies (and their transitive ones) listed here can be used in `tests/*-dep`. |
| 11 | 11 | libc = "0.2" |
| 12 | 12 | num_cpus = "1.10.1" |
| 13 | cfg-if = "1" | |
| 14 | 13 | |
| 15 | 14 | getrandom_01 = { package = "getrandom", version = "0.1" } |
| 16 | 15 | getrandom_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 @@ |
| 4 | 4 | |
| 5 | 5 | use std::thread; |
| 6 | 6 | |
| 7 | #[path = "../../utils/libc.rs"] | |
| 8 | mod libc_utils; | |
| 9 | use libc_utils::*; | |
| 10 | ||
| 7 | 11 | // Test the behaviour of a thread being blocked on an eventfd read, get unblocked, and then |
| 8 | 12 | // get blocked again. |
| 9 | 13 | |
| ... | ... | @@ -18,7 +22,7 @@ fn main() { |
| 18 | 22 | // eventfd write will block when EFD_NONBLOCK flag is clear |
| 19 | 23 | // and the addition caused counter to exceed u64::MAX - 1. |
| 20 | 24 | let flags = libc::EFD_CLOEXEC; |
| 21 | let fd = unsafe { libc::eventfd(0, flags) }; | |
| 25 | let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); | |
| 22 | 26 | |
| 23 | 27 | let thread1 = thread::spawn(move || { |
| 24 | 28 | 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 @@ |
| 4 | 4 | |
| 5 | 5 | use std::thread; |
| 6 | 6 | |
| 7 | #[path = "../../utils/libc.rs"] | |
| 8 | mod libc_utils; | |
| 9 | use libc_utils::*; | |
| 10 | ||
| 7 | 11 | // Test the behaviour of a thread being blocked on an eventfd `write`, get unblocked, and then |
| 8 | 12 | // get blocked again. |
| 9 | 13 | |
| ... | ... | @@ -17,7 +21,7 @@ fn main() { |
| 17 | 21 | // eventfd write will block when EFD_NONBLOCK flag is clear |
| 18 | 22 | // and the addition caused counter to exceed u64::MAX - 1. |
| 19 | 23 | let flags = libc::EFD_CLOEXEC; |
| 20 | let fd = unsafe { libc::eventfd(0, flags) }; | |
| 24 | let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap(); | |
| 21 | 25 | // Write u64 - 1, so the all subsequent write will block. |
| 22 | 26 | let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); |
| 23 | 27 | 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::*; |
| 16 | 16 | |
| 17 | 17 | fn main() { |
| 18 | 18 | // 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(); | |
| 21 | 20 | |
| 22 | 21 | // Create two socketpair instances. |
| 23 | 22 | 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; |
| 7 | 7 | #[path = "../../utils/libc.rs"] |
| 8 | 8 | mod libc_utils; |
| 9 | 9 | use libc_utils::epoll::*; |
| 10 | use libc_utils::*; | |
| 10 | 11 | |
| 11 | 12 | // Test if only one thread is unblocked if multiple threads blocked on same epfd. |
| 12 | 13 | // Expected execution: |
| ... | ... | @@ -16,14 +17,13 @@ use libc_utils::epoll::*; |
| 16 | 17 | // 4. Thread 1 deadlocks. |
| 17 | 18 | fn main() { |
| 18 | 19 | // 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(); | |
| 21 | 21 | |
| 22 | 22 | // Create an eventfd instance. |
| 23 | 23 | 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(); | |
| 25 | 25 | // 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(); | |
| 27 | 27 | |
| 28 | 28 | // Register both with epoll. |
| 29 | 29 | 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 @@ |
| 1 | 1 | //@only-target: linux android illumos |
| 2 | 2 | |
| 3 | #[path = "../../utils/libc.rs"] | |
| 4 | mod libc_utils; | |
| 5 | use libc_utils::*; | |
| 6 | ||
| 3 | 7 | // This is a test for registering unsupported fd with epoll. |
| 4 | 8 | // Register epoll fd with epoll is allowed in real system, but we do not support this. |
| 5 | 9 | fn main() { |
| 6 | 10 | // 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(); | |
| 11 | 13 | |
| 12 | 14 | // Register epoll with epoll. |
| 13 | 15 | 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 | ||
| 5 | fn 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 @@ |
| 1 | error: Undefined Behavior: `madvise` called on out-of-bounds memory | |
| 2 | --> tests/fail-dep/libc/madvise_out_of_bounds.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 11 | ||
| 12 | error: 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 | ||
| 5 | fn 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 @@ |
| 1 | error: Undefined Behavior: `mprotect` called on out-of-bounds memory | |
| 2 | --> tests/fail-dep/libc/mprotect_out_of_bounds.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 |
src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.rs-1| ... | ... | @@ -1,5 +1,4 @@ |
| 1 | 1 | //@ignore-target: windows # No libc socketpair on Windows |
| 2 | // test_race depends on a deterministic schedule. | |
| 3 | 2 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | 3 | //@error-in-other-file: deadlock |
| 5 | 4 | //@require-annotations-for-level: error |
src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.rs-1| ... | ... | @@ -1,5 +1,4 @@ |
| 1 | 1 | //@ignore-target: windows # No libc socketpair on Windows |
| 2 | // test_race depends on a deterministic schedule. | |
| 3 | 2 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | 3 | //@error-in-other-file: deadlock |
| 5 | 4 | //@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 | ||
| 7 | fn inner(x: &mut i32, f: fn(&mut i32)) { | |
| 8 | // `f` may mutate, but it may not deallocate! | |
| 9 | f(x) | |
| 10 | } | |
| 11 | ||
| 12 | fn 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 @@ |
| 1 | error: Undefined Behavior: deallocating while item [Unique for <TAG>] is strongly protected | |
| 2 | --> RUSTLIB/alloc/src/boxed.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | ||
| 25 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 26 | ||
| 27 | error: 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 @@ |
| 1 | error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden | |
| 2 | --> RUSTLIB/alloc/src/boxed.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: the accessed tag <TAG> was created here | |
| 12 | --> tests/fail/both_borrows/deallocate_against_protector1.rs:LL:CC | |
| 13 | | | |
| 14 | LL | drop(unsafe { Box::from_raw(raw) }); | |
| 15 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 16 | help: 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 | | | |
| 19 | LL | 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 | ||
| 37 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 38 | ||
| 39 | error: 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 | ||
| 7 | use std::alloc::Layout; | |
| 8 | ||
| 9 | fn inner(x: &mut (), f: fn(&mut ())) { | |
| 10 | // `f` may mutate, but it may not deallocate! | |
| 11 | f(x) | |
| 12 | } | |
| 13 | ||
| 14 | fn 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 @@ |
| 1 | error: 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 | | | |
| 4 | LL | 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 | |
| 9 | help: <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 | | | |
| 12 | LL | 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 | ||
| 24 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 25 | ||
| 26 | error: 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 @@ |
| 1 | error: Undefined Behavior: deallocation through <TAG> at ALLOC[0x0] is forbidden | |
| 2 | --> tests/fail/both_borrows/deallocate_against_protector2.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: 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 | | | |
| 14 | LL | 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 | ||
| 26 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 27 | ||
| 28 | error: 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 | ||
| 3 | fn inner(x: &mut i32, f: fn(&mut i32)) { | |
| 4 | // `f` may mutate, but it may not deallocate! | |
| 5 | f(x) | |
| 6 | } | |
| 7 | ||
| 8 | fn 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 @@ |
| 1 | error: Undefined Behavior: deallocating while item [Unique for <TAG>] is strongly protected | |
| 2 | --> RUSTLIB/alloc/src/boxed.rs:LL:CC | |
| 3 | | | |
| 4 | LL | 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 | ||
| 25 | note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | |
| 26 | ||
| 27 | error: 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() { |
| 146 | 146 | events: (EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO) as u32, |
| 147 | 147 | u64: u64::try_from(fds[1]).unwrap(), |
| 148 | 148 | }; |
| 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) }; | |
| 150 | 150 | assert_eq!(res, 0); |
| 151 | 151 | |
| 152 | 152 | // Test EPOLL_CTL_DEL. |
| ... | ... | @@ -158,10 +158,8 @@ fn test_epoll_ctl_del() { |
| 158 | 158 | // This test is for one fd registered under two different epoll instance. |
| 159 | 159 | fn test_two_epoll_instance() { |
| 160 | 160 | // 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(); | |
| 165 | 163 | |
| 166 | 164 | // Create a socketpair instance. |
| 167 | 165 | let mut fds = [-1, -1]; |
| ... | ... | @@ -570,8 +568,7 @@ fn test_epoll_ctl_epfd_equal_fd() { |
| 570 | 568 | // epfd that shouldn't receive a notification in edge-triggered mode. |
| 571 | 569 | fn test_epoll_ctl_notification() { |
| 572 | 570 | // 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(); | |
| 575 | 572 | |
| 576 | 573 | // Create a socketpair instance. |
| 577 | 574 | let mut fds = [-1, -1]; |
| ... | ... | @@ -584,8 +581,7 @@ fn test_epoll_ctl_notification() { |
| 584 | 581 | check_epoll_wait_noblock(epfd0, &[Ev { events: EPOLLOUT, data: fds[0] }]); |
| 585 | 582 | |
| 586 | 583 | // 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(); | |
| 589 | 585 | |
| 590 | 586 | // Register the same file description for epfd1. |
| 591 | 587 | epoll_ctl_add(epfd1, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap(); |
| ... | ... | @@ -692,8 +688,7 @@ fn test_issue_3858() { |
| 692 | 688 | /// Ensure that if a socket becomes un-writable, we don't see it any more. |
| 693 | 689 | fn test_issue_4374() { |
| 694 | 690 | // 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(); | |
| 697 | 692 | |
| 698 | 693 | // Create a socketpair instance, make it non-blocking. |
| 699 | 694 | let mut fds = [-1, -1]; |
| ... | ... | @@ -721,8 +716,7 @@ fn test_issue_4374() { |
| 721 | 716 | /// Same as above, but for becoming un-readable. |
| 722 | 717 | fn test_issue_4374_reads() { |
| 723 | 718 | // 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(); | |
| 726 | 720 | |
| 727 | 721 | // Create a socketpair instance, make it non-blocking. |
| 728 | 722 | let mut fds = [-1, -1]; |
src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs+15-10| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | //@only-target: linux android illumos |
| 2 | 2 | // test_race, test_blocking_read and test_blocking_write depend on a deterministic schedule. |
| 3 | 3 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint |
| 6 | 7 | #![allow(static_mut_refs)] |
| ... | ... | @@ -9,6 +10,7 @@ use std::{io, thread}; |
| 9 | 10 | |
| 10 | 11 | #[path = "../../utils/libc.rs"] |
| 11 | 12 | mod libc_utils; |
| 13 | use libc_utils::*; | |
| 12 | 14 | |
| 13 | 15 | fn main() { |
| 14 | 16 | test_read_write(); |
| ... | ... | @@ -35,8 +37,8 @@ fn write_bytes<const N: usize>(fd: i32, data: [u8; N]) -> io::Result<usize> { |
| 35 | 37 | } |
| 36 | 38 | |
| 37 | 39 | fn 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(); | |
| 40 | 42 | let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes(); |
| 41 | 43 | // Write 1 to the counter. |
| 42 | 44 | let res = write_bytes(fd, sized_8_data).unwrap(); |
| ... | ... | @@ -97,9 +99,15 @@ fn test_read_write() { |
| 97 | 99 | |
| 98 | 100 | fn test_race() { |
| 99 | 101 | 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(); | |
| 102 | 105 | 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 | ||
| 103 | 111 | let mut buf: [u8; 8] = [0; 8]; |
| 104 | 112 | let res = read_bytes(fd, &mut buf).unwrap(); |
| 105 | 113 | // read returns number of bytes has been read, which is always 8. |
| ... | ... | @@ -130,8 +138,7 @@ fn test_syscall() { |
| 130 | 138 | // This test will block on eventfd read then get unblocked by `write`. |
| 131 | 139 | fn test_blocking_read() { |
| 132 | 140 | // 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(); | |
| 135 | 142 | let thread1 = thread::spawn(move || { |
| 136 | 143 | let mut buf: [u8; 8] = [0; 8]; |
| 137 | 144 | // This will block. |
| ... | ... | @@ -154,8 +161,7 @@ fn test_blocking_read() { |
| 154 | 161 | fn test_blocking_write() { |
| 155 | 162 | // eventfd write will block when EFD_NONBLOCK flag is clear |
| 156 | 163 | // 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(); | |
| 159 | 165 | // Write u64 - 1, so the all subsequent write will block. |
| 160 | 166 | let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); |
| 161 | 167 | let res: i64 = unsafe { |
| ... | ... | @@ -192,8 +198,7 @@ fn test_blocking_write() { |
| 192 | 198 | fn test_two_threads_blocked_on_eventfd() { |
| 193 | 199 | // eventfd write will block when EFD_NONBLOCK flag is clear |
| 194 | 200 | // 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(); | |
| 197 | 202 | // Write u64 - 1, so the all subsequent write will block. |
| 198 | 203 | let sized_8_data: [u8; 8] = (u64::MAX - 1).to_ne_bytes(); |
| 199 | 204 | let res: i64 = unsafe { |
src/tools/miri/tests/pass-dep/libc/libc-fs.rs+5-4| ... | ... | @@ -272,7 +272,7 @@ fn test_dup() { |
| 272 | 272 | let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap(); |
| 273 | 273 | |
| 274 | 274 | 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(); | |
| 276 | 276 | let new_fd = libc::dup(fd); |
| 277 | 277 | let new_fd2 = libc::dup2(fd, 8); |
| 278 | 278 | |
| ... | ... | @@ -856,8 +856,8 @@ fn test_readdir() { |
| 856 | 856 | assert!(!dirp.is_null()); |
| 857 | 857 | let mut entries = Vec::new(); |
| 858 | 858 | loop { |
| 859 | cfg_if::cfg_if! { | |
| 860 | if #[cfg(target_os = "macos")] { | |
| 859 | cfg_select! { | |
| 860 | target_os = "macos" => { | |
| 861 | 861 | // On macos we only support readdir_r as that's what std uses there. |
| 862 | 862 | use std::mem::MaybeUninit; |
| 863 | 863 | use libc::dirent; |
| ... | ... | @@ -866,7 +866,8 @@ fn test_readdir() { |
| 866 | 866 | let ret = libc::readdir_r(dirp, entry.as_mut_ptr(), &mut result); |
| 867 | 867 | assert_eq!(ret, 0); |
| 868 | 868 | let entry_ptr = result; |
| 869 | } else { | |
| 869 | } | |
| 870 | _ => { | |
| 870 | 871 | let entry_ptr = libc::readdir(dirp); |
| 871 | 872 | } |
| 872 | 873 | } |
src/tools/miri/tests/pass-dep/libc/libc-pipe.rs+2-1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | //@ignore-target: windows # No libc pipe on Windows |
| 2 | 2 | // test_race depends on a deterministic schedule. |
| 3 | 3 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | //@run-native | |
| 4 | 5 | use std::thread; |
| 5 | 6 | |
| 6 | 7 | #[path = "../../utils/libc.rs"] |
| ... | ... | @@ -39,7 +40,7 @@ fn test_pipe() { |
| 39 | 40 | let data = b"123"; |
| 40 | 41 | write_all(fds[1], data).unwrap(); |
| 41 | 42 | 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(); | |
| 43 | 44 | assert_eq!(part1[..], data[..part1.len()]); |
| 44 | 45 | // Write 2 more bytes so we can exactly fill the `rest`. |
| 45 | 46 | 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() { |
| 28 | 28 | test_readiness_after_short_read(); |
| 29 | 29 | test_readiness_after_short_peek(); |
| 30 | 30 | test_readiness_after_short_write(); |
| 31 | test_readable_after_read_shutdown_and_short_read(); | |
| 32 | test_writable_after_write_shutdown_with_full_buffer(); | |
| 31 | 33 | } |
| 32 | 34 | |
| 33 | 35 | /// Test that connecting to a server socket works when the client |
| ... | ... | @@ -359,7 +361,7 @@ fn test_shutdown_read_write() { |
| 359 | 361 | let (server_sockfd, addr) = net::make_listener_ipv4().unwrap(); |
| 360 | 362 | let client_sockfd = |
| 361 | 363 | 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(); | |
| 363 | 365 | |
| 364 | 366 | // Spawn the server thread. |
| 365 | 367 | let server_thread = thread::spawn(move || net::accept_ipv4(server_sockfd).unwrap()); |
| ... | ... | @@ -387,7 +389,7 @@ fn test_shutdown_read() { |
| 387 | 389 | let (server_sockfd, addr) = net::make_listener_ipv4().unwrap(); |
| 388 | 390 | let client_sockfd = |
| 389 | 391 | 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(); | |
| 391 | 393 | |
| 392 | 394 | // Spawn the server thread. |
| 393 | 395 | let server_thread = thread::spawn(move || net::accept_ipv4(server_sockfd).unwrap()); |
| ... | ... | @@ -411,7 +413,7 @@ fn test_shutdown_write() { |
| 411 | 413 | let (server_sockfd, addr) = net::make_listener_ipv4().unwrap(); |
| 412 | 414 | let client_sockfd = |
| 413 | 415 | 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(); | |
| 415 | 417 | |
| 416 | 418 | // Spawn the server thread. |
| 417 | 419 | let server_thread = thread::spawn(move || { |
| ... | ... | @@ -562,24 +564,14 @@ fn test_readiness_after_short_write() { |
| 562 | 564 | unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() }; |
| 563 | 565 | let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap(); |
| 564 | 566 | |
| 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 | ||
| 573 | 567 | net::connect_ipv4(client_sockfd, addr).unwrap(); |
| 568 | let (peerfd, _) = net::accept_ipv4(server_sockfd).unwrap(); | |
| 574 | 569 | |
| 575 | 570 | unsafe { |
| 576 | 571 | // Change client socket to be non-blocking. |
| 577 | 572 | errno_check(libc::fcntl(client_sockfd, libc::F_SETFL, libc::O_NONBLOCK)); |
| 578 | 573 | } |
| 579 | 574 | |
| 580 | // The peer socket is a blocking socket. | |
| 581 | let peerfd = server_thread.join().unwrap(); | |
| 582 | ||
| 583 | 575 | // Add client socket with writable interest to epoll. |
| 584 | 576 | epoll_ctl_add(epfd, client_sockfd, EPOLLET | EPOLLOUT).unwrap(); |
| 585 | 577 | |
| ... | ... | @@ -636,3 +628,153 @@ fn test_readiness_after_short_write() { |
| 636 | 628 | // We should again be able to write into the socket. |
| 637 | 629 | libc_utils::write_all(client_sockfd, &buffer).unwrap(); |
| 638 | 630 | } |
| 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. | |
| 634 | fn 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. | |
| 716 | fn 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 @@ |
| 1 | 1 | //@ignore-target: windows # No libc socketpair on Windows |
| 2 | 2 | // test_race depends on a deterministic schedule. |
| 3 | 3 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint |
| 6 | 7 | #![allow(static_mut_refs)] |
| ... | ... | @@ -34,7 +35,7 @@ fn test_socketpair() { |
| 34 | 35 | let data = b"abc"; |
| 35 | 36 | write_all(fds[0], data).unwrap(); |
| 36 | 37 | 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(); | |
| 38 | 39 | assert_eq!(read[..], data[..read.len()]); |
| 39 | 40 | // Write 2 more bytes so we can exactly fill the `rest`. |
| 40 | 41 | write_all(fds[0], b"12").unwrap(); |
| ... | ... | @@ -52,7 +53,7 @@ fn test_socketpair() { |
| 52 | 53 | let data = b"abc"; |
| 53 | 54 | write_all(fds[1], data).unwrap(); |
| 54 | 55 | 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(); | |
| 56 | 57 | assert_eq!(read[..], data[..read.len()]); |
| 57 | 58 | // Write 2 more bytes so we can exactly fill the `rest`. |
| 58 | 59 | write_all(fds[1], b"12").unwrap(); |
| ... | ... | @@ -64,9 +65,9 @@ fn test_socketpair() { |
| 64 | 65 | errno_check(unsafe { libc::close(fds[0]) }); |
| 65 | 66 | // Reading the other end should return that data, then EOF. |
| 66 | 67 | 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(); | |
| 68 | 69 | 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(); | |
| 70 | 71 | assert_eq!(read, &[]); |
| 71 | 72 | // Writing the other end should emit EPIPE. |
| 72 | 73 | let err = write_all(fds[1], &mut buf).unwrap_err(); |
| ... | ... | @@ -132,6 +133,11 @@ fn test_blocking_read() { |
| 132 | 133 | |
| 133 | 134 | // Test the behaviour of a socketpair getting blocked on write and subsequently unblocked. |
| 134 | 135 | fn test_blocking_write() { |
| 136 | // The test uses Miri's exact buffer size. | |
| 137 | if !cfg!(miri) { | |
| 138 | return; | |
| 139 | } | |
| 140 | ||
| 135 | 141 | let mut fds = [-1, -1]; |
| 136 | 142 | errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }); |
| 137 | 143 | let arr1: [u8; 0x34000] = [1; 0x34000]; |
src/tools/miri/tests/pass-dep/libc/libc-time.rs+67-37| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | //@ignore-target: windows # no libc time APIs on Windows |
| 2 | 2 | //@compile-flags: -Zmiri-disable-isolation |
| 3 | //@run-native | |
| 3 | 4 | |
| 4 | 5 | #[path = "../../utils/libc.rs"] |
| 5 | 6 | mod libc_utils; |
| ... | ... | @@ -9,6 +10,17 @@ use std::{env, mem, ptr}; |
| 9 | 10 | |
| 10 | 11 | use libc_utils::errno_check; |
| 11 | 12 | |
| 13 | fn 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 | ||
| 12 | 24 | fn main() { |
| 13 | 25 | test_clocks(); |
| 14 | 26 | test_posix_gettimeofday(); |
| ... | ... | @@ -66,11 +78,13 @@ fn test_posix_gettimeofday() { |
| 66 | 78 | assert!(tv.tv_sec > 0); |
| 67 | 79 | assert!(tv.tv_usec >= 0); // Theoretically this could be 0. |
| 68 | 80 | |
| 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 | } | |
| 74 | 88 | } |
| 75 | 89 | |
| 76 | 90 | /// Helper function to create an empty tm struct. |
| ... | ... | @@ -104,9 +118,8 @@ fn create_empty_tm() -> libc::tm { |
| 104 | 118 | |
| 105 | 119 | /// Original GMT test |
| 106 | 120 | fn test_localtime_r_gmt() { |
| 107 | // Set timezone to GMT. | |
| 108 | let key = "TZ"; | |
| 109 | env::set_var(key, "GMT"); | |
| 121 | set_tz("GMT"); | |
| 122 | ||
| 110 | 123 | const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT |
| 111 | 124 | let custom_time_ptr = &TIME_SINCE_EPOCH; |
| 112 | 125 | let mut tm = create_empty_tm(); |
| ... | ... | @@ -120,7 +133,9 @@ fn test_localtime_r_gmt() { |
| 120 | 133 | assert_eq!(tm.tm_year, 124); |
| 121 | 134 | assert_eq!(tm.tm_wday, 0); |
| 122 | 135 | 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 | } | |
| 124 | 139 | #[cfg(any( |
| 125 | 140 | target_os = "linux", |
| 126 | 141 | target_os = "macos", |
| ... | ... | @@ -130,21 +145,21 @@ fn test_localtime_r_gmt() { |
| 130 | 145 | { |
| 131 | 146 | assert_eq!(tm.tm_gmtoff, 0); |
| 132 | 147 | 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 | ); | |
| 134 | 152 | } |
| 135 | 153 | } |
| 136 | 154 | |
| 137 | 155 | // The returned value is the pointer passed in. |
| 138 | 156 | assert!(ptr::eq(res, &mut tm)); |
| 139 | ||
| 140 | // Remove timezone setting. | |
| 141 | env::remove_var(key); | |
| 142 | 157 | } |
| 143 | 158 | |
| 144 | 159 | /// PST timezone test (testing different timezone handling). |
| 145 | 160 | fn test_localtime_r_pst() { |
| 146 | let key = "TZ"; | |
| 147 | env::set_var(key, "PST8PDT"); | |
| 161 | set_tz("PST8PDT"); | |
| 162 | ||
| 148 | 163 | const TIME_SINCE_EPOCH: libc::time_t = 1712475836; // 2024-04-07 07:43:56 GMT |
| 149 | 164 | let custom_time_ptr = &TIME_SINCE_EPOCH; |
| 150 | 165 | let mut tm = create_empty_tm(); |
| ... | ... | @@ -159,7 +174,9 @@ fn test_localtime_r_pst() { |
| 159 | 174 | assert_eq!(tm.tm_year, 124); |
| 160 | 175 | assert_eq!(tm.tm_wday, 0); |
| 161 | 176 | 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 | } | |
| 163 | 180 | |
| 164 | 181 | #[cfg(any( |
| 165 | 182 | target_os = "linux", |
| ... | ... | @@ -170,18 +187,20 @@ fn test_localtime_r_pst() { |
| 170 | 187 | { |
| 171 | 188 | assert_eq!(tm.tm_gmtoff, -7 * 3600); // -7 hours in seconds |
| 172 | 189 | 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 | ); | |
| 174 | 194 | } |
| 175 | 195 | } |
| 176 | 196 | |
| 177 | 197 | assert!(ptr::eq(res, &mut tm)); |
| 178 | env::remove_var(key); | |
| 179 | 198 | } |
| 180 | 199 | |
| 181 | 200 | /// Unix epoch test (edge case testing). |
| 182 | 201 | fn test_localtime_r_epoch() { |
| 183 | let key = "TZ"; | |
| 184 | env::set_var(key, "GMT"); | |
| 202 | set_tz("GMT"); | |
| 203 | ||
| 185 | 204 | const TIME_SINCE_EPOCH: libc::time_t = 0; // 1970-01-01 00:00:00 |
| 186 | 205 | let custom_time_ptr = &TIME_SINCE_EPOCH; |
| 187 | 206 | let mut tm = create_empty_tm(); |
| ... | ... | @@ -196,7 +215,9 @@ fn test_localtime_r_epoch() { |
| 196 | 215 | assert_eq!(tm.tm_year, 70); |
| 197 | 216 | assert_eq!(tm.tm_wday, 4); // Thursday |
| 198 | 217 | 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 | } | |
| 200 | 221 | |
| 201 | 222 | #[cfg(any( |
| 202 | 223 | target_os = "linux", |
| ... | ... | @@ -207,19 +228,20 @@ fn test_localtime_r_epoch() { |
| 207 | 228 | { |
| 208 | 229 | assert_eq!(tm.tm_gmtoff, 0); |
| 209 | 230 | 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 | ); | |
| 211 | 235 | } |
| 212 | 236 | } |
| 213 | 237 | |
| 214 | 238 | assert!(ptr::eq(res, &mut tm)); |
| 215 | env::remove_var(key); | |
| 216 | 239 | } |
| 217 | 240 | |
| 218 | 241 | /// Future date test (testing large values). |
| 219 | 242 | #[cfg(target_pointer_width = "64")] |
| 220 | 243 | fn test_localtime_r_future_64b() { |
| 221 | let key = "TZ"; | |
| 222 | env::set_var(key, "GMT"); | |
| 244 | set_tz("GMT"); | |
| 223 | 245 | |
| 224 | 246 | // Using 2050-01-01 00:00:00 for 64-bit systems |
| 225 | 247 | // value that's safe for 64-bit time_t |
| ... | ... | @@ -237,7 +259,9 @@ fn test_localtime_r_future_64b() { |
| 237 | 259 | assert_eq!(tm.tm_year, 150); // 2050 - 1900 |
| 238 | 260 | assert_eq!(tm.tm_wday, 6); // Saturday |
| 239 | 261 | 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 | } | |
| 241 | 265 | |
| 242 | 266 | #[cfg(any( |
| 243 | 267 | target_os = "linux", |
| ... | ... | @@ -248,19 +272,20 @@ fn test_localtime_r_future_64b() { |
| 248 | 272 | { |
| 249 | 273 | assert_eq!(tm.tm_gmtoff, 0); |
| 250 | 274 | 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 | ); | |
| 252 | 279 | } |
| 253 | 280 | } |
| 254 | 281 | |
| 255 | 282 | assert!(ptr::eq(res, &mut tm)); |
| 256 | env::remove_var(key); | |
| 257 | 283 | } |
| 258 | 284 | |
| 259 | 285 | /// Future date test (testing large values for 32b target). |
| 260 | 286 | #[cfg(target_pointer_width = "32")] |
| 261 | 287 | fn test_localtime_r_future_32b() { |
| 262 | let key = "TZ"; | |
| 263 | env::set_var(key, "GMT"); | |
| 288 | set_tz("GMT"); | |
| 264 | 289 | |
| 265 | 290 | // Using 2030-01-01 00:00:00 for 32-bit systems |
| 266 | 291 | // Safe value within i32 range |
| ... | ... | @@ -279,7 +304,9 @@ fn test_localtime_r_future_32b() { |
| 279 | 304 | assert_eq!(tm.tm_year, 130); // 2030 - 1900 |
| 280 | 305 | assert_eq!(tm.tm_wday, 2); // Tuesday |
| 281 | 306 | 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 | } | |
| 283 | 310 | |
| 284 | 311 | #[cfg(any( |
| 285 | 312 | target_os = "linux", |
| ... | ... | @@ -290,19 +317,20 @@ fn test_localtime_r_future_32b() { |
| 290 | 317 | { |
| 291 | 318 | assert_eq!(tm.tm_gmtoff, 0); |
| 292 | 319 | 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 | ); | |
| 294 | 324 | } |
| 295 | 325 | } |
| 296 | 326 | |
| 297 | 327 | assert!(ptr::eq(res, &mut tm)); |
| 298 | env::remove_var(key); | |
| 299 | 328 | } |
| 300 | 329 | |
| 301 | 330 | /// Tests the behavior of `localtime_r` with multiple calls to ensure deduplication of `tm_zone` pointers. |
| 302 | 331 | #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android"))] |
| 303 | 332 | fn test_localtime_r_multiple_calls_deduplication() { |
| 304 | let key = "TZ"; | |
| 305 | env::set_var(key, "PST8PDT"); | |
| 333 | set_tz("PST8PDT"); | |
| 306 | 334 | |
| 307 | 335 | const TIME_SINCE_EPOCH_BASE: libc::time_t = 1712475836; // Base timestamp: 2024-04-07 07:43:56 GMT |
| 308 | 336 | const NUM_CALLS: usize = 50; |
| ... | ... | @@ -321,9 +349,11 @@ fn test_localtime_r_multiple_calls_deduplication() { |
| 321 | 349 | |
| 322 | 350 | let unique_count = unique_pointers.len(); |
| 323 | 351 | |
| 352 | // Miri non-determinisitcally de-duplicates. Native always deduplicates. | |
| 353 | let min = if cfg!(miri) { 2 } else { 1 }; | |
| 324 | 354 | 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 {})", | |
| 327 | 357 | unique_count, |
| 328 | 358 | NUM_CALLS - 1 |
| 329 | 359 | ); |
src/tools/miri/tests/pass-dep/libc/mmap.rs+74| ... | ... | @@ -94,6 +94,78 @@ fn test_mmap<Offset: Default>( |
| 94 | 94 | assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | fn 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 | ||
| 133 | fn 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 | ||
| 97 | 169 | #[cfg(target_os = "linux")] |
| 98 | 170 | fn test_mremap() { |
| 99 | 171 | let page_size = page_size::get(); |
| ... | ... | @@ -145,6 +217,8 @@ fn main() { |
| 145 | 217 | test_mmap(libc::mmap); |
| 146 | 218 | #[cfg(target_os = "linux")] |
| 147 | 219 | test_mmap(libc::mmap64); |
| 220 | test_mprotect(); | |
| 221 | test_madvise(); | |
| 148 | 222 | #[cfg(target_os = "linux")] |
| 149 | 223 | test_mremap(); |
| 150 | 224 | } |
src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs+49-35| ... | ... | @@ -4,17 +4,21 @@ use std::ffi::{CStr, CString}; |
| 4 | 4 | use std::thread; |
| 5 | 5 | |
| 6 | 6 | const MAX_THREAD_NAME_LEN: usize = { |
| 7 | cfg_if::cfg_if! { | |
| 8 | if #[cfg(any(target_os = "linux"))] { | |
| 7 | cfg_select! { | |
| 8 | target_os = "linux" => { | |
| 9 | 9 | 16 |
| 10 | } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { | |
| 10 | } | |
| 11 | any(target_os = "illumos", target_os = "solaris") => { | |
| 11 | 12 | 32 |
| 12 | } else if #[cfg(target_os = "macos")] { | |
| 13 | } | |
| 14 | target_os = "macos" => { | |
| 13 | 15 | libc::MAXTHREADNAMESIZE // 64, at the time of writing |
| 14 | } else if #[cfg(target_os = "freebsd")] { | |
| 16 | } | |
| 17 | target_os = "freebsd" => { | |
| 15 | 18 | usize::MAX // as far as I can tell |
| 16 | } else { | |
| 17 | panic!() | |
| 19 | } | |
| 20 | _ => { | |
| 21 | compile_error!("unsupported OS"); | |
| 18 | 22 | } |
| 19 | 23 | } |
| 20 | 24 | }; |
| ... | ... | @@ -28,35 +32,38 @@ fn main() { |
| 28 | 32 | .collect::<String>(); |
| 29 | 33 | |
| 30 | 34 | fn set_thread_name(name: &CStr) -> i32 { |
| 31 | cfg_if::cfg_if! { | |
| 32 | if #[cfg(any( | |
| 35 | cfg_select! { | |
| 36 | any( | |
| 33 | 37 | target_os = "linux", |
| 34 | 38 | target_os = "freebsd", |
| 35 | 39 | target_os = "illumos", |
| 36 | 40 | target_os = "solaris" |
| 37 | ))] { | |
| 41 | ) => { | |
| 38 | 42 | unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) } |
| 39 | } else if #[cfg(target_os = "macos")] { | |
| 43 | } | |
| 44 | target_os = "macos" => { | |
| 40 | 45 | unsafe { libc::pthread_setname_np(name.as_ptr().cast()) } |
| 41 | } else { | |
| 46 | } | |
| 47 | _ => { | |
| 42 | 48 | compile_error!("set_thread_name not supported for this OS") |
| 43 | 49 | } |
| 44 | 50 | } |
| 45 | 51 | } |
| 46 | 52 | |
| 47 | 53 | fn get_thread_name(name: &mut [u8]) -> i32 { |
| 48 | cfg_if::cfg_if! { | |
| 49 | if #[cfg(any( | |
| 54 | cfg_select! { | |
| 55 | any( | |
| 50 | 56 | target_os = "linux", |
| 51 | 57 | target_os = "freebsd", |
| 52 | 58 | target_os = "illumos", |
| 53 | 59 | target_os = "solaris", |
| 54 | 60 | target_os = "macos" |
| 55 | ))] { | |
| 61 | ) => { | |
| 56 | 62 | unsafe { |
| 57 | 63 | libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len()) |
| 58 | 64 | } |
| 59 | } else { | |
| 65 | } | |
| 66 | _ => { | |
| 60 | 67 | compile_error!("get_thread_name not supported for this OS") |
| 61 | 68 | } |
| 62 | 69 | } |
| ... | ... | @@ -95,13 +102,14 @@ fn main() { |
| 95 | 102 | |
| 96 | 103 | // Test what happens when the buffer is shorter than 16, but still long enough. |
| 97 | 104 | 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" => { | |
| 100 | 107 | // For glibc used by linux-gnu there should be a failue, |
| 101 | 108 | // if a shorter than 16 bytes buffer is provided, even if that would be |
| 102 | 109 | // large enough for the thread name. |
| 103 | 110 | assert_eq!(res, libc::ERANGE); |
| 104 | } else { | |
| 111 | } | |
| 112 | _ => { | |
| 105 | 113 | // Everywhere else, this should work. |
| 106 | 114 | assert_eq!(res, 0); |
| 107 | 115 | // POSIX seems to promise at least 15 chars excluding a null terminator. |
| ... | ... | @@ -112,15 +120,16 @@ fn main() { |
| 112 | 120 | |
| 113 | 121 | // Test what happens when the buffer is too short even for the short name. |
| 114 | 122 | 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") => { | |
| 117 | 125 | // On macOS and FreeBSD it's not an error for the buffer to be |
| 118 | 126 | // too short for the thread name -- they truncate instead. |
| 119 | 127 | assert_eq!(res, 0); |
| 120 | 128 | let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); |
| 121 | 129 | assert_eq!(cstr.to_bytes_with_nul().len(), 4); |
| 122 | 130 | assert!(short_name.as_bytes().starts_with(cstr.to_bytes())); |
| 123 | } else { | |
| 131 | } | |
| 132 | _ => { | |
| 124 | 133 | // The rest should give an error. |
| 125 | 134 | assert_eq!(res, libc::ERANGE); |
| 126 | 135 | } |
| ... | ... | @@ -128,12 +137,13 @@ fn main() { |
| 128 | 137 | |
| 129 | 138 | // Test zero-sized buffer. |
| 130 | 139 | 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") => { | |
| 133 | 142 | // On macOS and FreeBSD it's not an error for the buffer to be |
| 134 | 143 | // too short for the thread name -- even with size 0. |
| 135 | 144 | assert_eq!(res, 0); |
| 136 | } else { | |
| 145 | } | |
| 146 | _ => { | |
| 137 | 147 | // The rest should give an error. |
| 138 | 148 | assert_eq!(res, libc::ERANGE); |
| 139 | 149 | } |
| ... | ... | @@ -149,16 +159,18 @@ fn main() { |
| 149 | 159 | // Set full thread name. |
| 150 | 160 | let cstr = CString::new(long_name.clone()).unwrap(); |
| 151 | 161 | let res = set_thread_name(&cstr); |
| 152 | cfg_if::cfg_if! { | |
| 153 | if #[cfg(target_os = "freebsd")] { | |
| 162 | cfg_select! { | |
| 163 | target_os = "freebsd" => { | |
| 154 | 164 | // Names of all size are supported. |
| 155 | 165 | assert!(cstr.to_bytes_with_nul().len() <= MAX_THREAD_NAME_LEN); |
| 156 | 166 | assert_eq!(res, 0); |
| 157 | } else if #[cfg(target_os = "macos")] { | |
| 167 | } | |
| 168 | target_os = "macos" => { | |
| 158 | 169 | // Name is too long. |
| 159 | 170 | assert!(cstr.to_bytes_with_nul().len() > MAX_THREAD_NAME_LEN); |
| 160 | 171 | assert_eq!(res, libc::ENAMETOOLONG); |
| 161 | } else { | |
| 172 | } | |
| 173 | _ => { | |
| 162 | 174 | // Name is too long. |
| 163 | 175 | assert!(cstr.to_bytes_with_nul().len() > MAX_THREAD_NAME_LEN); |
| 164 | 176 | assert_eq!(res, libc::ERANGE); |
| ... | ... | @@ -179,14 +191,15 @@ fn main() { |
| 179 | 191 | |
| 180 | 192 | // Test what happens when our buffer is just one byte too small. |
| 181 | 193 | 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") => { | |
| 184 | 196 | // On macOS and FreeBSD it's not an error for the buffer to be |
| 185 | 197 | // too short for the thread name -- they truncate instead. |
| 186 | 198 | assert_eq!(res, 0); |
| 187 | 199 | let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); |
| 188 | 200 | assert_eq!(cstr.to_bytes(), &truncated_name.as_bytes()[..(truncated_name.len() - 1)]); |
| 189 | } else { | |
| 201 | } | |
| 202 | _ => { | |
| 190 | 203 | // The rest should give an error. |
| 191 | 204 | assert_eq!(res, libc::ERANGE); |
| 192 | 205 | } |
| ... | ... | @@ -199,10 +212,11 @@ fn main() { |
| 199 | 212 | // Now set the name for a non-existing thread and verify error codes. |
| 200 | 213 | let invalid_thread = 0xdeadbeef; |
| 201 | 214 | let error = { |
| 202 | cfg_if::cfg_if! { | |
| 203 | if #[cfg(target_os = "linux")] { | |
| 215 | cfg_select! { | |
| 216 | target_os = "linux" => { | |
| 204 | 217 | libc::ENOENT |
| 205 | } else { | |
| 218 | } | |
| 219 | _ => { | |
| 206 | 220 | libc::ESRCH |
| 207 | 221 | } |
| 208 | 222 | } |
src/tools/miri/tests/pass-dep/shims/gettid.rs+18-10| ... | ... | @@ -5,29 +5,37 @@ |
| 5 | 5 | #![feature(linkage)] |
| 6 | 6 | |
| 7 | 7 | fn 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") => { | |
| 10 | 10 | gettid_linux_like() |
| 11 | } else if #[cfg(target_os = "nto")] { | |
| 11 | } | |
| 12 | target_os = "nto" => { | |
| 12 | 13 | unsafe { libc::gettid() as u64 } |
| 13 | } else if #[cfg(target_os = "openbsd")] { | |
| 14 | } | |
| 15 | target_os = "openbsd" => { | |
| 14 | 16 | unsafe { libc::getthrid() as u64 } |
| 15 | } else if #[cfg(target_os = "freebsd")] { | |
| 17 | } | |
| 18 | target_os = "freebsd" => { | |
| 16 | 19 | unsafe { libc::pthread_getthreadid_np() as u64 } |
| 17 | } else if #[cfg(target_os = "netbsd")] { | |
| 20 | } | |
| 21 | target_os = "netbsd" => { | |
| 18 | 22 | 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") => { | |
| 20 | 25 | // On Solaris and Illumos, the `pthread_t` is the OS TID. |
| 21 | 26 | unsafe { libc::pthread_self() as u64 } |
| 22 | } else if #[cfg(target_vendor = "apple")] { | |
| 27 | } | |
| 28 | target_vendor = "apple" => { | |
| 23 | 29 | let mut id = 0u64; |
| 24 | 30 | let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) }; |
| 25 | 31 | assert_eq!(status, 0); |
| 26 | 32 | id |
| 27 | } else if #[cfg(windows)] { | |
| 33 | } | |
| 34 | windows => { | |
| 28 | 35 | use windows_sys::Win32::System::Threading::GetCurrentThreadId; |
| 29 | 36 | unsafe { GetCurrentThreadId() as u64 } |
| 30 | } else { | |
| 37 | } | |
| 38 | _ => { | |
| 31 | 39 | compile_error!("platform has no gettid") |
| 32 | 40 | } |
| 33 | 41 | } |
src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.rs created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | fn main() { | |
| 2 | foo(1234); | |
| 3 | } | |
| 4 | ||
| 5 | #[allow(no_mangle_generic_items)] | |
| 6 | #[unsafe(no_mangle)] | |
| 7 | fn 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 @@ |
| 1 | 1234 |
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-aes.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing aarch64 AES target specific features. |
| 2 | 2 | //@only-target: aarch64 |
| 3 | 3 | //@compile-flags: -C target-feature=+neon,+aes |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | use std::arch::aarch64::*; |
| 6 | 7 | use std::arch::is_aarch64_feature_detected; |
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-crc32.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing aarch64 CRC32 target specific features |
| 2 | 2 | //@only-target: aarch64 |
| 3 | 3 | //@compile-flags: -C target-feature=+crc |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | use std::arch::aarch64::*; |
| 6 | 7 | use std::arch::is_aarch64_feature_detected; |
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-neon.rs+50| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing aarch64 target specific features |
| 2 | 2 | //@only-target: aarch64 |
| 3 | 3 | //@compile-flags: -C target-feature=+neon |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | use std::arch::aarch64::*; |
| 6 | 7 | use std::arch::is_aarch64_feature_detected; |
| ... | ... | @@ -14,6 +15,7 @@ fn main() { |
| 14 | 15 | test_tbl1_v16i8_basic(); |
| 15 | 16 | test_vpadd(); |
| 16 | 17 | test_vpaddl(); |
| 18 | test_vqdmulh(); | |
| 17 | 19 | } |
| 18 | 20 | } |
| 19 | 21 | |
| ... | ... | @@ -157,3 +159,51 @@ unsafe fn test_vpaddl() { |
| 157 | 159 | vst1q_u64(r.as_mut_ptr(), vpaddlq_u32(a)); |
| 158 | 160 | assert_eq!(r, e); |
| 159 | 161 | } |
| 162 | ||
| 163 | #[target_feature(enable = "neon")] | |
| 164 | unsafe 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 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+sha,+sse2,+ssse3,+sse4.1 |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+adx |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] |
| 6 | 7 | mod x86 { |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs+8-2| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+aes,+vaes,+avx512f |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | use core::mem::transmute; |
| 6 | 7 | #[cfg(target_arch = "x86")] |
| ... | ... | @@ -11,7 +12,6 @@ use std::arch::x86_64::*; |
| 11 | 12 | fn main() { |
| 12 | 13 | assert!(is_x86_feature_detected!("aes")); |
| 13 | 14 | assert!(is_x86_feature_detected!("vaes")); |
| 14 | assert!(is_x86_feature_detected!("avx512f")); | |
| 15 | 15 | |
| 16 | 16 | unsafe { |
| 17 | 17 | test_aes(); |
| ... | ... | @@ -86,7 +86,7 @@ unsafe fn test_aes() { |
| 86 | 86 | // be interpreted as integers; signedness does not make sense for them, but |
| 87 | 87 | // __m128i happens to be defined in terms of signed integers. |
| 88 | 88 | #[allow(overflowing_literals)] |
| 89 | #[target_feature(enable = "vaes,avx512f")] | |
| 89 | #[target_feature(enable = "vaes")] | |
| 90 | 90 | unsafe fn test_vaes() { |
| 91 | 91 | #[target_feature(enable = "avx")] |
| 92 | 92 | unsafe fn get_a256() -> __m256i { |
| ... | ... | @@ -177,6 +177,12 @@ unsafe fn test_vaes() { |
| 177 | 177 | } |
| 178 | 178 | test_mm256_aesenclast_epi128(); |
| 179 | 179 | |
| 180 | // The tests below require avx512. | |
| 181 | if !is_x86_feature_detected!("avx512f") { | |
| 182 | println!("warning: skipping avx512 tests"); | |
| 183 | return; | |
| 184 | } | |
| 185 | ||
| 180 | 186 | #[target_feature(enable = "avx512f")] |
| 181 | 187 | unsafe fn get_a512() -> __m512i { |
| 182 | 188 | // Constants are random |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+avx |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx2.rs+14-5| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+avx2 |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
| ... | ... | @@ -1068,23 +1069,31 @@ unsafe fn test_avx2() { |
| 1068 | 1069 | 18, 20, 22, 24, 26, 28, 30, |
| 1069 | 1070 | ); |
| 1070 | 1071 | |
| 1071 | let r = _mm256_mpsadbw_epu8::<0b000>(a, a); | |
| 1072 | let r = _mm256_mpsadbw_epu8::<0b00000>(a, a); | |
| 1072 | 1073 | let e = _mm256_setr_epi16(0, 4, 8, 12, 16, 20, 24, 28, 0, 8, 16, 24, 32, 40, 48, 56); |
| 1073 | 1074 | assert_eq_m256i(r, e); |
| 1074 | 1075 | |
| 1075 | let r = _mm256_mpsadbw_epu8::<0b001>(a, a); | |
| 1076 | let r = _mm256_mpsadbw_epu8::<0b001001>(a, a); | |
| 1076 | 1077 | let e = _mm256_setr_epi16(16, 12, 8, 4, 0, 4, 8, 12, 32, 24, 16, 8, 0, 8, 16, 24); |
| 1077 | 1078 | assert_eq_m256i(r, e); |
| 1078 | 1079 | |
| 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); | |
| 1080 | 1089 | let e = _mm256_setr_epi16(16, 20, 24, 28, 32, 36, 40, 44, 32, 40, 48, 56, 64, 72, 80, 88); |
| 1081 | 1090 | assert_eq_m256i(r, e); |
| 1082 | 1091 | |
| 1083 | let r = _mm256_mpsadbw_epu8::<0b101>(a, a); | |
| 1092 | let r = _mm256_mpsadbw_epu8::<0b101101>(a, a); | |
| 1084 | 1093 | let e = _mm256_setr_epi16(0, 4, 8, 12, 16, 20, 24, 28, 0, 8, 16, 24, 32, 40, 48, 56); |
| 1085 | 1094 | assert_eq_m256i(r, e); |
| 1086 | 1095 | |
| 1087 | let r = _mm256_mpsadbw_epu8::<0b111>(a, a); | |
| 1096 | let r = _mm256_mpsadbw_epu8::<0b111111>(a, a); | |
| 1088 | 1097 | let e = _mm256_setr_epi16(32, 28, 24, 20, 16, 12, 8, 4, 64, 56, 48, 40, 32, 24, 16, 8); |
| 1089 | 1098 | assert_eq_m256i(r, e); |
| 1090 | 1099 | } |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx512.rs+8| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512bitalg,+avx512vpopcntdq,+avx512vnni,+avx512vbmi |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
| ... | ... | @@ -9,6 +10,13 @@ use std::arch::x86_64::*; |
| 9 | 10 | use std::mem::transmute; |
| 10 | 11 | |
| 11 | 12 | fn 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 | ||
| 12 | 20 | assert!(is_x86_feature_detected!("avx512f")); |
| 13 | 21 | assert!(is_x86_feature_detected!("avx512vl")); |
| 14 | 22 | assert!(is_x86_feature_detected!("avx512bw")); |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+bmi1,+bmi2 |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs+17-5| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+gfni,+avx512f |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | // The constants in the tests below are just bit patterns. They should not |
| 6 | 7 | // be interpreted as integers; signedness does not make sense for them, but |
| ... | ... | @@ -20,8 +21,14 @@ const CONSTANT_BYTE: i32 = 0x63; |
| 20 | 21 | fn main() { |
| 21 | 22 | // Mostly copied from library/stdarch/crates/core_arch/src/x86/gfni.rs |
| 22 | 23 | |
| 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 | } | |
| 25 | 32 | |
| 26 | 33 | unsafe { |
| 27 | 34 | let byte_mul_test_data = generate_byte_mul_test_data(); |
| ... | ... | @@ -29,15 +36,20 @@ fn main() { |
| 29 | 36 | let affine_mul_test_data_constant = generate_affine_mul_test_data(CONSTANT_BYTE as u8); |
| 30 | 37 | let inv_tests_data = generate_inv_tests_data(); |
| 31 | 38 | |
| 32 | test_mm512_gf2p8mul_epi8(&byte_mul_test_data); | |
| 33 | 39 | test_mm256_gf2p8mul_epi8(&byte_mul_test_data); |
| 34 | 40 | test_mm_gf2p8mul_epi8(&byte_mul_test_data); |
| 35 | test_mm512_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity); | |
| 36 | 41 | test_mm256_gf2p8affine_epi64_epi8(&byte_mul_test_data, &affine_mul_test_data_identity); |
| 37 | 42 | 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); | |
| 39 | 43 | test_mm256_gf2p8affineinv_epi64_epi8(&inv_tests_data, &affine_mul_test_data_constant); |
| 40 | 44 | 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 | } | |
| 41 | 53 | } |
| 42 | 54 | } |
| 43 | 55 |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-pclmulqdq.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+pclmulqdq |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs+1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | //@run-native | |
| 3 | 4 | #![allow(unnecessary_transmutes)] |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse2.rs+1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | //@run-native | |
| 3 | 4 | #![allow(unnecessary_transmutes)] |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse3-ssse3.rs+1| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | // SSSE3 implicitly enables SSE3 |
| 4 | 4 | //@compile-flags: -C target-feature=+ssse3 |
| 5 | //@run-native | |
| 5 | 6 | |
| 6 | 7 | use core::mem::transmute; |
| 7 | 8 | #[cfg(target_arch = "x86")] |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse41.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+sse4.1 |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse42.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // We're testing x86 target specific features |
| 2 | 2 | //@only-target: x86_64 i686 |
| 3 | 3 | //@compile-flags: -C target-feature=+sse4.2 |
| 4 | //@run-native | |
| 4 | 5 | |
| 5 | 6 | #[cfg(target_arch = "x86")] |
| 6 | 7 | use std::arch::x86::*; |
src/tools/miri/tests/pass/shims/x86/intrinsics-x86-vpclmulqdq.rs+1| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | //@only-target: x86_64 i686 |
| 4 | 4 | //@[avx512]compile-flags: -C target-feature=+vpclmulqdq,+avx512f |
| 5 | 5 | //@[avx]compile-flags: -C target-feature=+vpclmulqdq,+avx2 |
| 6 | //@run-native | |
| 6 | 7 | |
| 7 | 8 | // The constants in the tests below are just bit patterns. They should not |
| 8 | 9 | // 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 | ||
| 2 | 4 | mod x86 { |
| 3 | 5 | #[cfg(target_arch = "x86")] |
| 4 | 6 | use core::arch::x86 as arch; |
| ... | ... | @@ -84,7 +86,6 @@ mod x86_64 { |
| 84 | 86 | } |
| 85 | 87 | |
| 86 | 88 | fn main() { |
| 87 | #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | |
| 88 | 89 | x86::main(); |
| 89 | 90 | #[cfg(target_arch = "x86_64")] |
| 90 | 91 | 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]> |
| 86 | 86 | /// Do a single read from `fd` and return the part of the buffer that was written into, |
| 87 | 87 | /// and the rest. |
| 88 | 88 | #[track_caller] |
| 89 | pub fn read_split_slice(fd: libc::c_int, buf: &mut [u8]) -> io::Result<(&mut [u8], &mut [u8])> { | |
| 89 | pub fn read_partial(fd: libc::c_int, buf: &mut [u8]) -> io::Result<(&mut [u8], &mut [u8])> { | |
| 90 | 90 | let res = errno_result(unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) })?; |
| 91 | 91 | Ok(buf.split_at_mut(res as usize)) |
| 92 | 92 | } |
src/tools/tidy/src/issues.txt-1| ... | ... | @@ -2442,7 +2442,6 @@ ui/span/issue-42234-unknown-receiver-type.rs |
| 2442 | 2442 | ui/span/issue-43927-non-ADT-derive.rs |
| 2443 | 2443 | ui/span/issue-71363.rs |
| 2444 | 2444 | ui/span/issue-81800.rs |
| 2445 | ui/span/issue28498-reject-ex1.rs | |
| 2446 | 2445 | ui/span/issue28498-reject-lifetime-param.rs |
| 2447 | 2446 | ui/span/issue28498-reject-passed-to-fn.rs |
| 2448 | 2447 | ui/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 | ||
| 7 | use std::pin::Pin; | |
| 8 | ||
| 9 | pub 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' | |
| 15 | impl 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' | |
| 23 | impl 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" | |
| 31 | impl<'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>>' | |
| 39 | impl 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>>' | |
| 47 | impl 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. | |
| 55 | pub 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>' | |
| 58 | impl 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 | ||
| 5 | use std::pin::Pin; | |
| 6 | ||
| 7 | pub struct Local; | |
| 8 | ||
| 9 | // Nested fundamental + foreign Self. | |
| 10 | /// from box local | |
| 11 | impl 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 | |
| 21 | impl<'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 | |
| 31 | impl 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 | |
| 41 | impl 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. | |
| 51 | pub trait Marker {} | |
| 52 | ||
| 53 | /// marker for vec local | |
| 54 | impl 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 |
| 1351 | 1351 | |
| 1352 | 1352 | **FIXME**: Some overlap with `tests/ui/did_you_mean/`, that directory should probably be moved under here. |
| 1353 | 1353 | |
| 1354 | ## `tests/ui/supertrait-shadowing/` | |
| 1355 | ||
| 1356 | Tests for supertrait item shadowing (RFC 3624). | |
| 1357 | ||
| 1354 | 1358 | ## `tests/ui/svh/`: Strict Version Hash |
| 1355 | 1359 | |
| 1356 | 1360 | Tests 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 | ||
| 4 | struct A<F: FnOnce()->T,T>(F::Output); | |
| 5 | struct B<F: FnOnce()->T,T>(A<F,T>); | |
| 6 | ||
| 7 | // Removing Option causes it to compile. | |
| 8 | fn foo<T,F: FnOnce()->T>(f: F) -> Option<B<F,T>> { | |
| 9 | Some(B(A(f()))) | |
| 10 | } | |
| 11 | ||
| 12 | fn 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 | ||
| 5 | pub trait Foo { | |
| 6 | type Out; | |
| 7 | } | |
| 8 | ||
| 9 | impl Foo for () { | |
| 10 | type Out = bool; | |
| 11 | } | |
| 12 | ||
| 13 | fn 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 | ||
| 5 | use std::ops::BitXor; | |
| 6 | ||
| 7 | fn 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 @@ |
| 1 | warning: trait objects without an explicit `dyn` are deprecated | |
| 2 | --> $DIR/resolve-method-with-missing-assoc-type.rs:8:17 | |
| 3 | | | |
| 4 | LL | 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 | |
| 10 | help: if this is a dyn-compatible trait, use `dyn` | |
| 11 | | | |
| 12 | LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8); | |
| 13 | | ++++ + | |
| 14 | ||
| 15 | error[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 | | | |
| 18 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | |
| 19 | | ^^^^^^ | |
| 20 | | | |
| 21 | help: specify the associated type | |
| 22 | | | |
| 23 | LL | let x: u8 = BitXor::<Output = /* Type */>::bitor(0 as u8, 0 as u8); | |
| 24 | | +++++++++++++++++++++++ | |
| 25 | ||
| 26 | warning: trait objects without an explicit `dyn` are deprecated | |
| 27 | --> $DIR/resolve-method-with-missing-assoc-type.rs:13:13 | |
| 28 | | | |
| 29 | LL | 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> | |
| 34 | help: if this is a dyn-compatible trait, use `dyn` | |
| 35 | | | |
| 36 | LL | let g = <dyn BitXor>::bitor; | |
| 37 | | ++++ + | |
| 38 | ||
| 39 | error[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 | | | |
| 42 | LL | let g = BitXor::bitor; | |
| 43 | | ^^^^^^ | |
| 44 | | | |
| 45 | help: specify the associated type | |
| 46 | | | |
| 47 | LL | let g = BitXor::<Output = /* Type */>::bitor; | |
| 48 | | +++++++++++++++++++++++ | |
| 49 | ||
| 50 | error: aborting due to 2 previous errors; 2 warnings emitted | |
| 51 | ||
| 52 | For 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)] | |
| 11 | struct Input<'a> { | |
| 12 | foo: &'a u32 | |
| 13 | } | |
| 14 | ||
| 15 | impl <'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 | ||
| 26 | fn 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 | ||
| 31 | fn 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 | ||
| 8 | pub enum Foo { | |
| 9 | X { foo: u32 }, | |
| 10 | Y { foo: u32 } | |
| 11 | } | |
| 12 | ||
| 13 | pub 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 | ||
| 24 | fn 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 | ||
| 5 | struct Foo; | |
| 6 | #[derive(Copy, Clone)] | |
| 7 | struct Bar(Foo); | |
| 8 | //~^ ERROR: the trait `Copy` cannot be implemented for this type | |
| 9 | //~| ERROR: `Foo: Clone` is not satisfied | |
| 10 | ||
| 11 | fn main() {} |
tests/ui/derives/clone-copy/derive-copy-clone-non-copy-field-diagnostic.stderr created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | error[E0204]: the trait `Copy` cannot be implemented for this type | |
| 2 | --> $DIR/derive-copy-clone-non-copy-field-diagnostic.rs:7:8 | |
| 3 | | | |
| 4 | LL | #[derive(Copy, Clone)] | |
| 5 | | ---- in this derive macro expansion | |
| 6 | LL | struct Bar(Foo); | |
| 7 | | ^^^ --- this field does not implement `Copy` | |
| 8 | ||
| 9 | error[E0277]: the trait bound `Foo: Clone` is not satisfied | |
| 10 | --> $DIR/derive-copy-clone-non-copy-field-diagnostic.rs:7:12 | |
| 11 | | | |
| 12 | LL | #[derive(Copy, Clone)] | |
| 13 | | ----- in this derive macro expansion | |
| 14 | LL | struct Bar(Foo); | |
| 15 | | ^^^ the trait `Clone` is not implemented for `Foo` | |
| 16 | | | |
| 17 | note: required by a bound in `std::clone::AssertParamIsClone` | |
| 18 | --> $SRC_DIR/core/src/clone.rs:LL:COL | |
| 19 | help: consider annotating `Foo` with `#[derive(Clone)]` | |
| 20 | | | |
| 21 | LL + #[derive(Clone)] | |
| 22 | LL | struct Foo; | |
| 23 | | | |
| 24 | ||
| 25 | error: aborting due to 2 previous errors | |
| 26 | ||
| 27 | Some errors have detailed explanations: E0204, E0277. | |
| 28 | For 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 | |
| 3 | trait 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)] | |
| 11 | struct Y(#[allow(dead_code)] isize); | |
| 12 | ||
| 13 | #[derive(Debug)] | |
| 14 | struct Z<T: X+std::fmt::Debug> { | |
| 15 | x: T | |
| 16 | } | |
| 17 | ||
| 18 | impl X for Y { | |
| 19 | fn call<T: std::fmt::Debug>(&self, x: &T) { | |
| 20 | println!("X::call {:?} {:?}", self, x); | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | impl<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 | ||
| 32 | pub 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 | ||
| 7 | struct A<'a>(&'a mut i32); | |
| 8 | ||
| 9 | impl<'a> Drop for A<'a> { | |
| 10 | fn drop(&mut self) { | |
| 11 | *self.0 += 1; | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | fn 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)] | |
| 3 | struct Flags; | |
| 4 | ||
| 5 | trait A { | |
| 6 | } | |
| 7 | ||
| 8 | impl<T> Drop for T where T: A { | |
| 9 | //~^ ERROR E0120 | |
| 10 | //~| ERROR E0210 | |
| 11 | fn drop(&mut self) { | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/dropck/drop-impl-for-type-param-with-trait-bound.stderr created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | error[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 | | | |
| 4 | LL | 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 | ||
| 10 | error[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 | | | |
| 13 | LL | impl<T> Drop for T where T: A { | |
| 14 | | ^ must be a struct, enum, or union in the current crate | |
| 15 | ||
| 16 | error: aborting due to 2 previous errors | |
| 17 | ||
| 18 | Some errors have detailed explanations: E0120, E0210. | |
| 19 | For 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 | ||
| 9 | struct Inner<I, V> { | |
| 10 | iterator: I, | |
| 11 | item: V, | |
| 12 | } | |
| 13 | ||
| 14 | struct Outer<I: Iterator> { | |
| 15 | inner: Inner<I, I::Item>, | |
| 16 | } | |
| 17 | ||
| 18 | fn outer<I>(iterator: I) -> Outer<I> | |
| 19 | where I: Iterator, | |
| 20 | I::Item: Default, | |
| 21 | { | |
| 22 | Outer { | |
| 23 | inner: Inner { | |
| 24 | iterator: iterator, | |
| 25 | item: Default::default(), | |
| 26 | } | |
| 27 | } | |
| 28 | } | |
| 29 | ||
| 30 | fn 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 | |
| 3 | struct Parser<'a>(#[allow(dead_code)] Box<dyn FnMut(Parser) + 'a>); | |
| 4 | ||
| 5 | fn 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 | |
| 2 | trait Trait {} | |
| 3 | ||
| 4 | trait X { | |
| 5 | fn foo(&self) where Self: Trait; | |
| 6 | } | |
| 7 | ||
| 8 | impl X for () { | |
| 9 | fn foo(&self) {} | |
| 10 | } | |
| 11 | ||
| 12 | impl Trait for dyn X {} | |
| 13 | //~^ ERROR the trait `X` is not dyn compatible | |
| 14 | ||
| 15 | pub 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 @@ |
| 1 | error[E0038]: the trait `X` is not dyn compatible | |
| 2 | --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:12:16 | |
| 3 | | | |
| 4 | LL | impl Trait for dyn X {} | |
| 5 | | ^^^^^ `X` is not dyn compatible | |
| 6 | | | |
| 7 | note: 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 | | | |
| 11 | LL | trait X { | |
| 12 | | - this trait is not dyn compatible... | |
| 13 | LL | 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 | ||
| 18 | error[E0038]: the trait `X` is not dyn compatible | |
| 19 | --> $DIR/method-with-self-trait-bound-not-dyn-safe.rs:17:10 | |
| 20 | | | |
| 21 | LL | <dyn X as X>::foo(&()); | |
| 22 | | ^ `X` is not dyn compatible | |
| 23 | | | |
| 24 | note: 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 | | | |
| 28 | LL | trait X { | |
| 29 | | - this trait is not dyn compatible... | |
| 30 | LL | 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 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 | ||
| 37 | For 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 | ||
| 5 | struct Test; | |
| 6 | ||
| 7 | impl 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 | ||
| 16 | fn 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)] | |
| 7 | use std::rc::Rc; | |
| 8 | ||
| 9 | fn test1() -> Rc<dyn for<'a> Fn(&'a usize) + 'static> { | |
| 10 | if let Some(_) = Some(1) { | |
| 11 | loop{} | |
| 12 | } else { | |
| 13 | loop{} | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn test2() -> *mut (dyn for<'a> Fn(&'a usize) + 'static) { | |
| 18 | if let Some(_) = Some(1) { | |
| 19 | loop{} | |
| 20 | } else { | |
| 21 | loop{} | |
| 22 | } | |
| 23 | } | |
| 24 | ||
| 25 | fn 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 | ||
| 4 | pub type Session = i32; | |
| 5 | pub struct StreamParser<'a, T> { | |
| 6 | _tokens: T, | |
| 7 | _session: &'a mut Session, | |
| 8 | } | |
| 9 | ||
| 10 | impl<'a, T> StreamParser<'a, T> { | |
| 11 | pub fn thing(&mut self) -> bool { true } | |
| 12 | } | |
| 13 | ||
| 14 | pub 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 | ||
| 18 | pub 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 | ||
| 29 | fn 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 | ||
| 7 | struct A<'a>(&'a mut i32); | |
| 8 | ||
| 9 | impl<'a> Drop for A<'a> { | |
| 10 | fn drop(&mut self) { | |
| 11 | *self.0 += 1; | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | fn 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 | ||
| 5 | fn main() { | |
| 6 | assert!(false, "custom message"); | |
| 7 | } |
tests/ui/issues/issue-27815.rs deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | mod A {} | |
| 2 | ||
| 3 | fn 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 @@ |
| 1 | error[E0574]: expected struct, variant or union type, found module `A` | |
| 2 | --> $DIR/issue-27815.rs:4:13 | |
| 3 | | | |
| 4 | LL | let u = A { x: 1 }; | |
| 5 | | ^ not a struct, variant or union type | |
| 6 | ||
| 7 | error[E0574]: expected struct, variant or union type, found builtin type `u32` | |
| 8 | --> $DIR/issue-27815.rs:5:13 | |
| 9 | | | |
| 10 | LL | let v = u32 { x: 1 }; | |
| 11 | | ^^^ not a struct, variant or union type | |
| 12 | ||
| 13 | error[E0574]: expected struct, variant or union type, found module `A` | |
| 14 | --> $DIR/issue-27815.rs:7:9 | |
| 15 | | | |
| 16 | LL | A { x: 1 } => {} | |
| 17 | | ^ not a struct, variant or union type | |
| 18 | ||
| 19 | error[E0574]: expected struct, variant or union type, found builtin type `u32` | |
| 20 | --> $DIR/issue-27815.rs:9:9 | |
| 21 | | | |
| 22 | LL | u32 { x: 1 } => {} | |
| 23 | | ^^^ not a struct, variant or union type | |
| 24 | ||
| 25 | error: aborting due to 4 previous errors | |
| 26 | ||
| 27 | For more information about this error, try `rustc --explain E0574`. |
tests/ui/issues/issue-27842.rs deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | fn 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 @@ |
| 1 | error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` | |
| 2 | --> $DIR/issue-27842.rs:4:16 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 9 | error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` | |
| 10 | --> $DIR/issue-27842.rs:9:16 | |
| 11 | | | |
| 12 | LL | let _ = tup[i]; | |
| 13 | | ^^^ | |
| 14 | | | |
| 15 | = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. | |
| 16 | ||
| 17 | error[E0608]: cannot index into a value of type `({integer},)` | |
| 18 | --> $DIR/issue-27842.rs:14:16 | |
| 19 | | | |
| 20 | LL | let _ = tup[3]; | |
| 21 | | ^^^ | |
| 22 | | | |
| 23 | = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. | |
| 24 | ||
| 25 | error: aborting due to 3 previous errors | |
| 26 | ||
| 27 | For 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 | ||
| 7 | pub enum Foo { | |
| 8 | X { foo: u32 }, | |
| 9 | Y { foo: u32 } | |
| 10 | } | |
| 11 | ||
| 12 | pub 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 | ||
| 23 | fn main() {} |
tests/ui/issues/issue-27942.rs deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | //@ dont-require-annotations: NOTE | |
| 2 | ||
| 3 | pub trait Resources<'a> {} | |
| 4 | ||
| 5 | pub 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 | ||
| 14 | pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R); | |
| 15 | ||
| 16 | fn main() {} |
tests/ui/issues/issue-27942.stderr deleted-41| ... | ... | @@ -1,41 +0,0 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/issue-27942.rs:7:25 | |
| 3 | | | |
| 4 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 5 | | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | |
| 6 | | | |
| 7 | = note: expected trait `Resources<'_>` | |
| 8 | found trait `Resources<'a>` | |
| 9 | note: the lifetime `'a` as defined here... | |
| 10 | --> $DIR/issue-27942.rs:5:18 | |
| 11 | | | |
| 12 | LL | pub trait Buffer<'a, R: Resources<'a>> { | |
| 13 | | ^^ | |
| 14 | note: ...does not necessarily outlive the anonymous lifetime defined here | |
| 15 | --> $DIR/issue-27942.rs:7:15 | |
| 16 | | | |
| 17 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 18 | | ^^^^^ | |
| 19 | ||
| 20 | error[E0308]: mismatched types | |
| 21 | --> $DIR/issue-27942.rs:7:25 | |
| 22 | | | |
| 23 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 24 | | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | |
| 25 | | | |
| 26 | = note: expected trait `Resources<'_>` | |
| 27 | found trait `Resources<'a>` | |
| 28 | note: the anonymous lifetime defined here... | |
| 29 | --> $DIR/issue-27942.rs:7:15 | |
| 30 | | | |
| 31 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 32 | | ^^^^^ | |
| 33 | note: ...does not necessarily outlive the lifetime `'a` as defined here | |
| 34 | --> $DIR/issue-27942.rs:5:18 | |
| 35 | | | |
| 36 | LL | pub trait Buffer<'a, R: Resources<'a>> { | |
| 37 | | ^^ | |
| 38 | ||
| 39 | error: aborting due to 2 previous errors | |
| 40 | ||
| 41 | For 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)] | |
| 10 | struct Input<'a> { | |
| 11 | foo: &'a u32 | |
| 12 | } | |
| 13 | ||
| 14 | impl <'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 | ||
| 25 | fn 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 | ||
| 30 | fn 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)] | |
| 3 | use std::rc::Rc; | |
| 4 | ||
| 5 | fn test1() -> Rc<dyn for<'a> Fn(&'a usize) + 'static> { | |
| 6 | if let Some(_) = Some(1) { | |
| 7 | loop{} | |
| 8 | } else { | |
| 9 | loop{} | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn test2() -> *mut (dyn for<'a> Fn(&'a usize) + 'static) { | |
| 14 | if let Some(_) = Some(1) { | |
| 15 | loop{} | |
| 16 | } else { | |
| 17 | loop{} | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | fn main() {} |
tests/ui/issues/issue-28344.rs deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | //@ edition:2015 | |
| 2 | use std::ops::BitXor; | |
| 3 | ||
| 4 | fn 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 @@ |
| 1 | warning: trait objects without an explicit `dyn` are deprecated | |
| 2 | --> $DIR/issue-28344.rs:5:17 | |
| 3 | | | |
| 4 | LL | 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 | |
| 10 | help: if this is a dyn-compatible trait, use `dyn` | |
| 11 | | | |
| 12 | LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8); | |
| 13 | | ++++ + | |
| 14 | ||
| 15 | error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified | |
| 16 | --> $DIR/issue-28344.rs:5:17 | |
| 17 | | | |
| 18 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | |
| 19 | | ^^^^^^ | |
| 20 | | | |
| 21 | help: specify the associated type | |
| 22 | | | |
| 23 | LL | let x: u8 = BitXor::<Output = /* Type */>::bitor(0 as u8, 0 as u8); | |
| 24 | | +++++++++++++++++++++++ | |
| 25 | ||
| 26 | warning: trait objects without an explicit `dyn` are deprecated | |
| 27 | --> $DIR/issue-28344.rs:10:13 | |
| 28 | | | |
| 29 | LL | 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> | |
| 34 | help: if this is a dyn-compatible trait, use `dyn` | |
| 35 | | | |
| 36 | LL | let g = <dyn BitXor>::bitor; | |
| 37 | | ++++ + | |
| 38 | ||
| 39 | error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be specified | |
| 40 | --> $DIR/issue-28344.rs:10:13 | |
| 41 | | | |
| 42 | LL | let g = BitXor::bitor; | |
| 43 | | ^^^^^^ | |
| 44 | | | |
| 45 | help: specify the associated type | |
| 46 | | | |
| 47 | LL | let g = BitXor::<Output = /* Type */>::bitor; | |
| 48 | | +++++++++++++++++++++++ | |
| 49 | ||
| 50 | error: aborting due to 2 previous errors; 2 warnings emitted | |
| 51 | ||
| 52 | For 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 | ||
| 3 | extern "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 | ||
| 13 | fn main() { | |
| 14 | } |
tests/ui/issues/issue-28472.stderr deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | error[E0428]: the name `foo` is defined multiple times | |
| 2 | --> $DIR/issue-28472.rs:6:3 | |
| 3 | | | |
| 4 | LL | fn foo(); | |
| 5 | | --------- previous definition of the value `foo` here | |
| 6 | LL | | |
| 7 | LL | / pub | |
| 8 | LL | | fn foo(); | |
| 9 | | |___________^ `foo` redefined here | |
| 10 | | | |
| 11 | = note: `foo` must be defined only once in the value namespace of this module | |
| 12 | ||
| 13 | error[E0428]: the name `foo` is defined multiple times | |
| 14 | --> $DIR/issue-28472.rs:9:3 | |
| 15 | | | |
| 16 | LL | fn foo(); | |
| 17 | | --------- previous definition of the value `foo` here | |
| 18 | ... | |
| 19 | LL | / pub | |
| 20 | LL | | 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 | ||
| 25 | error: aborting due to 2 previous errors | |
| 26 | ||
| 27 | For 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 | ||
| 7 | use std::cell::Cell; | |
| 8 | ||
| 9 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 10 | ||
| 11 | fn 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 | ||
| 7 | use std::cell::Cell; | |
| 8 | ||
| 9 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 10 | ||
| 11 | struct Foo<T> { data: Vec<T> } | |
| 12 | ||
| 13 | fn 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)] | |
| 9 | use std::cell::Cell; | |
| 10 | ||
| 11 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 12 | ||
| 13 | struct Foo<T> { data: Vec<T> } | |
| 14 | ||
| 15 | // Below is the UGEH attribute | |
| 16 | unsafe impl<#[may_dangle] T> Drop for Foo<T> { | |
| 17 | fn drop(&mut self) { } | |
| 18 | } | |
| 19 | ||
| 20 | fn 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 | |
| 2 | struct A<F: FnOnce()->T,T>(F::Output); | |
| 3 | struct B<F: FnOnce()->T,T>(A<F,T>); | |
| 4 | ||
| 5 | // Removing Option causes it to compile. | |
| 6 | fn foo<T,F: FnOnce()->T>(f: F) -> Option<B<F,T>> { | |
| 7 | Some(B(A(f()))) | |
| 8 | } | |
| 9 | ||
| 10 | fn 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 | ||
| 4 | struct Test; | |
| 5 | ||
| 6 | impl 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 | ||
| 15 | fn main() {} |
tests/ui/issues/issue-28776.rs deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | use std::ptr; | |
| 2 | ||
| 3 | fn main() { | |
| 4 | (&ptr::write)(1 as *mut _, 42); | |
| 5 | //~^ ERROR E0133 | |
| 6 | } |
tests/ui/issues/issue-28776.stderr deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block | |
| 2 | --> $DIR/issue-28776.rs:4:5 | |
| 3 | | | |
| 4 | LL | (&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 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0133`. |
tests/ui/issues/issue-28828.rs deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | pub trait Foo { | |
| 3 | type Out; | |
| 4 | } | |
| 5 | ||
| 6 | impl Foo for () { | |
| 7 | type Out = bool; | |
| 8 | } | |
| 9 | ||
| 10 | fn 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 | |
| 2 | pub type Session = i32; | |
| 3 | pub struct StreamParser<'a, T> { | |
| 4 | _tokens: T, | |
| 5 | _session: &'a mut Session, | |
| 6 | } | |
| 7 | ||
| 8 | impl<'a, T> StreamParser<'a, T> { | |
| 9 | pub fn thing(&mut self) -> bool { true } | |
| 10 | } | |
| 11 | ||
| 12 | pub 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 | ||
| 16 | pub 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 | ||
| 27 | fn main() {} |
tests/ui/issues/issue-28999.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | pub struct Xyz<'a, V> { | |
| 3 | pub v: (V, &'a u32), | |
| 4 | } | |
| 5 | ||
| 6 | pub 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 | ||
| 11 | fn main() {} |
tests/ui/issues/issue-41974.rs deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | #[derive(Copy, Clone)] | |
| 2 | struct Flags; | |
| 3 | ||
| 4 | trait A { | |
| 5 | } | |
| 6 | ||
| 7 | impl<T> Drop for T where T: A { | |
| 8 | //~^ ERROR E0120 | |
| 9 | //~| ERROR E0210 | |
| 10 | fn drop(&mut self) { | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | fn main() {} |
tests/ui/issues/issue-41974.stderr deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | error[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 | | | |
| 4 | LL | 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 | ||
| 10 | error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions | |
| 11 | --> $DIR/issue-41974.rs:7:18 | |
| 12 | | | |
| 13 | LL | impl<T> Drop for T where T: A { | |
| 14 | | ^ must be a struct, enum, or union in the current crate | |
| 15 | ||
| 16 | error: aborting due to 2 previous errors | |
| 17 | ||
| 18 | Some errors have detailed explanations: E0120, E0210. | |
| 19 | For more information about an error, try `rustc --explain E0120`. |
tests/ui/issues/issue-4252.rs deleted-33| ... | ... | @@ -1,33 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | trait 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)] | |
| 10 | struct Y(#[allow(dead_code)] isize); | |
| 11 | ||
| 12 | #[derive(Debug)] | |
| 13 | struct Z<T: X+std::fmt::Debug> { | |
| 14 | x: T | |
| 15 | } | |
| 16 | ||
| 17 | impl X for Y { | |
| 18 | fn call<T: std::fmt::Debug>(&self, x: &T) { | |
| 19 | println!("X::call {:?} {:?}", self, x); | |
| 20 | } | |
| 21 | } | |
| 22 | ||
| 23 | impl<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 | ||
| 31 | pub 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 | ||
| 8 | struct Inner<I, V> { | |
| 9 | iterator: I, | |
| 10 | item: V, | |
| 11 | } | |
| 12 | ||
| 13 | struct Outer<I: Iterator> { | |
| 14 | inner: Inner<I, I::Item>, | |
| 15 | } | |
| 16 | ||
| 17 | fn outer<I>(iterator: I) -> Outer<I> | |
| 18 | where I: Iterator, | |
| 19 | I::Item: Default, | |
| 20 | { | |
| 21 | Outer { | |
| 22 | inner: Inner { | |
| 23 | iterator: iterator, | |
| 24 | item: Default::default(), | |
| 25 | } | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn main() { | |
| 30 | outer(std::iter::once(&1).cloned()); | |
| 31 | } |
tests/ui/issues/issue-50781.rs deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | trait Trait {} | |
| 2 | ||
| 3 | trait X { | |
| 4 | fn foo(&self) where Self: Trait; | |
| 5 | } | |
| 6 | ||
| 7 | impl X for () { | |
| 8 | fn foo(&self) {} | |
| 9 | } | |
| 10 | ||
| 11 | impl Trait for dyn X {} | |
| 12 | //~^ ERROR the trait `X` is not dyn compatible | |
| 13 | ||
| 14 | pub 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 @@ |
| 1 | error[E0038]: the trait `X` is not dyn compatible | |
| 2 | --> $DIR/issue-50781.rs:11:16 | |
| 3 | | | |
| 4 | LL | impl Trait for dyn X {} | |
| 5 | | ^^^^^ `X` is not dyn compatible | |
| 6 | | | |
| 7 | note: 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 | | | |
| 11 | LL | trait X { | |
| 12 | | - this trait is not dyn compatible... | |
| 13 | LL | 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 | ||
| 18 | error[E0038]: the trait `X` is not dyn compatible | |
| 19 | --> $DIR/issue-50781.rs:16:10 | |
| 20 | | | |
| 21 | LL | <dyn X as X>::foo(&()); | |
| 22 | | ^ `X` is not dyn compatible | |
| 23 | | | |
| 24 | note: 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 | | | |
| 28 | LL | trait X { | |
| 29 | | - this trait is not dyn compatible... | |
| 30 | LL | 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 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 | ||
| 37 | For 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 | ||
| 5 | pub struct Xyz<'a, V> { | |
| 6 | pub v: (V, &'a u32), | |
| 7 | } | |
| 8 | ||
| 9 | pub 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 | ||
| 14 | fn 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 | ||
| 5 | pub trait Resources<'a> {} | |
| 6 | ||
| 7 | pub 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 | ||
| 16 | pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R); | |
| 17 | ||
| 18 | fn main() {} |
tests/ui/lifetimes/lifetime-errors/trait-method-return-lifetime-mismatch.stderr created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/trait-method-return-lifetime-mismatch.rs:9:25 | |
| 3 | | | |
| 4 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 5 | | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | |
| 6 | | | |
| 7 | = note: expected trait `Resources<'_>` | |
| 8 | found trait `Resources<'a>` | |
| 9 | note: the lifetime `'a` as defined here... | |
| 10 | --> $DIR/trait-method-return-lifetime-mismatch.rs:7:18 | |
| 11 | | | |
| 12 | LL | pub trait Buffer<'a, R: Resources<'a>> { | |
| 13 | | ^^ | |
| 14 | note: ...does not necessarily outlive the anonymous lifetime defined here | |
| 15 | --> $DIR/trait-method-return-lifetime-mismatch.rs:9:15 | |
| 16 | | | |
| 17 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 18 | | ^^^^^ | |
| 19 | ||
| 20 | error[E0308]: mismatched types | |
| 21 | --> $DIR/trait-method-return-lifetime-mismatch.rs:9:25 | |
| 22 | | | |
| 23 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 24 | | ^^^^^^^^^^^^^^^^^^^ lifetime mismatch | |
| 25 | | | |
| 26 | = note: expected trait `Resources<'_>` | |
| 27 | found trait `Resources<'a>` | |
| 28 | note: the anonymous lifetime defined here... | |
| 29 | --> $DIR/trait-method-return-lifetime-mismatch.rs:9:15 | |
| 30 | | | |
| 31 | LL | fn select(&self) -> BufferViewHandle<R>; | |
| 32 | | ^^^^^ | |
| 33 | note: ...does not necessarily outlive the lifetime `'a` as defined here | |
| 34 | --> $DIR/trait-method-return-lifetime-mismatch.rs:7:18 | |
| 35 | | | |
| 36 | LL | pub trait Buffer<'a, R: Resources<'a>> { | |
| 37 | | ^^ | |
| 38 | ||
| 39 | error: aborting due to 2 previous errors | |
| 40 | ||
| 41 | For more information about this error, try `rustc --explain E0308`. |
tests/ui/lint/auxiliary/lint_stability.rs+6| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | #![crate_name="lint_stability"] |
| 2 | 2 | #![crate_type = "lib"] |
| 3 | #![feature(extern_types)] | |
| 3 | 4 | #![feature(staged_api)] |
| 4 | 5 | #![feature(associated_type_defaults)] |
| 5 | 6 | #![stable(feature = "lint_stability", since = "1.0.0")] |
| ... | ... | @@ -186,3 +187,8 @@ macro_rules! macro_test_arg { |
| 186 | 187 | macro_rules! macro_test_arg_nested { |
| 187 | 188 | ($func:ident) => (macro_test_arg!($func())); |
| 188 | 189 | } |
| 190 | ||
| 191 | extern "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 @@ |
| 6 | 6 | #![allow(deprecated)] |
| 7 | 7 | #![allow(dead_code)] |
| 8 | 8 | #![feature(staged_api)] |
| 9 | ||
| 9 | #![feature(extern_types)] | |
| 10 | 10 | #![stable(feature = "rust1", since = "1.0.0")] |
| 11 | 11 | |
| 12 | 12 | #[macro_use] |
| ... | ... | @@ -18,6 +18,9 @@ mod cross_crate { |
| 18 | 18 | |
| 19 | 19 | use lint_stability::*; |
| 20 | 20 | |
| 21 | fn test_foreign_type(_: &mut UnstableForeignType) { //~ ERROR use of unstable library feature | |
| 22 | } | |
| 23 | ||
| 21 | 24 | fn test() { |
| 22 | 25 | type Foo = MethodTester; |
| 23 | 26 | let foo = MethodTester; |
tests/ui/lint/lint-stability.stderr+52-43| ... | ... | @@ -8,7 +8,16 @@ LL | extern crate stability_cfg2; |
| 8 | 8 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 9 | 9 | |
| 10 | 10 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 11 | --> $DIR/lint-stability.rs:45:9 | |
| 11 | --> $DIR/lint-stability.rs:21:34 | |
| 12 | | | |
| 13 | LL | 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 | ||
| 19 | error[E0658]: use of unstable library feature `unstable_test_feature` | |
| 20 | --> $DIR/lint-stability.rs:48:9 | |
| 12 | 21 | | |
| 13 | 22 | LL | deprecated_unstable(); |
| 14 | 23 | | ^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -17,7 +26,7 @@ LL | deprecated_unstable(); |
| 17 | 26 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 18 | 27 | |
| 19 | 28 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 20 | --> $DIR/lint-stability.rs:47:9 | |
| 29 | --> $DIR/lint-stability.rs:50:9 | |
| 21 | 30 | | |
| 22 | 31 | LL | Trait::trait_deprecated_unstable(&foo); |
| 23 | 32 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -26,7 +35,7 @@ LL | Trait::trait_deprecated_unstable(&foo); |
| 26 | 35 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 27 | 36 | |
| 28 | 37 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 29 | --> $DIR/lint-stability.rs:49:9 | |
| 38 | --> $DIR/lint-stability.rs:52:9 | |
| 30 | 39 | | |
| 31 | 40 | LL | <Foo as Trait>::trait_deprecated_unstable(&foo); |
| 32 | 41 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -35,7 +44,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable(&foo); |
| 35 | 44 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 36 | 45 | |
| 37 | 46 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 38 | --> $DIR/lint-stability.rs:52:9 | |
| 47 | --> $DIR/lint-stability.rs:55:9 | |
| 39 | 48 | | |
| 40 | 49 | LL | deprecated_unstable_text(); |
| 41 | 50 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -44,7 +53,7 @@ LL | deprecated_unstable_text(); |
| 44 | 53 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 45 | 54 | |
| 46 | 55 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 47 | --> $DIR/lint-stability.rs:54:9 | |
| 56 | --> $DIR/lint-stability.rs:57:9 | |
| 48 | 57 | | |
| 49 | 58 | LL | Trait::trait_deprecated_unstable_text(&foo); |
| 50 | 59 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -53,7 +62,7 @@ LL | Trait::trait_deprecated_unstable_text(&foo); |
| 53 | 62 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 54 | 63 | |
| 55 | 64 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 56 | --> $DIR/lint-stability.rs:56:9 | |
| 65 | --> $DIR/lint-stability.rs:59:9 | |
| 57 | 66 | | |
| 58 | 67 | LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo); |
| 59 | 68 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -62,7 +71,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo); |
| 62 | 71 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 63 | 72 | |
| 64 | 73 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 65 | --> $DIR/lint-stability.rs:59:9 | |
| 74 | --> $DIR/lint-stability.rs:62:9 | |
| 66 | 75 | | |
| 67 | 76 | LL | unstable(); |
| 68 | 77 | | ^^^^^^^^ |
| ... | ... | @@ -71,7 +80,7 @@ LL | unstable(); |
| 71 | 80 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 72 | 81 | |
| 73 | 82 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 74 | --> $DIR/lint-stability.rs:60:9 | |
| 83 | --> $DIR/lint-stability.rs:63:9 | |
| 75 | 84 | | |
| 76 | 85 | LL | Trait::trait_unstable(&foo); |
| 77 | 86 | | ^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -80,7 +89,7 @@ LL | Trait::trait_unstable(&foo); |
| 80 | 89 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 81 | 90 | |
| 82 | 91 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 83 | --> $DIR/lint-stability.rs:61:9 | |
| 92 | --> $DIR/lint-stability.rs:64:9 | |
| 84 | 93 | | |
| 85 | 94 | LL | <Foo as Trait>::trait_unstable(&foo); |
| 86 | 95 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -89,7 +98,7 @@ LL | <Foo as Trait>::trait_unstable(&foo); |
| 89 | 98 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 90 | 99 | |
| 91 | 100 | error[E0658]: use of unstable library feature `unstable_test_feature`: text |
| 92 | --> $DIR/lint-stability.rs:63:9 | |
| 101 | --> $DIR/lint-stability.rs:66:9 | |
| 93 | 102 | | |
| 94 | 103 | LL | unstable_text(); |
| 95 | 104 | | ^^^^^^^^^^^^^ |
| ... | ... | @@ -98,7 +107,7 @@ LL | unstable_text(); |
| 98 | 107 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 99 | 108 | |
| 100 | 109 | error[E0658]: use of unstable library feature `unstable_test_feature`: text |
| 101 | --> $DIR/lint-stability.rs:65:9 | |
| 110 | --> $DIR/lint-stability.rs:68:9 | |
| 102 | 111 | | |
| 103 | 112 | LL | Trait::trait_unstable_text(&foo); |
| 104 | 113 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -107,7 +116,7 @@ LL | Trait::trait_unstable_text(&foo); |
| 107 | 116 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 108 | 117 | |
| 109 | 118 | error[E0658]: use of unstable library feature `unstable_test_feature`: text |
| 110 | --> $DIR/lint-stability.rs:67:9 | |
| 119 | --> $DIR/lint-stability.rs:70:9 | |
| 111 | 120 | | |
| 112 | 121 | LL | <Foo as Trait>::trait_unstable_text(&foo); |
| 113 | 122 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -116,7 +125,7 @@ LL | <Foo as Trait>::trait_unstable_text(&foo); |
| 116 | 125 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 117 | 126 | |
| 118 | 127 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 119 | --> $DIR/lint-stability.rs:99:17 | |
| 128 | --> $DIR/lint-stability.rs:102:17 | |
| 120 | 129 | | |
| 121 | 130 | LL | let _ = DeprecatedUnstableStruct { |
| 122 | 131 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -125,7 +134,7 @@ LL | let _ = DeprecatedUnstableStruct { |
| 125 | 134 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 126 | 135 | |
| 127 | 136 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 128 | --> $DIR/lint-stability.rs:103:17 | |
| 137 | --> $DIR/lint-stability.rs:106:17 | |
| 129 | 138 | | |
| 130 | 139 | LL | let _ = UnstableStruct { i: 0 }; |
| 131 | 140 | | ^^^^^^^^^^^^^^ |
| ... | ... | @@ -134,7 +143,7 @@ LL | let _ = UnstableStruct { i: 0 }; |
| 134 | 143 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 135 | 144 | |
| 136 | 145 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 137 | --> $DIR/lint-stability.rs:107:17 | |
| 146 | --> $DIR/lint-stability.rs:110:17 | |
| 138 | 147 | | |
| 139 | 148 | LL | let _ = DeprecatedUnstableUnitStruct; |
| 140 | 149 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -143,7 +152,7 @@ LL | let _ = DeprecatedUnstableUnitStruct; |
| 143 | 152 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 144 | 153 | |
| 145 | 154 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 146 | --> $DIR/lint-stability.rs:109:17 | |
| 155 | --> $DIR/lint-stability.rs:112:17 | |
| 147 | 156 | | |
| 148 | 157 | LL | let _ = UnstableUnitStruct; |
| 149 | 158 | | ^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -152,7 +161,7 @@ LL | let _ = UnstableUnitStruct; |
| 152 | 161 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 153 | 162 | |
| 154 | 163 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 155 | --> $DIR/lint-stability.rs:113:17 | |
| 164 | --> $DIR/lint-stability.rs:116:17 | |
| 156 | 165 | | |
| 157 | 166 | LL | let _ = Enum::DeprecatedUnstableVariant; |
| 158 | 167 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -161,7 +170,7 @@ LL | let _ = Enum::DeprecatedUnstableVariant; |
| 161 | 170 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 162 | 171 | |
| 163 | 172 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 164 | --> $DIR/lint-stability.rs:115:17 | |
| 173 | --> $DIR/lint-stability.rs:118:17 | |
| 165 | 174 | | |
| 166 | 175 | LL | let _ = Enum::UnstableVariant; |
| 167 | 176 | | ^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -170,7 +179,7 @@ LL | let _ = Enum::UnstableVariant; |
| 170 | 179 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 171 | 180 | |
| 172 | 181 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 173 | --> $DIR/lint-stability.rs:119:17 | |
| 182 | --> $DIR/lint-stability.rs:122:17 | |
| 174 | 183 | | |
| 175 | 184 | LL | let _ = DeprecatedUnstableTupleStruct (1); |
| 176 | 185 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -179,7 +188,7 @@ LL | let _ = DeprecatedUnstableTupleStruct (1); |
| 179 | 188 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 180 | 189 | |
| 181 | 190 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 182 | --> $DIR/lint-stability.rs:121:17 | |
| 191 | --> $DIR/lint-stability.rs:124:17 | |
| 183 | 192 | | |
| 184 | 193 | LL | let _ = UnstableTupleStruct (1); |
| 185 | 194 | | ^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -188,7 +197,7 @@ LL | let _ = UnstableTupleStruct (1); |
| 188 | 197 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 189 | 198 | |
| 190 | 199 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 191 | --> $DIR/lint-stability.rs:130:25 | |
| 200 | --> $DIR/lint-stability.rs:133:25 | |
| 192 | 201 | | |
| 193 | 202 | LL | macro_test_arg!(deprecated_unstable_text()); |
| 194 | 203 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -197,7 +206,7 @@ LL | macro_test_arg!(deprecated_unstable_text()); |
| 197 | 206 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 198 | 207 | |
| 199 | 208 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 200 | --> $DIR/lint-stability.rs:144:9 | |
| 209 | --> $DIR/lint-stability.rs:147:9 | |
| 201 | 210 | | |
| 202 | 211 | LL | Trait::trait_deprecated_unstable(&foo); |
| 203 | 212 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -206,7 +215,7 @@ LL | Trait::trait_deprecated_unstable(&foo); |
| 206 | 215 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 207 | 216 | |
| 208 | 217 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 209 | --> $DIR/lint-stability.rs:146:9 | |
| 218 | --> $DIR/lint-stability.rs:149:9 | |
| 210 | 219 | | |
| 211 | 220 | LL | <Foo as Trait>::trait_deprecated_unstable(&foo); |
| 212 | 221 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -215,7 +224,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable(&foo); |
| 215 | 224 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 216 | 225 | |
| 217 | 226 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 218 | --> $DIR/lint-stability.rs:148:9 | |
| 227 | --> $DIR/lint-stability.rs:151:9 | |
| 219 | 228 | | |
| 220 | 229 | LL | Trait::trait_deprecated_unstable_text(&foo); |
| 221 | 230 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -224,7 +233,7 @@ LL | Trait::trait_deprecated_unstable_text(&foo); |
| 224 | 233 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 225 | 234 | |
| 226 | 235 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 227 | --> $DIR/lint-stability.rs:150:9 | |
| 236 | --> $DIR/lint-stability.rs:153:9 | |
| 228 | 237 | | |
| 229 | 238 | LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo); |
| 230 | 239 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -233,7 +242,7 @@ LL | <Foo as Trait>::trait_deprecated_unstable_text(&foo); |
| 233 | 242 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 234 | 243 | |
| 235 | 244 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 236 | --> $DIR/lint-stability.rs:152:9 | |
| 245 | --> $DIR/lint-stability.rs:155:9 | |
| 237 | 246 | | |
| 238 | 247 | LL | Trait::trait_unstable(&foo); |
| 239 | 248 | | ^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -242,7 +251,7 @@ LL | Trait::trait_unstable(&foo); |
| 242 | 251 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 243 | 252 | |
| 244 | 253 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 245 | --> $DIR/lint-stability.rs:153:9 | |
| 254 | --> $DIR/lint-stability.rs:156:9 | |
| 246 | 255 | | |
| 247 | 256 | LL | <Foo as Trait>::trait_unstable(&foo); |
| 248 | 257 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -251,7 +260,7 @@ LL | <Foo as Trait>::trait_unstable(&foo); |
| 251 | 260 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 252 | 261 | |
| 253 | 262 | error[E0658]: use of unstable library feature `unstable_test_feature`: text |
| 254 | --> $DIR/lint-stability.rs:154:9 | |
| 263 | --> $DIR/lint-stability.rs:157:9 | |
| 255 | 264 | | |
| 256 | 265 | LL | Trait::trait_unstable_text(&foo); |
| 257 | 266 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -260,7 +269,7 @@ LL | Trait::trait_unstable_text(&foo); |
| 260 | 269 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 261 | 270 | |
| 262 | 271 | error[E0658]: use of unstable library feature `unstable_test_feature`: text |
| 263 | --> $DIR/lint-stability.rs:156:9 | |
| 272 | --> $DIR/lint-stability.rs:159:9 | |
| 264 | 273 | | |
| 265 | 274 | LL | <Foo as Trait>::trait_unstable_text(&foo); |
| 266 | 275 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -269,7 +278,7 @@ LL | <Foo as Trait>::trait_unstable_text(&foo); |
| 269 | 278 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 270 | 279 | |
| 271 | 280 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 272 | --> $DIR/lint-stability.rs:172:10 | |
| 281 | --> $DIR/lint-stability.rs:175:10 | |
| 273 | 282 | | |
| 274 | 283 | LL | impl UnstableTrait for S { } |
| 275 | 284 | | ^^^^^^^^^^^^^ |
| ... | ... | @@ -278,7 +287,7 @@ LL | impl UnstableTrait for S { } |
| 278 | 287 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 279 | 288 | |
| 280 | 289 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 281 | --> $DIR/lint-stability.rs:174:24 | |
| 290 | --> $DIR/lint-stability.rs:177:24 | |
| 282 | 291 | | |
| 283 | 292 | LL | trait LocalTrait : UnstableTrait { } |
| 284 | 293 | | ^^^^^^^^^^^^^ |
| ... | ... | @@ -287,7 +296,7 @@ LL | trait LocalTrait : UnstableTrait { } |
| 287 | 296 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 288 | 297 | |
| 289 | 298 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 290 | --> $DIR/lint-stability.rs:179:9 | |
| 299 | --> $DIR/lint-stability.rs:182:9 | |
| 291 | 300 | | |
| 292 | 301 | LL | fn trait_unstable(&self) {} |
| 293 | 302 | | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -296,7 +305,7 @@ LL | fn trait_unstable(&self) {} |
| 296 | 305 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 297 | 306 | |
| 298 | 307 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 299 | --> $DIR/lint-stability.rs:184:5 | |
| 308 | --> $DIR/lint-stability.rs:187:5 | |
| 300 | 309 | | |
| 301 | 310 | LL | extern crate inherited_stability; |
| 302 | 311 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -305,7 +314,7 @@ LL | extern crate inherited_stability; |
| 305 | 314 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 306 | 315 | |
| 307 | 316 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 308 | --> $DIR/lint-stability.rs:185:9 | |
| 317 | --> $DIR/lint-stability.rs:188:9 | |
| 309 | 318 | | |
| 310 | 319 | LL | use self::inherited_stability::*; |
| 311 | 320 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -314,7 +323,7 @@ LL | use self::inherited_stability::*; |
| 314 | 323 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 315 | 324 | |
| 316 | 325 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 317 | --> $DIR/lint-stability.rs:188:9 | |
| 326 | --> $DIR/lint-stability.rs:191:9 | |
| 318 | 327 | | |
| 319 | 328 | LL | unstable(); |
| 320 | 329 | | ^^^^^^^^ |
| ... | ... | @@ -323,7 +332,7 @@ LL | unstable(); |
| 323 | 332 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 324 | 333 | |
| 325 | 334 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 326 | --> $DIR/lint-stability.rs:191:9 | |
| 335 | --> $DIR/lint-stability.rs:194:9 | |
| 327 | 336 | | |
| 328 | 337 | LL | stable_mod::unstable(); |
| 329 | 338 | | ^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -332,7 +341,7 @@ LL | stable_mod::unstable(); |
| 332 | 341 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 333 | 342 | |
| 334 | 343 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 335 | --> $DIR/lint-stability.rs:194:9 | |
| 344 | --> $DIR/lint-stability.rs:197:9 | |
| 336 | 345 | | |
| 337 | 346 | LL | unstable_mod::deprecated(); |
| 338 | 347 | | ^^^^^^^^^^^^ |
| ... | ... | @@ -341,7 +350,7 @@ LL | unstable_mod::deprecated(); |
| 341 | 350 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 342 | 351 | |
| 343 | 352 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 344 | --> $DIR/lint-stability.rs:195:9 | |
| 353 | --> $DIR/lint-stability.rs:198:9 | |
| 345 | 354 | | |
| 346 | 355 | LL | unstable_mod::unstable(); |
| 347 | 356 | | ^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -350,7 +359,7 @@ LL | unstable_mod::unstable(); |
| 350 | 359 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 351 | 360 | |
| 352 | 361 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 353 | --> $DIR/lint-stability.rs:197:17 | |
| 362 | --> $DIR/lint-stability.rs:200:17 | |
| 354 | 363 | | |
| 355 | 364 | LL | let _ = Unstable::UnstableVariant; |
| 356 | 365 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -359,7 +368,7 @@ LL | let _ = Unstable::UnstableVariant; |
| 359 | 368 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 360 | 369 | |
| 361 | 370 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 362 | --> $DIR/lint-stability.rs:198:17 | |
| 371 | --> $DIR/lint-stability.rs:201:17 | |
| 363 | 372 | | |
| 364 | 373 | LL | let _ = Unstable::StableVariant; |
| 365 | 374 | | ^^^^^^^^ |
| ... | ... | @@ -368,7 +377,7 @@ LL | let _ = Unstable::StableVariant; |
| 368 | 377 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 369 | 378 | |
| 370 | 379 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 371 | --> $DIR/lint-stability.rs:88:48 | |
| 380 | --> $DIR/lint-stability.rs:91:48 | |
| 372 | 381 | | |
| 373 | 382 | LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); |
| 374 | 383 | | ^^^^^^^^^^^^^^^ |
| ... | ... | @@ -377,7 +386,7 @@ LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); |
| 377 | 386 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 378 | 387 | |
| 379 | 388 | error[E0658]: use of unstable library feature `unstable_test_feature` |
| 380 | --> $DIR/lint-stability.rs:92:13 | |
| 389 | --> $DIR/lint-stability.rs:95:13 | |
| 381 | 390 | | |
| 382 | 391 | LL | TypeUnstable = u8, |
| 383 | 392 | | ^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -385,6 +394,6 @@ LL | TypeUnstable = u8, |
| 385 | 394 | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable |
| 386 | 395 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 387 | 396 | |
| 388 | error: aborting due to 43 previous errors | |
| 397 | error: aborting due to 44 previous errors | |
| 389 | 398 | |
| 390 | 399 | For 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 | ||
| 6 | fn 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 | ||
| 6 | trait A { | |
| 7 | const CONST: i32; | |
| 8 | } | |
| 9 | impl<T> A for T { | |
| 10 | const CONST: i32 = 1; | |
| 11 | } | |
| 12 | ||
| 13 | trait B: A { | |
| 14 | const CONST: i32; | |
| 15 | } | |
| 16 | impl<T> B for T { | |
| 17 | const CONST: i32 = 2; | |
| 18 | } | |
| 19 | ||
| 20 | fn 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")] | |
| 5 | pub 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")] | |
| 12 | impl<T> A for T {} | |
| 13 | ||
| 14 | #[stable(feature = "main", since = "1.0.0")] | |
| 15 | pub 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")] | |
| 22 | impl<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 | ||
| 8 | trait A { | |
| 9 | fn hello(&self) -> &'static str { | |
| 10 | "A" | |
| 11 | } | |
| 12 | } | |
| 13 | impl<T> A for T {} | |
| 14 | ||
| 15 | trait B { | |
| 16 | fn hello(&self) -> &'static str { | |
| 17 | "B" | |
| 18 | } | |
| 19 | } | |
| 20 | impl<T> B for T {} | |
| 21 | ||
| 22 | trait C: A + B { | |
| 23 | fn hello(&self) -> &'static str { | |
| 24 | //~^ WARN trait item `hello` from `C` shadows identically named item | |
| 25 | "C" | |
| 26 | } | |
| 27 | } | |
| 28 | impl<T> C for T {} | |
| 29 | ||
| 30 | fn 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 @@ |
| 1 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor-2.rs:23:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: items from several supertraits are shadowed: `B` and `A` | |
| 8 | --> $DIR/common-ancestor-2.rs:9:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ... | |
| 13 | LL | fn hello(&self) -> &'static str { | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | note: the lint level is defined here | |
| 16 | --> $DIR/common-ancestor-2.rs:5:9 | |
| 17 | | | |
| 18 | LL | #![warn(shadowing_supertrait_items)] | |
| 19 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 20 | ||
| 21 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 22 | --> $DIR/common-ancestor-2.rs:31:19 | |
| 23 | | | |
| 24 | LL | assert_eq!(().hello(), "C"); | |
| 25 | | ^^^^^ | |
| 26 | | | |
| 27 | note: item from `C` shadows a supertrait item | |
| 28 | --> $DIR/common-ancestor-2.rs:23:5 | |
| 29 | | | |
| 30 | LL | fn hello(&self) -> &'static str { | |
| 31 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 32 | note: items from several supertraits are shadowed: `A` and `B` | |
| 33 | --> $DIR/common-ancestor-2.rs:9:5 | |
| 34 | | | |
| 35 | LL | fn hello(&self) -> &'static str { | |
| 36 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 37 | ... | |
| 38 | LL | fn hello(&self) -> &'static str { | |
| 39 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 40 | note: the lint level is defined here | |
| 41 | --> $DIR/common-ancestor-2.rs:4:9 | |
| 42 | | | |
| 43 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 44 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 45 | ||
| 46 | warning: 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 | ||
| 8 | trait A { | |
| 9 | fn hello(&self) -> &'static str { | |
| 10 | "A" | |
| 11 | } | |
| 12 | } | |
| 13 | impl<T> A for T {} | |
| 14 | ||
| 15 | trait B { | |
| 16 | fn hello(&self) -> &'static str { | |
| 17 | "B" | |
| 18 | } | |
| 19 | } | |
| 20 | impl<T> B for T {} | |
| 21 | ||
| 22 | trait C: A + B { | |
| 23 | fn hello(&self) -> &'static str { | |
| 24 | //~^ WARN trait item `hello` from `C` shadows identically named item | |
| 25 | "C" | |
| 26 | } | |
| 27 | } | |
| 28 | impl<T> C for T {} | |
| 29 | ||
| 30 | // `D` extends `C` which extends `B` and `A` | |
| 31 | ||
| 32 | trait D: C { | |
| 33 | fn hello(&self) -> &'static str { | |
| 34 | //~^ WARN trait item `hello` from `D` shadows identically named item | |
| 35 | "D" | |
| 36 | } | |
| 37 | } | |
| 38 | impl<T> D for T {} | |
| 39 | ||
| 40 | fn 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 @@ |
| 1 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor-3.rs:23:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: items from several supertraits are shadowed: `B` and `A` | |
| 8 | --> $DIR/common-ancestor-3.rs:9:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ... | |
| 13 | LL | fn hello(&self) -> &'static str { | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | note: the lint level is defined here | |
| 16 | --> $DIR/common-ancestor-3.rs:5:9 | |
| 17 | | | |
| 18 | LL | #![warn(shadowing_supertrait_items)] | |
| 19 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 20 | ||
| 21 | warning: trait item `hello` from `D` shadows identically named item from supertrait | |
| 22 | --> $DIR/common-ancestor-3.rs:33:5 | |
| 23 | | | |
| 24 | LL | fn hello(&self) -> &'static str { | |
| 25 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 26 | | | |
| 27 | note: items from several supertraits are shadowed: `C`, `B`, and `A` | |
| 28 | --> $DIR/common-ancestor-3.rs:9:5 | |
| 29 | | | |
| 30 | LL | fn hello(&self) -> &'static str { | |
| 31 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 32 | ... | |
| 33 | LL | fn hello(&self) -> &'static str { | |
| 34 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 35 | ... | |
| 36 | LL | fn hello(&self) -> &'static str { | |
| 37 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 38 | ||
| 39 | warning: trait item `hello` from `D` shadows identically named item from supertrait | |
| 40 | --> $DIR/common-ancestor-3.rs:41:19 | |
| 41 | | | |
| 42 | LL | assert_eq!(().hello(), "D"); | |
| 43 | | ^^^^^ | |
| 44 | | | |
| 45 | note: item from `D` shadows a supertrait item | |
| 46 | --> $DIR/common-ancestor-3.rs:33:5 | |
| 47 | | | |
| 48 | LL | fn hello(&self) -> &'static str { | |
| 49 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 50 | note: items from several supertraits are shadowed: `A`, `B`, and `C` | |
| 51 | --> $DIR/common-ancestor-3.rs:9:5 | |
| 52 | | | |
| 53 | LL | fn hello(&self) -> &'static str { | |
| 54 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 55 | ... | |
| 56 | LL | fn hello(&self) -> &'static str { | |
| 57 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 58 | ... | |
| 59 | LL | fn hello(&self) -> &'static str { | |
| 60 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 61 | note: the lint level is defined here | |
| 62 | --> $DIR/common-ancestor-3.rs:4:9 | |
| 63 | | | |
| 64 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 65 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 66 | ||
| 67 | warning: 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 | ||
| 8 | trait A { | |
| 9 | fn hello(&self) -> &'static str { | |
| 10 | "A" | |
| 11 | } | |
| 12 | } | |
| 13 | impl<T> A for T {} | |
| 14 | ||
| 15 | trait B: A { | |
| 16 | fn hello(&self) -> &'static str { | |
| 17 | //~^ WARN trait item `hello` from `B` shadows identically named item | |
| 18 | "B" | |
| 19 | } | |
| 20 | } | |
| 21 | impl<T> B for T {} | |
| 22 | ||
| 23 | fn 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 @@ |
| 1 | warning: trait item `hello` from `B` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor.rs:16:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `A` is shadowed by a subtrait item | |
| 8 | --> $DIR/common-ancestor.rs:9:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/common-ancestor.rs:5:9 | |
| 14 | | | |
| 15 | LL | #![warn(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | warning: trait item `hello` from `B` shadows identically named item from supertrait | |
| 19 | --> $DIR/common-ancestor.rs:24:19 | |
| 20 | | | |
| 21 | LL | assert_eq!(().hello(), "B"); | |
| 22 | | ^^^^^ | |
| 23 | | | |
| 24 | note: item from `B` shadows a supertrait item | |
| 25 | --> $DIR/common-ancestor.rs:16:5 | |
| 26 | | | |
| 27 | LL | fn hello(&self) -> &'static str { | |
| 28 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 29 | note: item from `A` is shadowed by a subtrait item | |
| 30 | --> $DIR/common-ancestor.rs:9:5 | |
| 31 | | | |
| 32 | LL | fn hello(&self) -> &'static str { | |
| 33 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 34 | note: the lint level is defined here | |
| 35 | --> $DIR/common-ancestor.rs:4:9 | |
| 36 | | | |
| 37 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 38 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 39 | ||
| 40 | warning: 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 | ||
| 4 | trait SuperSuper { | |
| 5 | fn method(); | |
| 6 | } | |
| 7 | ||
| 8 | trait Super: SuperSuper { | |
| 9 | fn method(); | |
| 10 | //~^ ERROR trait item `method` from `Super` shadows identically named item | |
| 11 | } | |
| 12 | ||
| 13 | trait Sub: Super { | |
| 14 | fn method(); | |
| 15 | //~^ ERROR trait item `method` from `Sub` shadows identically named item | |
| 16 | } | |
| 17 | ||
| 18 | fn main() {} |
tests/ui/methods/supertrait-shadowing/definition-site.stderr deleted-34| ... | ... | @@ -1,34 +0,0 @@ |
| 1 | error: trait item `method` from `Super` shadows identically named item from supertrait | |
| 2 | --> $DIR/definition-site.rs:9:5 | |
| 3 | | | |
| 4 | LL | fn method(); | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `SuperSuper` is shadowed by a subtrait item | |
| 8 | --> $DIR/definition-site.rs:5:5 | |
| 9 | | | |
| 10 | LL | fn method(); | |
| 11 | | ^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/definition-site.rs:2:9 | |
| 14 | | | |
| 15 | LL | #![deny(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | error: trait item `method` from `Sub` shadows identically named item from supertrait | |
| 19 | --> $DIR/definition-site.rs:14:5 | |
| 20 | | | |
| 21 | LL | fn method(); | |
| 22 | | ^^^^^^^^^^^^ | |
| 23 | | | |
| 24 | note: items from several supertraits are shadowed: `Super` and `SuperSuper` | |
| 25 | --> $DIR/definition-site.rs:5:5 | |
| 26 | | | |
| 27 | LL | fn method(); | |
| 28 | | ^^^^^^^^^^^^ | |
| 29 | ... | |
| 30 | LL | fn method(); | |
| 31 | | ^^^^^^^^^^^^ | |
| 32 | ||
| 33 | error: 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 | ||
| 5 | struct W<T>(T); | |
| 6 | ||
| 7 | trait Upstream { | |
| 8 | fn hello(&self) {} | |
| 9 | } | |
| 10 | impl<T> Upstream for T {} | |
| 11 | ||
| 12 | trait Downstream: Upstream { | |
| 13 | fn hello(&self) {} | |
| 14 | //~^ WARN trait item `hello` from `Downstream` shadows identically named item | |
| 15 | } | |
| 16 | impl<T> Downstream for W<T> where T: Foo {} | |
| 17 | ||
| 18 | trait Foo {} | |
| 19 | ||
| 20 | fn 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 @@ |
| 1 | warning: trait item `hello` from `Downstream` shadows identically named item from supertrait | |
| 2 | --> $DIR/false-subtrait-after-inference.rs:13:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) {} | |
| 5 | | ^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `Upstream` is shadowed by a subtrait item | |
| 8 | --> $DIR/false-subtrait-after-inference.rs:8:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) {} | |
| 11 | | ^^^^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/false-subtrait-after-inference.rs:3:9 | |
| 14 | | | |
| 15 | LL | #![warn(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | warning: trait item `hello` from `Downstream` shadows identically named item from supertrait | |
| 19 | --> $DIR/false-subtrait-after-inference.rs:22:7 | |
| 20 | | | |
| 21 | LL | x.hello(); | |
| 22 | | ^^^^^ | |
| 23 | | | |
| 24 | note: item from `Downstream` shadows a supertrait item | |
| 25 | --> $DIR/false-subtrait-after-inference.rs:13:5 | |
| 26 | | | |
| 27 | LL | fn hello(&self) {} | |
| 28 | | ^^^^^^^^^^^^^^^ | |
| 29 | note: item from `Upstream` is shadowed by a subtrait item | |
| 30 | --> $DIR/false-subtrait-after-inference.rs:8:5 | |
| 31 | | | |
| 32 | LL | fn hello(&self) {} | |
| 33 | | ^^^^^^^^^^^^^^^ | |
| 34 | note: the lint level is defined here | |
| 35 | --> $DIR/false-subtrait-after-inference.rs:2:9 | |
| 36 | | | |
| 37 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 38 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 39 | ||
| 40 | error[E0277]: the trait bound `i32: Foo` is not satisfied | |
| 41 | --> $DIR/false-subtrait-after-inference.rs:22:7 | |
| 42 | | | |
| 43 | LL | x.hello(); | |
| 44 | | ^^^^^ the trait `Foo` is not implemented for `i32` | |
| 45 | | | |
| 46 | help: this trait has no implementations, consider adding one | |
| 47 | --> $DIR/false-subtrait-after-inference.rs:18:1 | |
| 48 | | | |
| 49 | LL | trait Foo {} | |
| 50 | | ^^^^^^^^^ | |
| 51 | note: required for `W<i32>` to implement `Downstream` | |
| 52 | --> $DIR/false-subtrait-after-inference.rs:16:9 | |
| 53 | | | |
| 54 | LL | impl<T> Downstream for W<T> where T: Foo {} | |
| 55 | | ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here | |
| 56 | ||
| 57 | error: aborting due to 1 previous error; 2 warnings emitted | |
| 58 | ||
| 59 | For 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 | ||
| 3 | trait A { | |
| 4 | fn hello(&self) -> &'static str { | |
| 5 | "A" | |
| 6 | } | |
| 7 | } | |
| 8 | impl<T> A for T {} | |
| 9 | ||
| 10 | trait B { | |
| 11 | fn hello(&self) -> &'static str { | |
| 12 | "B" | |
| 13 | } | |
| 14 | } | |
| 15 | impl<T> B for T {} | |
| 16 | ||
| 17 | trait C: A + B { | |
| 18 | fn hello(&self) -> &'static str { | |
| 19 | "C" | |
| 20 | } | |
| 21 | } | |
| 22 | impl<T> C for T {} | |
| 23 | ||
| 24 | // Since `D` is not a subtrait of `C`, | |
| 25 | // we have no obvious lower bound. | |
| 26 | ||
| 27 | trait D: B { | |
| 28 | fn hello(&self) -> &'static str { | |
| 29 | "D" | |
| 30 | } | |
| 31 | } | |
| 32 | impl<T> D for T {} | |
| 33 | ||
| 34 | fn 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 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/no-common-ancestor-2.rs:35:8 | |
| 3 | | | |
| 4 | LL | ().hello(); | |
| 5 | | ^^^^^ multiple `hello` found | |
| 6 | | | |
| 7 | note: 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 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: 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 | | | |
| 15 | LL | fn hello(&self) -> &'static str { | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | note: 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 | | | |
| 20 | LL | fn hello(&self) -> &'static str { | |
| 21 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 22 | note: 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 | | | |
| 25 | LL | fn hello(&self) -> &'static str { | |
| 26 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 27 | help: disambiguate the method for candidate #1 | |
| 28 | | | |
| 29 | LL - ().hello(); | |
| 30 | LL + A::hello(&()); | |
| 31 | | | |
| 32 | help: disambiguate the method for candidate #2 | |
| 33 | | | |
| 34 | LL - ().hello(); | |
| 35 | LL + B::hello(&()); | |
| 36 | | | |
| 37 | help: disambiguate the method for candidate #3 | |
| 38 | | | |
| 39 | LL - ().hello(); | |
| 40 | LL + C::hello(&()); | |
| 41 | | | |
| 42 | help: disambiguate the method for candidate #4 | |
| 43 | | | |
| 44 | LL - ().hello(); | |
| 45 | LL + D::hello(&()); | |
| 46 | | | |
| 47 | ||
| 48 | error: aborting due to 1 previous error | |
| 49 | ||
| 50 | For 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 | ||
| 3 | trait A { | |
| 4 | fn hello(&self) -> &'static str { | |
| 5 | "A" | |
| 6 | } | |
| 7 | } | |
| 8 | impl<T> A for T {} | |
| 9 | ||
| 10 | trait B { | |
| 11 | fn hello(&self) -> &'static str { | |
| 12 | "B" | |
| 13 | } | |
| 14 | } | |
| 15 | impl<T> B for T {} | |
| 16 | ||
| 17 | fn 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 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/no-common-ancestor.rs:18:8 | |
| 3 | | | |
| 4 | LL | ().hello(); | |
| 5 | | ^^^^^ multiple `hello` found | |
| 6 | | | |
| 7 | note: candidate #1 is defined in an impl of the trait `A` for the type `T` | |
| 8 | --> $DIR/no-common-ancestor.rs:4:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: candidate #2 is defined in an impl of the trait `B` for the type `T` | |
| 13 | --> $DIR/no-common-ancestor.rs:11:5 | |
| 14 | | | |
| 15 | LL | fn hello(&self) -> &'static str { | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | help: disambiguate the method for candidate #1 | |
| 18 | | | |
| 19 | LL - ().hello(); | |
| 20 | LL + A::hello(&()); | |
| 21 | | | |
| 22 | help: disambiguate the method for candidate #2 | |
| 23 | | | |
| 24 | LL - ().hello(); | |
| 25 | LL + B::hello(&()); | |
| 26 | | | |
| 27 | ||
| 28 | error: aborting due to 1 previous error | |
| 29 | ||
| 30 | For 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 | ||
| 5 | mod 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 | ||
| 14 | trait Supertrait { | |
| 15 | fn hello(&self) -> &'static str { | |
| 16 | "supertrait" | |
| 17 | } | |
| 18 | } | |
| 19 | impl<T> Supertrait for T {} | |
| 20 | ||
| 21 | fn 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 | ||
| 8 | struct W<T>(T); | |
| 9 | ||
| 10 | trait Upstream { | |
| 11 | fn hello(&self) -> &'static str { | |
| 12 | "upstream" | |
| 13 | } | |
| 14 | } | |
| 15 | impl<T> Upstream for T {} | |
| 16 | ||
| 17 | trait Downstream: Upstream { | |
| 18 | fn hello(&self) -> &'static str { | |
| 19 | "downstream" | |
| 20 | } | |
| 21 | } | |
| 22 | impl<T> Downstream for W<T> where T: Foo {} | |
| 23 | ||
| 24 | trait Foo {} | |
| 25 | ||
| 26 | fn 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 | ||
| 8 | trait A { | |
| 9 | fn hello() -> &'static str { | |
| 10 | "A" | |
| 11 | } | |
| 12 | } | |
| 13 | impl<T> A for T {} | |
| 14 | ||
| 15 | trait B: A { | |
| 16 | fn hello() -> &'static str { | |
| 17 | "B" | |
| 18 | } | |
| 19 | } | |
| 20 | impl<T> B for T {} | |
| 21 | ||
| 22 | fn foo<T>() -> &'static str { | |
| 23 | T::hello() | |
| 24 | } | |
| 25 | ||
| 26 | fn main() { | |
| 27 | assert_eq!(foo::<()>(), "B"); | |
| 28 | } |
tests/ui/methods/supertrait-shadowing/unstable.off_normal.stderr deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | warning: a method with this name may be added to the standard library in the future | |
| 2 | --> $DIR/unstable.rs:26:19 | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` | |
| 12 | | | |
| 13 | LL + #![feature(downstream)] | |
| 14 | | | |
| 15 | ||
| 16 | warning: 1 warning emitted | |
| 17 |
tests/ui/methods/supertrait-shadowing/unstable.off_shadowing.stderr deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | warning: a method with this name may be added to the standard library in the future | |
| 2 | --> $DIR/unstable.rs:26:19 | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` | |
| 12 | | | |
| 13 | LL + #![feature(downstream)] | |
| 14 | | | |
| 15 | ||
| 16 | warning: 1 warning emitted | |
| 17 |
tests/ui/methods/supertrait-shadowing/unstable.on_normal.stderr deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/unstable.rs:30:19 | |
| 3 | | | |
| 4 | LL | 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` | |
| 9 | help: disambiguate the method for candidate #1 | |
| 10 | | | |
| 11 | LL - assert_eq!(().hello(), "B"); | |
| 12 | LL + assert_eq!(shadowed_stability::A::hello(&()), "B"); | |
| 13 | | | |
| 14 | help: disambiguate the method for candidate #2 | |
| 15 | | | |
| 16 | LL - assert_eq!(().hello(), "B"); | |
| 17 | LL + assert_eq!(shadowed_stability::B::hello(&()), "B"); | |
| 18 | | | |
| 19 | ||
| 20 | error: aborting due to 1 previous error | |
| 21 | ||
| 22 | For 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 | ||
| 21 | extern crate shadowed_stability; | |
| 22 | use shadowed_stability::*; | |
| 23 | ||
| 24 | fn 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 | ||
| 6 | use std::cell::Cell; | |
| 7 | ||
| 8 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 9 | ||
| 10 | fn 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 | ||
| 6 | use std::cell::Cell; | |
| 7 | ||
| 8 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 9 | ||
| 10 | struct Foo<T> { data: Vec<T> } | |
| 11 | ||
| 12 | fn 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 | ||
| 6 | use std::cell::Cell; | |
| 7 | ||
| 8 | struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>); | |
| 9 | ||
| 10 | struct Foo<T> { data: Vec<T> } | |
| 11 | ||
| 12 | fn 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 | ||
| 21 | impl<T> Drop for Foo<T> { | |
| 22 | fn drop(&mut self) { | |
| 23 | potentially_specialized_wrt_t(&self.data[0]) | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | fn 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 @@ |
| 1 | error[E0713]: borrow may still be in use when destructor runs | |
| 2 | --> $DIR/reject-ex1.rs:32:29 | |
| 3 | | | |
| 4 | LL | foo.data[0].1.set(Some(&foo.data[1])); | |
| 5 | | ^^^^^^^^ | |
| 6 | ... | |
| 7 | LL | } | |
| 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 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 | ||
| 17 | For 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)] | |
| 7 | use std::cell::Cell; | |
| 8 | ||
| 9 | struct Concrete<'a>(#[allow(dead_code)] u32, Cell<Option<&'a Concrete<'a>>>); | |
| 10 | ||
| 11 | struct Foo<T> { data: Vec<T> } | |
| 12 | ||
| 13 | // Below is the UGEH attribute | |
| 14 | unsafe impl<#[may_dangle] T> Drop for Foo<T> { | |
| 15 | fn drop(&mut self) { } | |
| 16 | } | |
| 17 | ||
| 18 | fn 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 | ||
| 4 | extern "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 | ||
| 14 | fn main() { | |
| 15 | } |
tests/ui/span/foreign-item-vis-span.stderr created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | error[E0428]: the name `foo` is defined multiple times | |
| 2 | --> $DIR/foreign-item-vis-span.rs:7:3 | |
| 3 | | | |
| 4 | LL | fn foo(); | |
| 5 | | --------- previous definition of the value `foo` here | |
| 6 | LL | | |
| 7 | LL | / pub | |
| 8 | LL | | fn foo(); | |
| 9 | | |___________^ `foo` redefined here | |
| 10 | | | |
| 11 | = note: `foo` must be defined only once in the value namespace of this module | |
| 12 | ||
| 13 | error[E0428]: the name `foo` is defined multiple times | |
| 14 | --> $DIR/foreign-item-vis-span.rs:10:3 | |
| 15 | | | |
| 16 | LL | fn foo(); | |
| 17 | | --------- previous definition of the value `foo` here | |
| 18 | ... | |
| 19 | LL | / pub | |
| 20 | LL | | 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 | ||
| 25 | error: aborting due to 2 previous errors | |
| 26 | ||
| 27 | For 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 | ||
| 8 | use std::cell::Cell; | |
| 9 | ||
| 10 | struct Concrete<'a>(u32, Cell<Option<&'a Concrete<'a>>>); | |
| 11 | ||
| 12 | struct Foo<T> { data: Vec<T> } | |
| 13 | ||
| 14 | fn 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 | ||
| 23 | impl<T> Drop for Foo<T> { | |
| 24 | fn drop(&mut self) { | |
| 25 | potentially_specialized_wrt_t(&self.data[0]) | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn 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 @@ |
| 1 | error[E0713]: borrow may still be in use when destructor runs | |
| 2 | --> $DIR/issue28498-reject-ex1.rs:34:29 | |
| 3 | | | |
| 4 | LL | foo.data[0].1.set(Some(&foo.data[1])); | |
| 5 | | ^^^^^^^^ | |
| 6 | ... | |
| 7 | LL | } | |
| 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 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 | ||
| 17 | For 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 | ||
| 4 | mod A {} | |
| 5 | ||
| 6 | fn 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 @@ |
| 1 | error[E0574]: expected struct, variant or union type, found module `A` | |
| 2 | --> $DIR/non-struct-in-struct-position.rs:7:13 | |
| 3 | | | |
| 4 | LL | let u = A { x: 1 }; | |
| 5 | | ^ not a struct, variant or union type | |
| 6 | ||
| 7 | error[E0574]: expected struct, variant or union type, found builtin type `u32` | |
| 8 | --> $DIR/non-struct-in-struct-position.rs:8:13 | |
| 9 | | | |
| 10 | LL | let v = u32 { x: 1 }; | |
| 11 | | ^^^ not a struct, variant or union type | |
| 12 | ||
| 13 | error[E0574]: expected struct, variant or union type, found module `A` | |
| 14 | --> $DIR/non-struct-in-struct-position.rs:10:9 | |
| 15 | | | |
| 16 | LL | A { x: 1 } => {} | |
| 17 | | ^ not a struct, variant or union type | |
| 18 | ||
| 19 | error[E0574]: expected struct, variant or union type, found builtin type `u32` | |
| 20 | --> $DIR/non-struct-in-struct-position.rs:12:9 | |
| 21 | | | |
| 22 | LL | u32 { x: 1 } => {} | |
| 23 | | ^^^ not a struct, variant or union type | |
| 24 | ||
| 25 | error: aborting due to 4 previous errors | |
| 26 | ||
| 27 | For 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 | ||
| 7 | trait A { | |
| 8 | const CONST: i32; | |
| 9 | } | |
| 10 | impl<T> A for T { | |
| 11 | const CONST: i32 = 1; | |
| 12 | } | |
| 13 | ||
| 14 | trait B: A { | |
| 15 | type const CONST: i32; | |
| 16 | } | |
| 17 | impl<T> B for T { | |
| 18 | type const CONST: i32 = 2; | |
| 19 | } | |
| 20 | ||
| 21 | trait C: B {} | |
| 22 | impl<T> C for T {} | |
| 23 | ||
| 24 | fn main() { | |
| 25 | assert_eq!(i32::CONST, 2); | |
| 26 | generic::<u32>(); | |
| 27 | } | |
| 28 | ||
| 29 | fn 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 | ||
| 4 | use std::mem::size_of; | |
| 5 | ||
| 6 | trait A { | |
| 7 | type Assoc; | |
| 8 | } | |
| 9 | impl<X> A for X { | |
| 10 | type Assoc = i8; | |
| 11 | } | |
| 12 | ||
| 13 | trait B: A { | |
| 14 | type Assoc; | |
| 15 | } | |
| 16 | impl<X> B for X { | |
| 17 | type Assoc = i16; | |
| 18 | } | |
| 19 | ||
| 20 | trait C: B {} | |
| 21 | impl<X> C for X {} | |
| 22 | ||
| 23 | fn 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 | ||
| 33 | fn b_unbound<U: B>() { | |
| 34 | let _ = size_of::<U::Assoc>(); | |
| 35 | } | |
| 36 | ||
| 37 | fn c_unbound<U: C>() { | |
| 38 | let _ = size_of::<U::Assoc>(); | |
| 39 | } | |
| 40 | ||
| 41 | fn b_assoc_is_a<U: B<Assoc = i8>>() { | |
| 42 | let _ = size_of::<U::Assoc>(); | |
| 43 | } | |
| 44 | ||
| 45 | fn 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 @@ |
| 1 | error[E0271]: type mismatch resolving `<u32 as B>::Assoc == i8` | |
| 2 | --> $DIR/assoc-type-fail.rs:27:20 | |
| 3 | | | |
| 4 | LL | b_assoc_is_a::<u32>(); | |
| 5 | | ^^^ type mismatch resolving `<u32 as B>::Assoc == i8` | |
| 6 | | | |
| 7 | note: expected this to be `i8` | |
| 8 | --> $DIR/assoc-type-fail.rs:17:18 | |
| 9 | | | |
| 10 | LL | type Assoc = i16; | |
| 11 | | ^^^ | |
| 12 | note: required by a bound in `b_assoc_is_a` | |
| 13 | --> $DIR/assoc-type-fail.rs:41:22 | |
| 14 | | | |
| 15 | LL | fn b_assoc_is_a<U: B<Assoc = i8>>() { | |
| 16 | | ^^^^^^^^^^ required by this bound in `b_assoc_is_a` | |
| 17 | ||
| 18 | error[E0271]: type mismatch resolving `<u32 as B>::Assoc == i8` | |
| 19 | --> $DIR/assoc-type-fail.rs:29:20 | |
| 20 | | | |
| 21 | LL | c_assoc_is_a::<u32>(); | |
| 22 | | ^^^ type mismatch resolving `<u32 as B>::Assoc == i8` | |
| 23 | | | |
| 24 | note: expected this to be `i8` | |
| 25 | --> $DIR/assoc-type-fail.rs:17:18 | |
| 26 | | | |
| 27 | LL | type Assoc = i16; | |
| 28 | | ^^^ | |
| 29 | note: required by a bound in `c_assoc_is_a` | |
| 30 | --> $DIR/assoc-type-fail.rs:45:22 | |
| 31 | | | |
| 32 | LL | fn c_assoc_is_a<U: C<Assoc = i8>>() { | |
| 33 | | ^^^^^^^^^^ required by this bound in `c_assoc_is_a` | |
| 34 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 | ||
| 37 | For 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 | ||
| 7 | trait A { | |
| 8 | type Assoc; | |
| 9 | } | |
| 10 | impl<T> A for T { | |
| 11 | type Assoc = i8; | |
| 12 | } | |
| 13 | ||
| 14 | trait B: A { | |
| 15 | type Assoc; | |
| 16 | } | |
| 17 | impl<T> B for T { | |
| 18 | type Assoc = i16; | |
| 19 | } | |
| 20 | ||
| 21 | trait C: B {} | |
| 22 | impl<T> C for T {} | |
| 23 | ||
| 24 | #[rustc_dump_predicates] | |
| 25 | fn 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] | |
| 32 | fn 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] | |
| 39 | fn 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 | ||
| 45 | fn main() {} |
tests/ui/supertrait-shadowing/assoc-type-predicates.stderr created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | error: rustc_dump_predicates | |
| 2 | --> $DIR/assoc-type-predicates.rs:25:1 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 11 | error: rustc_dump_predicates | |
| 12 | --> $DIR/assoc-type-predicates.rs:32:1 | |
| 13 | | | |
| 14 | LL | 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 | ||
| 21 | error: rustc_dump_predicates | |
| 22 | --> $DIR/assoc-type-predicates.rs:39:1 | |
| 23 | | | |
| 24 | LL | 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 | ||
| 31 | error: 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 | ||
| 7 | use std::mem::size_of; | |
| 8 | ||
| 9 | trait A { | |
| 10 | type Assoc; | |
| 11 | } | |
| 12 | impl<T> A for T { | |
| 13 | type Assoc = i8; | |
| 14 | } | |
| 15 | ||
| 16 | trait B: A { | |
| 17 | type Assoc; | |
| 18 | } | |
| 19 | impl<T> B for T { | |
| 20 | type Assoc = i16; | |
| 21 | } | |
| 22 | ||
| 23 | trait C: B {} | |
| 24 | impl<T> C for T {} | |
| 25 | ||
| 26 | fn main() { | |
| 27 | generic::<u32>(); | |
| 28 | generic2::<u32>(); | |
| 29 | generic3::<u32>(); | |
| 30 | generic4::<u32>(); | |
| 31 | generic5::<u32>(); | |
| 32 | } | |
| 33 | ||
| 34 | fn generic<T: B>() { | |
| 35 | assert_eq!(size_of::<T::Assoc>(), 2); | |
| 36 | } | |
| 37 | ||
| 38 | fn generic2<T: A<Assoc = i8>>() { | |
| 39 | assert_eq!(size_of::<T::Assoc>(), 1); | |
| 40 | } | |
| 41 | ||
| 42 | fn generic3<T: B<Assoc = i16>>() { | |
| 43 | assert_eq!(size_of::<T::Assoc>(), 2); | |
| 44 | } | |
| 45 | ||
| 46 | fn generic4<T: C<Assoc = i16>>() { | |
| 47 | assert_eq!(size_of::<T::Assoc>(), 2); | |
| 48 | } | |
| 49 | ||
| 50 | fn 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")] | |
| 5 | pub 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")] | |
| 12 | impl<T> A for T {} | |
| 13 | ||
| 14 | #[stable(feature = "main", since = "1.0.0")] | |
| 15 | pub 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")] | |
| 22 | impl<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 | ||
| 9 | use std::mem::size_of; | |
| 10 | ||
| 11 | trait A { | |
| 12 | fn hello(&self) -> &'static str { | |
| 13 | "A" | |
| 14 | } | |
| 15 | type Assoc; | |
| 16 | const CONST: i32; | |
| 17 | } | |
| 18 | impl<T> A for T { | |
| 19 | type Assoc = i8; | |
| 20 | const CONST: i32 = 1; | |
| 21 | } | |
| 22 | ||
| 23 | trait B { | |
| 24 | fn hello(&self) -> &'static str { | |
| 25 | "B" | |
| 26 | } | |
| 27 | type Assoc; | |
| 28 | const CONST: i32; | |
| 29 | } | |
| 30 | impl<T> B for T { | |
| 31 | type Assoc = i16; | |
| 32 | const CONST: i32 = 2; | |
| 33 | } | |
| 34 | ||
| 35 | trait 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 | } | |
| 45 | impl<T> C for T { | |
| 46 | type Assoc = i32; | |
| 47 | type const CONST: i32 = 3; | |
| 48 | } | |
| 49 | ||
| 50 | fn main() { | |
| 51 | assert_eq!(().hello(), "C"); | |
| 52 | //~^ WARN trait item `hello` from `C` shadows identically named item from supertrait | |
| 53 | check::<()>(); | |
| 54 | } | |
| 55 | ||
| 56 | fn 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 @@ |
| 1 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor-2.rs:36:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: items from several supertraits are shadowed: `B` and `A` | |
| 8 | --> $DIR/common-ancestor-2.rs:12:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ... | |
| 13 | LL | fn hello(&self) -> &'static str { | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | note: the lint level is defined here | |
| 16 | --> $DIR/common-ancestor-2.rs:6:9 | |
| 17 | | | |
| 18 | LL | #![warn(shadowing_supertrait_items)] | |
| 19 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 20 | ||
| 21 | warning: trait item `Assoc` from `C` shadows identically named item from supertrait | |
| 22 | --> $DIR/common-ancestor-2.rs:40:5 | |
| 23 | | | |
| 24 | LL | type Assoc; | |
| 25 | | ^^^^^^^^^^ | |
| 26 | | | |
| 27 | note: items from several supertraits are shadowed: `B` and `A` | |
| 28 | --> $DIR/common-ancestor-2.rs:15:5 | |
| 29 | | | |
| 30 | LL | type Assoc; | |
| 31 | | ^^^^^^^^^^ | |
| 32 | ... | |
| 33 | LL | type Assoc; | |
| 34 | | ^^^^^^^^^^ | |
| 35 | ||
| 36 | warning: trait item `CONST` from `C` shadows identically named item from supertrait | |
| 37 | --> $DIR/common-ancestor-2.rs:42:5 | |
| 38 | | | |
| 39 | LL | type const CONST: i32; | |
| 40 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 41 | | | |
| 42 | note: items from several supertraits are shadowed: `B` and `A` | |
| 43 | --> $DIR/common-ancestor-2.rs:16:5 | |
| 44 | | | |
| 45 | LL | const CONST: i32; | |
| 46 | | ^^^^^^^^^^^^^^^^ | |
| 47 | ... | |
| 48 | LL | const CONST: i32; | |
| 49 | | ^^^^^^^^^^^^^^^^ | |
| 50 | ||
| 51 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 52 | --> $DIR/common-ancestor-2.rs:51:19 | |
| 53 | | | |
| 54 | LL | assert_eq!(().hello(), "C"); | |
| 55 | | ^^^^^ | |
| 56 | | | |
| 57 | note: item from `C` shadows a supertrait item | |
| 58 | --> $DIR/common-ancestor-2.rs:36:5 | |
| 59 | | | |
| 60 | LL | fn hello(&self) -> &'static str { | |
| 61 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 62 | note: items from several supertraits are shadowed: `A` and `B` | |
| 63 | --> $DIR/common-ancestor-2.rs:12:5 | |
| 64 | | | |
| 65 | LL | fn hello(&self) -> &'static str { | |
| 66 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 67 | ... | |
| 68 | LL | fn hello(&self) -> &'static str { | |
| 69 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 70 | note: the lint level is defined here | |
| 71 | --> $DIR/common-ancestor-2.rs:5:9 | |
| 72 | | | |
| 73 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 74 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 75 | ||
| 76 | warning: 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 | ||
| 9 | use std::mem::size_of; | |
| 10 | ||
| 11 | trait A { | |
| 12 | fn hello(&self) -> &'static str { | |
| 13 | "A" | |
| 14 | } | |
| 15 | type Assoc; | |
| 16 | const CONST: i32; | |
| 17 | } | |
| 18 | impl<T> A for T { | |
| 19 | type Assoc = i8; | |
| 20 | const CONST: i32 = 1; | |
| 21 | } | |
| 22 | ||
| 23 | trait B { | |
| 24 | fn hello(&self) -> &'static str { | |
| 25 | "B" | |
| 26 | } | |
| 27 | type Assoc; | |
| 28 | const CONST: i32; | |
| 29 | } | |
| 30 | impl<T> B for T { | |
| 31 | type Assoc = i16; | |
| 32 | const CONST: i32 = 2; | |
| 33 | } | |
| 34 | ||
| 35 | trait 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 | } | |
| 45 | impl<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 | ||
| 52 | trait 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 | } | |
| 62 | impl<T> D for T { | |
| 63 | type Assoc = i64; | |
| 64 | type const CONST: i32 = 4; | |
| 65 | } | |
| 66 | ||
| 67 | fn main() { | |
| 68 | assert_eq!(().hello(), "D"); | |
| 69 | //~^ WARN trait item `hello` from `D` shadows identically named item from supertrait | |
| 70 | check::<()>(); | |
| 71 | } | |
| 72 | ||
| 73 | fn 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 @@ |
| 1 | warning: trait item `hello` from `C` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor-3.rs:36:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: items from several supertraits are shadowed: `B` and `A` | |
| 8 | --> $DIR/common-ancestor-3.rs:12:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | ... | |
| 13 | LL | fn hello(&self) -> &'static str { | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | note: the lint level is defined here | |
| 16 | --> $DIR/common-ancestor-3.rs:6:9 | |
| 17 | | | |
| 18 | LL | #![warn(shadowing_supertrait_items)] | |
| 19 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 20 | ||
| 21 | warning: trait item `Assoc` from `C` shadows identically named item from supertrait | |
| 22 | --> $DIR/common-ancestor-3.rs:40:5 | |
| 23 | | | |
| 24 | LL | type Assoc; | |
| 25 | | ^^^^^^^^^^ | |
| 26 | | | |
| 27 | note: items from several supertraits are shadowed: `B` and `A` | |
| 28 | --> $DIR/common-ancestor-3.rs:15:5 | |
| 29 | | | |
| 30 | LL | type Assoc; | |
| 31 | | ^^^^^^^^^^ | |
| 32 | ... | |
| 33 | LL | type Assoc; | |
| 34 | | ^^^^^^^^^^ | |
| 35 | ||
| 36 | warning: trait item `CONST` from `C` shadows identically named item from supertrait | |
| 37 | --> $DIR/common-ancestor-3.rs:42:5 | |
| 38 | | | |
| 39 | LL | type const CONST: i32; | |
| 40 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 41 | | | |
| 42 | note: items from several supertraits are shadowed: `B` and `A` | |
| 43 | --> $DIR/common-ancestor-3.rs:16:5 | |
| 44 | | | |
| 45 | LL | const CONST: i32; | |
| 46 | | ^^^^^^^^^^^^^^^^ | |
| 47 | ... | |
| 48 | LL | const CONST: i32; | |
| 49 | | ^^^^^^^^^^^^^^^^ | |
| 50 | ||
| 51 | warning: trait item `hello` from `D` shadows identically named item from supertrait | |
| 52 | --> $DIR/common-ancestor-3.rs:53:5 | |
| 53 | | | |
| 54 | LL | fn hello(&self) -> &'static str { | |
| 55 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 56 | | | |
| 57 | note: items from several supertraits are shadowed: `C`, `B`, and `A` | |
| 58 | --> $DIR/common-ancestor-3.rs:12:5 | |
| 59 | | | |
| 60 | LL | fn hello(&self) -> &'static str { | |
| 61 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 62 | ... | |
| 63 | LL | fn hello(&self) -> &'static str { | |
| 64 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 65 | ... | |
| 66 | LL | fn hello(&self) -> &'static str { | |
| 67 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 68 | ||
| 69 | warning: trait item `Assoc` from `D` shadows identically named item from supertrait | |
| 70 | --> $DIR/common-ancestor-3.rs:57:5 | |
| 71 | | | |
| 72 | LL | type Assoc; | |
| 73 | | ^^^^^^^^^^ | |
| 74 | | | |
| 75 | note: items from several supertraits are shadowed: `C`, `B`, and `A` | |
| 76 | --> $DIR/common-ancestor-3.rs:15:5 | |
| 77 | | | |
| 78 | LL | type Assoc; | |
| 79 | | ^^^^^^^^^^ | |
| 80 | ... | |
| 81 | LL | type Assoc; | |
| 82 | | ^^^^^^^^^^ | |
| 83 | ... | |
| 84 | LL | type Assoc; | |
| 85 | | ^^^^^^^^^^ | |
| 86 | ||
| 87 | warning: trait item `CONST` from `D` shadows identically named item from supertrait | |
| 88 | --> $DIR/common-ancestor-3.rs:59:5 | |
| 89 | | | |
| 90 | LL | type const CONST: i32; | |
| 91 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 92 | | | |
| 93 | note: items from several supertraits are shadowed: `C`, `B`, and `A` | |
| 94 | --> $DIR/common-ancestor-3.rs:16:5 | |
| 95 | | | |
| 96 | LL | const CONST: i32; | |
| 97 | | ^^^^^^^^^^^^^^^^ | |
| 98 | ... | |
| 99 | LL | const CONST: i32; | |
| 100 | | ^^^^^^^^^^^^^^^^ | |
| 101 | ... | |
| 102 | LL | type const CONST: i32; | |
| 103 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 104 | ||
| 105 | warning: trait item `hello` from `D` shadows identically named item from supertrait | |
| 106 | --> $DIR/common-ancestor-3.rs:68:19 | |
| 107 | | | |
| 108 | LL | assert_eq!(().hello(), "D"); | |
| 109 | | ^^^^^ | |
| 110 | | | |
| 111 | note: item from `D` shadows a supertrait item | |
| 112 | --> $DIR/common-ancestor-3.rs:53:5 | |
| 113 | | | |
| 114 | LL | fn hello(&self) -> &'static str { | |
| 115 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 116 | note: items from several supertraits are shadowed: `A`, `B`, and `C` | |
| 117 | --> $DIR/common-ancestor-3.rs:12:5 | |
| 118 | | | |
| 119 | LL | fn hello(&self) -> &'static str { | |
| 120 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 121 | ... | |
| 122 | LL | fn hello(&self) -> &'static str { | |
| 123 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 124 | ... | |
| 125 | LL | fn hello(&self) -> &'static str { | |
| 126 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 127 | note: the lint level is defined here | |
| 128 | --> $DIR/common-ancestor-3.rs:5:9 | |
| 129 | | | |
| 130 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 131 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 132 | ||
| 133 | warning: 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 | ||
| 9 | use std::mem::size_of; | |
| 10 | ||
| 11 | trait A { | |
| 12 | fn hello(&self) -> &'static str { | |
| 13 | "A" | |
| 14 | } | |
| 15 | type Assoc; | |
| 16 | const CONST: i32; | |
| 17 | } | |
| 18 | impl<T> A for T { | |
| 19 | type Assoc = i8; | |
| 20 | const CONST: i32 = 1; | |
| 21 | } | |
| 22 | ||
| 23 | trait 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 | } | |
| 33 | impl<T> B for T { | |
| 34 | type Assoc = i16; | |
| 35 | type const CONST: i32 = 2; | |
| 36 | } | |
| 37 | ||
| 38 | fn main() { | |
| 39 | assert_eq!(().hello(), "B"); | |
| 40 | //~^ WARN trait item `hello` from `B` shadows identically named item from supertrait | |
| 41 | check::<()>(); | |
| 42 | } | |
| 43 | ||
| 44 | fn 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 @@ |
| 1 | warning: trait item `hello` from `B` shadows identically named item from supertrait | |
| 2 | --> $DIR/common-ancestor.rs:24:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) -> &'static str { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `A` is shadowed by a subtrait item | |
| 8 | --> $DIR/common-ancestor.rs:12:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/common-ancestor.rs:6:9 | |
| 14 | | | |
| 15 | LL | #![warn(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | warning: trait item `Assoc` from `B` shadows identically named item from supertrait | |
| 19 | --> $DIR/common-ancestor.rs:28:5 | |
| 20 | | | |
| 21 | LL | type Assoc; | |
| 22 | | ^^^^^^^^^^ | |
| 23 | | | |
| 24 | note: item from `A` is shadowed by a subtrait item | |
| 25 | --> $DIR/common-ancestor.rs:15:5 | |
| 26 | | | |
| 27 | LL | type Assoc; | |
| 28 | | ^^^^^^^^^^ | |
| 29 | ||
| 30 | warning: trait item `CONST` from `B` shadows identically named item from supertrait | |
| 31 | --> $DIR/common-ancestor.rs:30:5 | |
| 32 | | | |
| 33 | LL | type const CONST: i32; | |
| 34 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 35 | | | |
| 36 | note: item from `A` is shadowed by a subtrait item | |
| 37 | --> $DIR/common-ancestor.rs:16:5 | |
| 38 | | | |
| 39 | LL | const CONST: i32; | |
| 40 | | ^^^^^^^^^^^^^^^^ | |
| 41 | ||
| 42 | warning: trait item `hello` from `B` shadows identically named item from supertrait | |
| 43 | --> $DIR/common-ancestor.rs:39:19 | |
| 44 | | | |
| 45 | LL | assert_eq!(().hello(), "B"); | |
| 46 | | ^^^^^ | |
| 47 | | | |
| 48 | note: item from `B` shadows a supertrait item | |
| 49 | --> $DIR/common-ancestor.rs:24:5 | |
| 50 | | | |
| 51 | LL | fn hello(&self) -> &'static str { | |
| 52 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 53 | note: item from `A` is shadowed by a subtrait item | |
| 54 | --> $DIR/common-ancestor.rs:12:5 | |
| 55 | | | |
| 56 | LL | fn hello(&self) -> &'static str { | |
| 57 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 58 | note: the lint level is defined here | |
| 59 | --> $DIR/common-ancestor.rs:5:9 | |
| 60 | | | |
| 61 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 62 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 63 | ||
| 64 | warning: 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 | ||
| 4 | trait SuperSuper { | |
| 5 | fn method(); | |
| 6 | const CONST: i32; | |
| 7 | type Assoc; | |
| 8 | } | |
| 9 | ||
| 10 | trait 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 | ||
| 19 | trait 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 | ||
| 28 | fn main() {} |
tests/ui/supertrait-shadowing/definition-site.stderr created+88| ... | ... | @@ -0,0 +1,88 @@ |
| 1 | error: trait item `method` from `Super` shadows identically named item from supertrait | |
| 2 | --> $DIR/definition-site.rs:11:5 | |
| 3 | | | |
| 4 | LL | fn method(); | |
| 5 | | ^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `SuperSuper` is shadowed by a subtrait item | |
| 8 | --> $DIR/definition-site.rs:5:5 | |
| 9 | | | |
| 10 | LL | fn method(); | |
| 11 | | ^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/definition-site.rs:2:9 | |
| 14 | | | |
| 15 | LL | #![deny(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | error: trait item `CONST` from `Super` shadows identically named item from supertrait | |
| 19 | --> $DIR/definition-site.rs:13:5 | |
| 20 | | | |
| 21 | LL | const CONST: i32; | |
| 22 | | ^^^^^^^^^^^^^^^^ | |
| 23 | | | |
| 24 | note: item from `SuperSuper` is shadowed by a subtrait item | |
| 25 | --> $DIR/definition-site.rs:6:5 | |
| 26 | | | |
| 27 | LL | const CONST: i32; | |
| 28 | | ^^^^^^^^^^^^^^^^ | |
| 29 | ||
| 30 | error: trait item `Assoc` from `Super` shadows identically named item from supertrait | |
| 31 | --> $DIR/definition-site.rs:15:5 | |
| 32 | | | |
| 33 | LL | type Assoc; | |
| 34 | | ^^^^^^^^^^ | |
| 35 | | | |
| 36 | note: item from `SuperSuper` is shadowed by a subtrait item | |
| 37 | --> $DIR/definition-site.rs:7:5 | |
| 38 | | | |
| 39 | LL | type Assoc; | |
| 40 | | ^^^^^^^^^^ | |
| 41 | ||
| 42 | error: trait item `method` from `Sub` shadows identically named item from supertrait | |
| 43 | --> $DIR/definition-site.rs:20:5 | |
| 44 | | | |
| 45 | LL | fn method(); | |
| 46 | | ^^^^^^^^^^^^ | |
| 47 | | | |
| 48 | note: items from several supertraits are shadowed: `Super` and `SuperSuper` | |
| 49 | --> $DIR/definition-site.rs:5:5 | |
| 50 | | | |
| 51 | LL | fn method(); | |
| 52 | | ^^^^^^^^^^^^ | |
| 53 | ... | |
| 54 | LL | fn method(); | |
| 55 | | ^^^^^^^^^^^^ | |
| 56 | ||
| 57 | error: trait item `CONST` from `Sub` shadows identically named item from supertrait | |
| 58 | --> $DIR/definition-site.rs:22:5 | |
| 59 | | | |
| 60 | LL | const CONST: i32; | |
| 61 | | ^^^^^^^^^^^^^^^^ | |
| 62 | | | |
| 63 | note: items from several supertraits are shadowed: `Super` and `SuperSuper` | |
| 64 | --> $DIR/definition-site.rs:6:5 | |
| 65 | | | |
| 66 | LL | const CONST: i32; | |
| 67 | | ^^^^^^^^^^^^^^^^ | |
| 68 | ... | |
| 69 | LL | const CONST: i32; | |
| 70 | | ^^^^^^^^^^^^^^^^ | |
| 71 | ||
| 72 | error: trait item `Assoc` from `Sub` shadows identically named item from supertrait | |
| 73 | --> $DIR/definition-site.rs:24:5 | |
| 74 | | | |
| 75 | LL | type Assoc; | |
| 76 | | ^^^^^^^^^^ | |
| 77 | | | |
| 78 | note: items from several supertraits are shadowed: `Super` and `SuperSuper` | |
| 79 | --> $DIR/definition-site.rs:7:5 | |
| 80 | | | |
| 81 | LL | type Assoc; | |
| 82 | | ^^^^^^^^^^ | |
| 83 | ... | |
| 84 | LL | type Assoc; | |
| 85 | | ^^^^^^^^^^ | |
| 86 | ||
| 87 | error: 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 | ||
| 5 | struct W<T>(T); | |
| 6 | ||
| 7 | trait Upstream { | |
| 8 | fn hello(&self) {} | |
| 9 | } | |
| 10 | impl<T> Upstream for T {} | |
| 11 | ||
| 12 | trait Downstream: Upstream { | |
| 13 | fn hello(&self) {} | |
| 14 | //~^ WARN trait item `hello` from `Downstream` shadows identically named item | |
| 15 | } | |
| 16 | impl<T> Downstream for W<T> where T: Foo {} | |
| 17 | ||
| 18 | trait Foo {} | |
| 19 | ||
| 20 | fn 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 @@ |
| 1 | warning: trait item `hello` from `Downstream` shadows identically named item from supertrait | |
| 2 | --> $DIR/false-subtrait-after-inference.rs:13:5 | |
| 3 | | | |
| 4 | LL | fn hello(&self) {} | |
| 5 | | ^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | note: item from `Upstream` is shadowed by a subtrait item | |
| 8 | --> $DIR/false-subtrait-after-inference.rs:8:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) {} | |
| 11 | | ^^^^^^^^^^^^^^^ | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/false-subtrait-after-inference.rs:3:9 | |
| 14 | | | |
| 15 | LL | #![warn(shadowing_supertrait_items)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | warning: trait item `hello` from `Downstream` shadows identically named item from supertrait | |
| 19 | --> $DIR/false-subtrait-after-inference.rs:22:7 | |
| 20 | | | |
| 21 | LL | x.hello(); | |
| 22 | | ^^^^^ | |
| 23 | | | |
| 24 | note: item from `Downstream` shadows a supertrait item | |
| 25 | --> $DIR/false-subtrait-after-inference.rs:13:5 | |
| 26 | | | |
| 27 | LL | fn hello(&self) {} | |
| 28 | | ^^^^^^^^^^^^^^^ | |
| 29 | note: item from `Upstream` is shadowed by a subtrait item | |
| 30 | --> $DIR/false-subtrait-after-inference.rs:8:5 | |
| 31 | | | |
| 32 | LL | fn hello(&self) {} | |
| 33 | | ^^^^^^^^^^^^^^^ | |
| 34 | note: the lint level is defined here | |
| 35 | --> $DIR/false-subtrait-after-inference.rs:2:9 | |
| 36 | | | |
| 37 | LL | #![warn(resolving_to_items_shadowing_supertrait_items)] | |
| 38 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 39 | ||
| 40 | error[E0277]: the trait bound `i32: Foo` is not satisfied | |
| 41 | --> $DIR/false-subtrait-after-inference.rs:22:7 | |
| 42 | | | |
| 43 | LL | x.hello(); | |
| 44 | | ^^^^^ the trait `Foo` is not implemented for `i32` | |
| 45 | | | |
| 46 | help: this trait has no implementations, consider adding one | |
| 47 | --> $DIR/false-subtrait-after-inference.rs:18:1 | |
| 48 | | | |
| 49 | LL | trait Foo {} | |
| 50 | | ^^^^^^^^^ | |
| 51 | note: required for `W<i32>` to implement `Downstream` | |
| 52 | --> $DIR/false-subtrait-after-inference.rs:16:9 | |
| 53 | | | |
| 54 | LL | impl<T> Downstream for W<T> where T: Foo {} | |
| 55 | | ^^^^^^^^^^ ^^^^ --- unsatisfied trait bound introduced here | |
| 56 | ||
| 57 | error: aborting due to 1 previous error; 2 warnings emitted | |
| 58 | ||
| 59 | For 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 | ||
| 4 | use std::mem::size_of; | |
| 5 | ||
| 6 | trait A { | |
| 7 | fn hello(&self) -> &'static str { | |
| 8 | "A" | |
| 9 | } | |
| 10 | type Assoc; | |
| 11 | const CONST: i32; | |
| 12 | } | |
| 13 | impl<T> A for T { | |
| 14 | type Assoc = i8; | |
| 15 | const CONST: i32 = 1; | |
| 16 | } | |
| 17 | ||
| 18 | trait B { | |
| 19 | fn hello(&self) -> &'static str { | |
| 20 | "B" | |
| 21 | } | |
| 22 | type Assoc; | |
| 23 | const CONST: i32; | |
| 24 | } | |
| 25 | impl<T> B for T { | |
| 26 | type Assoc = i16; | |
| 27 | const CONST: i32 = 2; | |
| 28 | } | |
| 29 | ||
| 30 | trait C: A + B { | |
| 31 | fn hello(&self) -> &'static str { | |
| 32 | "C" | |
| 33 | } | |
| 34 | type Assoc; | |
| 35 | type const CONST: i32; | |
| 36 | } | |
| 37 | impl<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 | ||
| 45 | trait D: B { | |
| 46 | fn hello(&self) -> &'static str { | |
| 47 | "D" | |
| 48 | } | |
| 49 | type Assoc; | |
| 50 | type const CONST: i32; | |
| 51 | } | |
| 52 | impl<T> D for T { | |
| 53 | type Assoc = i64; | |
| 54 | type const CONST: i32 = 4; | |
| 55 | } | |
| 56 | ||
| 57 | fn main() { | |
| 58 | ().hello(); | |
| 59 | //~^ ERROR multiple applicable items in scope | |
| 60 | check::<()>(); | |
| 61 | } | |
| 62 | ||
| 63 | fn 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 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/no-common-ancestor-2.rs:58:8 | |
| 3 | | | |
| 4 | LL | ().hello(); | |
| 5 | | ^^^^^ multiple `hello` found | |
| 6 | | | |
| 7 | note: 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 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: 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 | | | |
| 15 | LL | fn hello(&self) -> &'static str { | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | note: 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 | | | |
| 20 | LL | fn hello(&self) -> &'static str { | |
| 21 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 22 | note: 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 | | | |
| 25 | LL | fn hello(&self) -> &'static str { | |
| 26 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 27 | help: disambiguate the method for candidate #1 | |
| 28 | | | |
| 29 | LL - ().hello(); | |
| 30 | LL + A::hello(&()); | |
| 31 | | | |
| 32 | help: disambiguate the method for candidate #2 | |
| 33 | | | |
| 34 | LL - ().hello(); | |
| 35 | LL + B::hello(&()); | |
| 36 | | | |
| 37 | help: disambiguate the method for candidate #3 | |
| 38 | | | |
| 39 | LL - ().hello(); | |
| 40 | LL + C::hello(&()); | |
| 41 | | | |
| 42 | help: disambiguate the method for candidate #4 | |
| 43 | | | |
| 44 | LL - ().hello(); | |
| 45 | LL + D::hello(&()); | |
| 46 | | | |
| 47 | ||
| 48 | error[E0221]: ambiguous associated type `Assoc` in bounds of `T` | |
| 49 | --> $DIR/no-common-ancestor-2.rs:64:23 | |
| 50 | | | |
| 51 | LL | type Assoc; | |
| 52 | | ---------- ambiguous `Assoc` from `A` | |
| 53 | ... | |
| 54 | LL | type Assoc; | |
| 55 | | ---------- ambiguous `Assoc` from `B` | |
| 56 | ... | |
| 57 | LL | type Assoc; | |
| 58 | | ---------- ambiguous `Assoc` from `C` | |
| 59 | ... | |
| 60 | LL | type Assoc; | |
| 61 | | ---------- ambiguous `Assoc` from `D` | |
| 62 | ... | |
| 63 | LL | let _ = size_of::<T::Assoc>(); | |
| 64 | | ^^^^^^^^ ambiguous associated type `Assoc` | |
| 65 | | | |
| 66 | help: use fully-qualified syntax to disambiguate | |
| 67 | | | |
| 68 | LL - let _ = size_of::<T::Assoc>(); | |
| 69 | LL + let _ = size_of::<<T as A>::Assoc>(); | |
| 70 | | | |
| 71 | help: use fully-qualified syntax to disambiguate | |
| 72 | | | |
| 73 | LL - let _ = size_of::<T::Assoc>(); | |
| 74 | LL + let _ = size_of::<<T as C>::Assoc>(); | |
| 75 | | | |
| 76 | help: use fully-qualified syntax to disambiguate | |
| 77 | | | |
| 78 | LL - let _ = size_of::<T::Assoc>(); | |
| 79 | LL + let _ = size_of::<<T as B>::Assoc>(); | |
| 80 | | | |
| 81 | help: use fully-qualified syntax to disambiguate | |
| 82 | | | |
| 83 | LL - let _ = size_of::<T::Assoc>(); | |
| 84 | LL + let _ = size_of::<<T as D>::Assoc>(); | |
| 85 | | | |
| 86 | ||
| 87 | error[E0034]: multiple applicable items in scope | |
| 88 | --> $DIR/no-common-ancestor-2.rs:66:16 | |
| 89 | | | |
| 90 | LL | let _ = T::CONST; | |
| 91 | | ^^^^^ multiple `CONST` found | |
| 92 | | | |
| 93 | note: candidate #1 is defined in the trait `A` | |
| 94 | --> $DIR/no-common-ancestor-2.rs:11:5 | |
| 95 | | | |
| 96 | LL | const CONST: i32; | |
| 97 | | ^^^^^^^^^^^^^^^^ | |
| 98 | note: candidate #2 is defined in the trait `B` | |
| 99 | --> $DIR/no-common-ancestor-2.rs:23:5 | |
| 100 | | | |
| 101 | LL | const CONST: i32; | |
| 102 | | ^^^^^^^^^^^^^^^^ | |
| 103 | note: candidate #3 is defined in the trait `C` | |
| 104 | --> $DIR/no-common-ancestor-2.rs:35:5 | |
| 105 | | | |
| 106 | LL | type const CONST: i32; | |
| 107 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 108 | note: candidate #4 is defined in the trait `D` | |
| 109 | --> $DIR/no-common-ancestor-2.rs:50:5 | |
| 110 | | | |
| 111 | LL | type const CONST: i32; | |
| 112 | | ^^^^^^^^^^^^^^^^^^^^^ | |
| 113 | help: use fully-qualified syntax to disambiguate | |
| 114 | | | |
| 115 | LL - let _ = T::CONST; | |
| 116 | LL + let _ = <T as A>::CONST; | |
| 117 | | | |
| 118 | LL - let _ = T::CONST; | |
| 119 | LL + let _ = <T as B>::CONST; | |
| 120 | | | |
| 121 | LL - let _ = T::CONST; | |
| 122 | LL + let _ = <T as C>::CONST; | |
| 123 | | | |
| 124 | LL - let _ = T::CONST; | |
| 125 | LL + let _ = <T as D>::CONST; | |
| 126 | | | |
| 127 | ||
| 128 | error: aborting due to 3 previous errors | |
| 129 | ||
| 130 | Some errors have detailed explanations: E0034, E0221. | |
| 131 | For 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 | ||
| 4 | use std::mem::size_of; | |
| 5 | ||
| 6 | trait A { | |
| 7 | fn hello(&self) -> &'static str { | |
| 8 | "A" | |
| 9 | } | |
| 10 | type Assoc; | |
| 11 | const CONST: i32; | |
| 12 | } | |
| 13 | impl<T> A for T { | |
| 14 | type Assoc = i8; | |
| 15 | const CONST: i32 = 1; | |
| 16 | } | |
| 17 | ||
| 18 | trait B { | |
| 19 | fn hello(&self) -> &'static str { | |
| 20 | "B" | |
| 21 | } | |
| 22 | type Assoc; | |
| 23 | const CONST: i32; | |
| 24 | } | |
| 25 | impl<T> B for T { | |
| 26 | type Assoc = i16; | |
| 27 | const CONST: i32 = 2; | |
| 28 | } | |
| 29 | ||
| 30 | fn main() { | |
| 31 | ().hello(); | |
| 32 | //~^ ERROR multiple applicable items in scope | |
| 33 | check::<()>(); | |
| 34 | } | |
| 35 | ||
| 36 | fn 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 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/no-common-ancestor.rs:31:8 | |
| 3 | | | |
| 4 | LL | ().hello(); | |
| 5 | | ^^^^^ multiple `hello` found | |
| 6 | | | |
| 7 | note: candidate #1 is defined in an impl of the trait `A` for the type `T` | |
| 8 | --> $DIR/no-common-ancestor.rs:7:5 | |
| 9 | | | |
| 10 | LL | fn hello(&self) -> &'static str { | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 12 | note: candidate #2 is defined in an impl of the trait `B` for the type `T` | |
| 13 | --> $DIR/no-common-ancestor.rs:19:5 | |
| 14 | | | |
| 15 | LL | fn hello(&self) -> &'static str { | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | help: disambiguate the method for candidate #1 | |
| 18 | | | |
| 19 | LL - ().hello(); | |
| 20 | LL + A::hello(&()); | |
| 21 | | | |
| 22 | help: disambiguate the method for candidate #2 | |
| 23 | | | |
| 24 | LL - ().hello(); | |
| 25 | LL + B::hello(&()); | |
| 26 | | | |
| 27 | ||
| 28 | error[E0221]: ambiguous associated type `Assoc` in bounds of `T` | |
| 29 | --> $DIR/no-common-ancestor.rs:37:23 | |
| 30 | | | |
| 31 | LL | type Assoc; | |
| 32 | | ---------- ambiguous `Assoc` from `A` | |
| 33 | ... | |
| 34 | LL | type Assoc; | |
| 35 | | ---------- ambiguous `Assoc` from `B` | |
| 36 | ... | |
| 37 | LL | let _ = size_of::<T::Assoc>(); | |
| 38 | | ^^^^^^^^ ambiguous associated type `Assoc` | |
| 39 | | | |
| 40 | help: use fully-qualified syntax to disambiguate | |
| 41 | | | |
| 42 | LL - let _ = size_of::<T::Assoc>(); | |
| 43 | LL + let _ = size_of::<<T as A>::Assoc>(); | |
| 44 | | | |
| 45 | help: use fully-qualified syntax to disambiguate | |
| 46 | | | |
| 47 | LL - let _ = size_of::<T::Assoc>(); | |
| 48 | LL + let _ = size_of::<<T as B>::Assoc>(); | |
| 49 | | | |
| 50 | ||
| 51 | error[E0034]: multiple applicable items in scope | |
| 52 | --> $DIR/no-common-ancestor.rs:39:16 | |
| 53 | | | |
| 54 | LL | let _ = T::CONST; | |
| 55 | | ^^^^^ multiple `CONST` found | |
| 56 | | | |
| 57 | note: candidate #1 is defined in the trait `A` | |
| 58 | --> $DIR/no-common-ancestor.rs:11:5 | |
| 59 | | | |
| 60 | LL | const CONST: i32; | |
| 61 | | ^^^^^^^^^^^^^^^^ | |
| 62 | note: candidate #2 is defined in the trait `B` | |
| 63 | --> $DIR/no-common-ancestor.rs:23:5 | |
| 64 | | | |
| 65 | LL | const CONST: i32; | |
| 66 | | ^^^^^^^^^^^^^^^^ | |
| 67 | help: use fully-qualified syntax to disambiguate | |
| 68 | | | |
| 69 | LL - let _ = T::CONST; | |
| 70 | LL + let _ = <T as A>::CONST; | |
| 71 | | | |
| 72 | LL - let _ = T::CONST; | |
| 73 | LL + let _ = <T as B>::CONST; | |
| 74 | | | |
| 75 | ||
| 76 | error: aborting due to 3 previous errors | |
| 77 | ||
| 78 | Some errors have detailed explanations: E0034, E0221. | |
| 79 | For 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 | ||
| 6 | use std::mem::size_of; | |
| 7 | ||
| 8 | mod 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 | ||
| 22 | trait Supertrait { | |
| 23 | fn hello(&self) -> &'static str { | |
| 24 | "supertrait" | |
| 25 | } | |
| 26 | type Assoc; | |
| 27 | const CONST: i32; | |
| 28 | } | |
| 29 | impl<T> Supertrait for T { | |
| 30 | type Assoc = i8; | |
| 31 | const CONST: i32 = 1; | |
| 32 | } | |
| 33 | ||
| 34 | fn main() { | |
| 35 | assert_eq!(().hello(), "supertrait"); | |
| 36 | check::<()>(); | |
| 37 | } | |
| 38 | ||
| 39 | fn 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 | ||
| 8 | struct W<T>(T); | |
| 9 | ||
| 10 | trait Upstream { | |
| 11 | fn hello(&self) -> &'static str { | |
| 12 | "upstream" | |
| 13 | } | |
| 14 | } | |
| 15 | impl<T> Upstream for T {} | |
| 16 | ||
| 17 | trait Downstream: Upstream { | |
| 18 | fn hello(&self) -> &'static str { | |
| 19 | "downstream" | |
| 20 | } | |
| 21 | } | |
| 22 | impl<T> Downstream for W<T> where T: Foo {} | |
| 23 | ||
| 24 | trait Foo {} | |
| 25 | ||
| 26 | fn 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 | ||
| 9 | use std::mem::size_of; | |
| 10 | ||
| 11 | trait A { | |
| 12 | fn hello() -> &'static str { | |
| 13 | "A" | |
| 14 | } | |
| 15 | type Assoc; | |
| 16 | const CONST: i32; | |
| 17 | } | |
| 18 | impl<T> A for T { | |
| 19 | type Assoc = i8; | |
| 20 | const CONST: i32 = 1; | |
| 21 | } | |
| 22 | ||
| 23 | trait B: A { | |
| 24 | fn hello() -> &'static str { | |
| 25 | "B" | |
| 26 | } | |
| 27 | type Assoc; | |
| 28 | type const CONST: i32; | |
| 29 | } | |
| 30 | impl<T> B for T { | |
| 31 | type Assoc = i16; | |
| 32 | type const CONST: i32 = 2; | |
| 33 | } | |
| 34 | ||
| 35 | fn foo<T>() -> &'static str { | |
| 36 | T::hello() | |
| 37 | } | |
| 38 | ||
| 39 | fn assoc<T: B>() -> usize { | |
| 40 | size_of::<T::Assoc>() | |
| 41 | } | |
| 42 | ||
| 43 | fn konst<T: B>() -> i32 { | |
| 44 | T::CONST | |
| 45 | } | |
| 46 | ||
| 47 | fn 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 @@ |
| 1 | warning: a method with this name may be added to the standard library in the future | |
| 2 | --> $DIR/unstable.rs:26:19 | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` | |
| 12 | | | |
| 13 | LL + #![feature(downstream)] | |
| 14 | | | |
| 15 | ||
| 16 | warning: 1 warning emitted | |
| 17 |
tests/ui/supertrait-shadowing/unstable.off_shadowing.stderr created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | warning: a method with this name may be added to the standard library in the future | |
| 2 | --> $DIR/unstable.rs:26:19 | |
| 3 | | | |
| 4 | LL | 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 | |
| 11 | help: add `#![feature(downstream)]` to the crate attributes to enable `shadowed_stability::B::hello` | |
| 12 | | | |
| 13 | LL + #![feature(downstream)] | |
| 14 | | | |
| 15 | ||
| 16 | warning: 1 warning emitted | |
| 17 |
tests/ui/supertrait-shadowing/unstable.on_normal.stderr created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | error[E0034]: multiple applicable items in scope | |
| 2 | --> $DIR/unstable.rs:30:19 | |
| 3 | | | |
| 4 | LL | 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` | |
| 9 | help: disambiguate the method for candidate #1 | |
| 10 | | | |
| 11 | LL - assert_eq!(().hello(), "B"); | |
| 12 | LL + assert_eq!(shadowed_stability::A::hello(&()), "B"); | |
| 13 | | | |
| 14 | help: disambiguate the method for candidate #2 | |
| 15 | | | |
| 16 | LL - assert_eq!(().hello(), "B"); | |
| 17 | LL + assert_eq!(shadowed_stability::B::hello(&()), "B"); | |
| 18 | | | |
| 19 | ||
| 20 | error: aborting due to 1 previous error | |
| 21 | ||
| 22 | For 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 | ||
| 21 | extern crate shadowed_stability; | |
| 22 | use shadowed_stability::*; | |
| 23 | ||
| 24 | fn 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 | ||
| 5 | fn 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 @@ |
| 1 | error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` | |
| 2 | --> $DIR/tuple-bracket-index-suggest-dot.rs:8:16 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 9 | error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` | |
| 10 | --> $DIR/tuple-bracket-index-suggest-dot.rs:13:16 | |
| 11 | | | |
| 12 | LL | let _ = tup[i]; | |
| 13 | | ^^^ | |
| 14 | | | |
| 15 | = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. | |
| 16 | ||
| 17 | error[E0608]: cannot index into a value of type `({integer},)` | |
| 18 | --> $DIR/tuple-bracket-index-suggest-dot.rs:18:16 | |
| 19 | | | |
| 20 | LL | let _ = tup[3]; | |
| 21 | | ^^^ | |
| 22 | | | |
| 23 | = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. | |
| 24 | ||
| 25 | error: aborting due to 3 previous errors | |
| 26 | ||
| 27 | For 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 | ||
| 4 | use std::ptr; | |
| 5 | ||
| 6 | fn 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 @@ |
| 1 | error[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 | | | |
| 4 | LL | (&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 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0133`. |