diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 333cfce47abe2..5258f179d95d2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3553,6 +3553,19 @@ impl VisibilityKind { } } +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub struct ImplRestriction { + pub kind: RestrictionKind, + pub span: Span, + pub tokens: Option, +} + +#[derive(Clone, Encodable, Decodable, Debug, Walkable)] +pub enum RestrictionKind { + Unrestricted, + Restricted { path: Box, id: NodeId, shorthand: bool }, +} + /// Field definition in a struct, variant or union. /// /// E.g., `bar: usize` as in `struct Foo { bar: usize }`. @@ -3752,6 +3765,7 @@ pub struct Trait { pub constness: Const, pub safety: Safety, pub is_auto: IsAuto, + pub impl_restriction: ImplRestriction, pub ident: Ident, pub generics: Generics, #[visitable(extra = BoundKind::SuperTraits)] diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 3d2477e5f033f..73bfa0ba7ab6d 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -8,8 +8,8 @@ use std::marker::PhantomData; use crate::tokenstream::LazyAttrTokenStream; use crate::{ Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField, - FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind, - Ty, Variant, Visibility, WherePredicate, + FieldDef, ForeignItem, GenericParam, ImplRestriction, Item, NodeId, Param, Pat, PatField, Path, + Stmt, StmtKind, Ty, Variant, Visibility, WherePredicate, }; /// A trait for AST nodes having an ID. @@ -97,7 +97,19 @@ macro_rules! impl_has_tokens_none { }; } -impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility); +impl_has_tokens!( + AssocItem, + AttrItem, + Block, + Expr, + ForeignItem, + Item, + Pat, + Path, + Ty, + Visibility, + ImplRestriction +); impl_has_tokens_none!( Arm, ExprField, @@ -242,7 +254,7 @@ impl_has_attrs!( Variant, WherePredicate, ); -impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility); +impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility, ImplRestriction); impl HasAttrs for Box { const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::SUPPORTS_CUSTOM_INNER_ATTRS; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ff389607457d4..e7b492a9c1db5 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -467,6 +467,7 @@ macro_rules! common_visitor_and_walkers { RangeEnd, RangeSyntax, Recovered, + RestrictionKind, Safety, StaticItem, StrLit, @@ -595,6 +596,7 @@ macro_rules! common_visitor_and_walkers { fn visit_poly_trait_ref(PolyTraitRef); fn visit_precise_capturing_arg(PreciseCapturingArg); fn visit_qself(QSelf); + fn visit_impl_restriction(ImplRestriction); fn visit_trait_ref(TraitRef); fn visit_ty_pat(TyPat); fn visit_ty(Ty); @@ -1117,6 +1119,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_poly_trait_ref(PolyTraitRef); pub fn walk_precise_capturing_arg(PreciseCapturingArg); pub fn walk_qself(QSelf); + pub fn walk_impl_restriction(ImplRestriction); pub fn walk_trait_ref(TraitRef); pub fn walk_ty_pat(TyPat); pub fn walk_ty(Ty); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d853a5d0558e1..c17eb7c633d1b 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -512,6 +512,8 @@ impl<'hir> LoweringContext<'_, 'hir> { constness, is_auto, safety, + // FIXME(impl_restrictions): lower to HIR + impl_restriction: _, ident, generics, bounds, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index c955ada05b09a..72679d7456659 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -590,6 +590,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(coroutines, "coroutine syntax is experimental"); gate_all!(const_block_items, "const block items are experimental"); gate_all!(final_associated_functions, "`final` on trait functions is experimental"); + gate_all!(impl_restriction, "`impl` restrictions are experimental"); if !visitor.features.never_patterns() { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index 74ed0405498d9..25b398b849246 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -80,6 +80,10 @@ pub fn vis_to_string(v: &ast::Visibility) -> String { State::new().vis_to_string(v) } +pub fn impl_restriction_to_string(r: &ast::ImplRestriction) -> String { + State::new().impl_restriction_to_string(r) +} + pub fn meta_list_item_to_string(li: &ast::MetaItemInner) -> String { State::new().meta_list_item_to_string(li) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index f4168301bc5df..1ca0715606181 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1110,6 +1110,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere Self::to_string(|s| s.print_visibility(v)) } + fn impl_restriction_to_string(&self, r: &ast::ImplRestriction) -> String { + Self::to_string(|s| s.print_impl_restriction(r)) + } + fn block_to_string(&self, blk: &ast::Block) -> String { Self::to_string(|s| { let (cb, ib) = s.head(""); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 57e105010343c..3407feb3dcc3a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -365,6 +365,7 @@ impl<'a> State<'a> { constness, safety, is_auto, + impl_restriction, ident, generics, bounds, @@ -375,6 +376,7 @@ impl<'a> State<'a> { self.print_constness(*constness); self.print_safety(*safety); self.print_is_auto(*is_auto); + self.print_impl_restriction(impl_restriction); self.word_nbsp("trait"); self.print_ident(*ident); self.print_generic_params(&generics.params); @@ -483,6 +485,20 @@ impl<'a> State<'a> { } } + pub(crate) fn print_impl_restriction(&mut self, impl_restriction: &ast::ImplRestriction) { + match &impl_restriction.kind { + ast::RestrictionKind::Restricted { path, shorthand, .. } => { + let path = Self::to_string(|s| s.print_path(path, false, 0)); + if *shorthand { + self.word_nbsp(format!("impl({path})")) + } else { + self.word_nbsp(format!("impl(in {path})")) + } + } + ast::RestrictionKind::Unrestricted => {} + } + } + fn print_defaultness(&mut self, defaultness: ast::Defaultness) { if let ast::Defaultness::Default(_) = defaultness { self.word_nbsp("default"); diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index fc5c634d95709..79a3214568082 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -10,9 +10,9 @@ use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; -use rustc_codegen_ssa::back::write::{CompiledModules, produce_final_output_artifacts}; +use rustc_codegen_ssa::back::write::produce_final_output_artifacts; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; @@ -54,7 +54,6 @@ impl HashStable for OngoingModuleCodegen { pub(crate) struct OngoingCodegen { modules: Vec, allocator_module: Option, - crate_info: CrateInfo, concurrency_limiter: ConcurrencyLimiter, } @@ -63,7 +62,7 @@ impl OngoingCodegen { self, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { let mut work_products = FxIndexMap::default(); let mut modules = vec![]; let disable_incr_cache = disable_incr_cache(); @@ -126,15 +125,7 @@ impl OngoingCodegen { produce_final_output_artifacts(sess, &compiled_modules, outputs); - ( - CodegenResults { - crate_info: self.crate_info, - - modules: compiled_modules.modules, - allocator_module: compiled_modules.allocator_module, - }, - work_products, - ) + (compiled_modules, work_products) } } @@ -483,13 +474,6 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option { } pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { - // FIXME handle `-Ctarget-cpu=native` - let target_cpu = match tcx.sess.opts.cg.target_cpu { - Some(ref name) => name, - None => tcx.sess.target.cpu.as_ref(), - } - .to_owned(); - let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; if tcx.dep_graph.is_fully_enabled() { @@ -549,7 +533,6 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { Box::new(OngoingCodegen { modules, allocator_module, - crate_info: CrateInfo::new(tcx, target_cpu), concurrency_limiter: concurrency_limiter.0, }) } diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 3a8ca25a5fc00..9bbc338a8e07c 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -16,13 +16,14 @@ use crate::debuginfo::TypeDebugContext; use crate::prelude::*; use crate::unwind_module::UnwindModule; -fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option) { - let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); - +fn create_jit_module( + tcx: TyCtxt<'_>, + crate_info: &CrateInfo, +) -> (UnwindModule, Option) { let isa = crate::build_isa(tcx.sess, true); let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); - jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); + jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info.clone())); let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name"); @@ -32,14 +33,14 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option, jit_args: Vec) -> ! { +pub(crate) fn run_jit(tcx: TyCtxt<'_>, crate_info: &CrateInfo, jit_args: Vec) -> ! { if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) { tcx.dcx().fatal("can't jit non-executable crate"); } let output_filenames = tcx.output_filenames(()); let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess); - let (mut jit_module, mut debug_context) = create_jit_module(tcx); + let (mut jit_module, mut debug_context) = create_jit_module(tcx, crate_info); let mut cached_context = Context::new(); let cgus = tcx.collect_and_partition_mono_items(()).codegen_units; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 7bab07def63d1..82c2e91b4b0f7 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -40,7 +40,7 @@ use std::sync::Arc; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, TargetConfig}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; @@ -200,12 +200,21 @@ impl CodegenBackend for CraneliftCodegenBackend { println!("Cranelift version: {}", cranelift_codegen::VERSION); } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { + fn target_cpu(&self, sess: &Session) -> String { + // FIXME handle `-Ctarget-cpu=native` + match sess.opts.cg.target_cpu { + Some(ref name) => name, + None => sess.target.cpu.as_ref(), + } + .to_owned() + } + + fn codegen_crate(&self, tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, config.jit_args.clone()); + driver::jit::run_jit(tcx, _crate_info, config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -219,7 +228,7 @@ impl CodegenBackend for CraneliftCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { ongoing_codegen.downcast::().unwrap().join(sess, outputs) } } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index afb07f57ab7a7..529a5085c30f4 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -88,7 +88,7 @@ use rustc_codegen_ssa::back::write::{ use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; @@ -287,11 +287,12 @@ impl CodegenBackend for GccCodegenBackend { |tcx, ()| gcc_util::global_gcc_features(tcx.sess) } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { - let target_cpu = target_cpu(tcx.sess); - let res = codegen_crate(self.clone(), tcx, target_cpu.to_string()); + fn target_cpu(&self, sess: &Session) -> String { + target_cpu(sess).to_owned() + } - Box::new(res) + fn codegen_crate(&self, tcx: TyCtxt<'_>, crate_info: &CrateInfo) -> Box { + Box::new(codegen_crate(self.clone(), tcx, crate_info)) } fn join_codegen( @@ -299,7 +300,7 @@ impl CodegenBackend for GccCodegenBackend { ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 7120ee0afec96..c03b0ac9157a8 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -33,7 +33,7 @@ use rustc_codegen_ssa::back::write::{ TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; +use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; @@ -360,12 +360,12 @@ impl CodegenBackend for LlvmCodegenBackend { will_not_use_fallback } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { - Box::new(rustc_codegen_ssa::base::codegen_crate( - LlvmCodegenBackend(()), - tcx, - crate::llvm_util::target_cpu(tcx.sess).to_string(), - )) + fn target_cpu(&self, sess: &Session) -> String { + crate::llvm_util::target_cpu(sess).to_string() + } + + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box { + Box::new(rustc_codegen_ssa::base::codegen_crate(LlvmCodegenBackend(()), tcx, crate_info)) } fn join_codegen( @@ -373,8 +373,8 @@ impl CodegenBackend for LlvmCodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { - let (codegen_results, work_products) = ongoing_codegen + ) -> (CompiledModules, FxIndexMap) { + let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") .join(sess); @@ -386,13 +386,14 @@ impl CodegenBackend for LlvmCodegenBackend { }); } - (codegen_results, work_products) + (compiled_modules, work_products) } fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { @@ -405,7 +406,8 @@ impl CodegenBackend for LlvmCodegenBackend { link_binary( sess, &LlvmArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 388503c720532..11bee7f865f6c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -60,7 +60,7 @@ use super::rpath::{self, RPathConfig}; use super::{apple, versioned_llvm_target}; use crate::base::needs_allocator_shim_for_linking; use crate::{ - CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file, + CompiledModule, CompiledModules, CrateInfo, NativeLib, errors, looks_like_rust_object_file, }; pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { @@ -76,7 +76,8 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) { pub fn link_binary( sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, codegen_backend: &'static str, @@ -84,7 +85,7 @@ pub fn link_binary( let _timer = sess.timer("link_binary"); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); let mut tempfiles_for_stdout_output: Vec = Vec::new(); - for &crate_type in &codegen_results.crate_info.crate_types { + for &crate_type in &crate_info.crate_types { // Ignore executable crates if we have -Z no-codegen, as they will error. if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen()) && !output_metadata @@ -98,25 +99,20 @@ pub fn link_binary( } sess.time("link_binary_check_files_are_writeable", || { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { + for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { check_file_is_writeable(obj, sess); } }); if outputs.outputs.should_link() { - let output = out_filename( - sess, - crate_type, - outputs, - codegen_results.crate_info.local_crate_name, - ); + let output = out_filename(sess, crate_type, outputs, crate_info.local_crate_name); let tmpdir = TempDirBuilder::new() .prefix("rustc") .tempdir_in(output.parent().unwrap_or_else(|| Path::new("."))) .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); - let crate_name = format!("{}", codegen_results.crate_info.local_crate_name); + let crate_name = format!("{}", crate_info.local_crate_name); let out_filename = output.file_for_writing( outputs, OutputType::Exe, @@ -130,7 +126,8 @@ pub fn link_binary( link_rlib( sess, archive_builder_builder, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, RlibFlavor::Normal, &path, @@ -141,7 +138,8 @@ pub fn link_binary( link_staticlib( sess, archive_builder_builder, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, &out_filename, &path, @@ -153,7 +151,8 @@ pub fn link_binary( archive_builder_builder, crate_type, &out_filename, - &codegen_results, + &compiled_modules, + &crate_info, &metadata, path.as_ref(), codegen_backend, @@ -218,7 +217,7 @@ pub fn link_binary( |module: &CompiledModule| maybe_remove_temps_from_module(false, false, module); // Otherwise, always remove the allocator module temporaries. - if let Some(ref allocator_module) = codegen_results.allocator_module { + if let Some(ref allocator_module) = compiled_modules.allocator_module { remove_temps_from_module(allocator_module); } @@ -237,7 +236,7 @@ pub fn link_binary( let (preserve_objects, preserve_dwarf_objects) = preserve_objects_for_their_debuginfo(sess); debug!(?preserve_objects, ?preserve_dwarf_objects); - for module in &codegen_results.modules { + for module in &compiled_modules.modules { maybe_remove_temps_from_module(preserve_objects, preserve_dwarf_objects, module); } }); @@ -298,7 +297,8 @@ pub fn each_linked_rlib( fn link_rlib<'a>( sess: &'a Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, flavor: RlibFlavor, tmpdir: &MaybeTempDir, @@ -327,7 +327,7 @@ fn link_rlib<'a>( RlibFlavor::StaticlibBase => None, }; - for m in &codegen_results.modules { + for m in &compiled_modules.modules { if let Some(obj) = m.object.as_ref() { ab.add_file(obj); } @@ -340,7 +340,7 @@ fn link_rlib<'a>( match flavor { RlibFlavor::Normal => {} RlibFlavor::StaticlibBase => { - let obj = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()); + let obj = compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref()); if let Some(obj) = obj { ab.add_file(obj); } @@ -366,7 +366,7 @@ fn link_rlib<'a>( // feature then we'll need to figure out how to record what objects were // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. - for lib in codegen_results.crate_info.used_libraries.iter() { + for lib in crate_info.used_libraries.iter() { let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; @@ -394,7 +394,7 @@ fn link_rlib<'a>( for output_path in raw_dylib::create_raw_dylib_dll_import_libs( sess, archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), tmpdir.as_ref(), true, ) { @@ -457,7 +457,8 @@ fn link_rlib<'a>( fn link_staticlib( sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, out_filename: &Path, tempdir: &MaybeTempDir, @@ -466,72 +467,67 @@ fn link_staticlib( let mut ab = link_rlib( sess, archive_builder_builder, - codegen_results, + compiled_modules, + crate_info, metadata, RlibFlavor::StaticlibBase, tempdir, ); let mut all_native_libs = vec![]; - let res = each_linked_rlib( - &codegen_results.crate_info, - Some(CrateType::StaticLib), - &mut |cnum, path| { - let lto = are_upstream_rust_objects_already_included(sess) - && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); - - let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter(); - let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); - let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); - - let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); - ab.add_archive( - path, - Box::new(move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } + let res = each_linked_rlib(crate_info, Some(CrateType::StaticLib), &mut |cnum, path| { + let lto = are_upstream_rust_objects_already_included(sess) + && !ignored_for_lto(sess, crate_info, cnum); - // Don't include Rust objects if LTO is enabled - if lto && looks_like_rust_object_file(fname) { - return true; - } + let native_libs = crate_info.native_libraries[&cnum].iter(); + let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib)); + let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect(); - // Skip objects for bundled libs. - if bundled_libs.contains(&Symbol::intern(fname)) { - return true; - } + let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect(); + ab.add_archive( + path, + Box::new(move |fname: &str| { + // Ignore metadata files, no matter the name. + if fname == METADATA_FILENAME { + return true; + } - false - }), - ) - .unwrap(); + // Don't include Rust objects if LTO is enabled + if lto && looks_like_rust_object_file(fname) { + return true; + } - archive_builder_builder - .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs) - .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); + // Skip objects for bundled libs. + if bundled_libs.contains(&Symbol::intern(fname)) { + return true; + } - for filename in relevant_libs.iter() { - let joined = tempdir.as_ref().join(filename.as_str()); - let path = joined.as_path(); - ab.add_archive(path, Box::new(|_| false)).unwrap(); - } + false + }), + ) + .unwrap(); - all_native_libs - .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); - }, - ); + archive_builder_builder + .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs) + .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); + + for filename in relevant_libs.iter() { + let joined = tempdir.as_ref().join(filename.as_str()); + let path = joined.as_path(); + ab.add_archive(path, Box::new(|_| false)).unwrap(); + } + + all_native_libs.extend(crate_info.native_libraries[&cnum].iter().cloned()); + }); if let Err(e) = res { sess.dcx().emit_fatal(e); } ab.build(out_filename); - let crates = codegen_results.crate_info.used_crates.iter(); + let crates = crate_info.used_crates.iter(); - let fmts = codegen_results - .crate_info + let fmts = crate_info .dependency_formats .get(&CrateType::StaticLib) .expect("no dependency formats for staticlib"); @@ -541,8 +537,8 @@ fn link_staticlib( let Some(Linkage::Dynamic) = fmts.get(cnum) else { continue; }; - let crate_name = codegen_results.crate_info.crate_name[&cnum]; - let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; + let crate_name = crate_info.crate_name[&cnum]; + let used_crate_source = &crate_info.used_crate_source[&cnum]; if let Some(path) = &used_crate_source.dylib { all_rust_dylibs.push(&**path); } else if used_crate_source.rmeta.is_some() { @@ -552,7 +548,7 @@ fn link_staticlib( } } - all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries); + all_native_libs.extend_from_slice(&crate_info.used_libraries); for print in &sess.opts.prints { if print.kind == PrintKind::NativeStaticLibs { @@ -563,7 +559,12 @@ fn link_staticlib( /// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a /// DWARF package. -fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out_filename: &Path) { +fn link_dwarf_object( + sess: &Session, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, + executable_out_filename: &Path, +) { let mut dwp_out_filename = executable_out_filename.to_path_buf().into_os_string(); dwp_out_filename.push(".dwp"); debug!(?dwp_out_filename, ?executable_out_filename); @@ -604,20 +605,21 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out // Input objs contain .o/.dwo files from the current crate. match sess.opts.unstable_opts.split_dwarf_kind { SplitDwarfKind::Single => { - for input_obj in cg_results.modules.iter().filter_map(|m| m.object.as_ref()) { + for input_obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { package.add_input_object(input_obj)?; } } SplitDwarfKind::Split => { - for input_obj in cg_results.modules.iter().filter_map(|m| m.dwarf_object.as_ref()) { + for input_obj in + compiled_modules.modules.iter().filter_map(|m| m.dwarf_object.as_ref()) + { package.add_input_object(input_obj)?; } } } // Input rlibs contain .o/.dwo files from dependencies. - let input_rlibs = cg_results - .crate_info + let input_rlibs = crate_info .used_crate_source .items() .filter_map(|(_, csource)| csource.rlib.as_ref()) @@ -679,7 +681,8 @@ fn link_natively( archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, out_filename: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, tmpdir: &Path, codegen_backend: &'static str, @@ -705,7 +708,8 @@ fn link_natively( crate_type, tmpdir, temp_filename, - codegen_results, + compiled_modules, + crate_info, metadata, self_contained_components, codegen_backend, @@ -936,7 +940,7 @@ fn link_natively( } } - let level = codegen_results.crate_info.lint_levels.linker_messages; + let level = crate_info.lint_levels.linker_messages; let lint = |msg| { diag_lint_level(sess, LINKER_MESSAGES, level, None, LinkerOutput { inner: msg }); }; @@ -1013,7 +1017,9 @@ fn link_natively( // We cannot rely on the .o paths in the executable because they may have been // remapped by --remap-path-prefix and therefore invalid, so we need to provide // the .o/.dwo paths explicitly. - SplitDebuginfo::Packed => link_dwarf_object(sess, codegen_results, out_filename), + SplitDebuginfo::Packed => { + link_dwarf_object(sess, compiled_modules, crate_info, out_filename) + } } let strip = sess.opts.cg.strip; @@ -1908,11 +1914,11 @@ fn add_late_link_args( sess: &Session, flavor: LinkerFlavor, crate_type: CrateType, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, ) { let any_dynamic_crate = crate_type == CrateType::Dylib || crate_type == CrateType::Sdylib - || codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| { + || crate_info.dependency_formats.iter().any(|(ty, list)| { *ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic) }); if any_dynamic_crate { @@ -2074,8 +2080,8 @@ fn add_linked_symbol_object( } /// Add object files containing code from the current crate. -fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &CodegenResults) { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { +fn add_local_crate_regular_objects(cmd: &mut dyn Linker, compiled_modules: &CompiledModules) { + for obj in compiled_modules.modules.iter().filter_map(|m| m.object.as_ref()) { cmd.add_object(obj); } } @@ -2083,12 +2089,13 @@ fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &Codeg /// Add object files for allocator code linked once for the whole crate tree. fn add_local_crate_allocator_objects( cmd: &mut dyn Linker, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, crate_type: CrateType, ) { - if needs_allocator_shim_for_linking(&codegen_results.crate_info.dependency_formats, crate_type) - { - if let Some(obj) = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()) + if needs_allocator_shim_for_linking(&crate_info.dependency_formats, crate_type) { + if let Some(obj) = + compiled_modules.allocator_module.as_ref().and_then(|m| m.object.as_ref()) { cmd.add_object(obj); } @@ -2102,7 +2109,7 @@ fn add_local_crate_metadata_objects( archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, tmpdir: &Path, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, metadata: &EncodedMetadata, ) { // When linking a dynamic library, we put the metadata into a section of the @@ -2112,7 +2119,7 @@ fn add_local_crate_metadata_objects( let data = archive_builder_builder.create_dylib_metadata_wrapper( sess, &metadata, - &codegen_results.crate_info.metadata_symbol, + &crate_info.metadata_symbol, ); let obj = emit_wrapper_file(sess, &data, tmpdir, "rmeta.o"); @@ -2157,7 +2164,7 @@ fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { fn add_rpath_args( cmd: &mut dyn Linker, sess: &Session, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, out_filename: &Path, ) { if !sess.target.has_rpath { @@ -2168,11 +2175,10 @@ fn add_rpath_args( // where extern libraries might live, based on the // add_lib_search_paths if sess.opts.cg.rpath { - let libs = codegen_results - .crate_info + let libs = crate_info .used_crates .iter() - .filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref()) + .filter_map(|cnum| crate_info.used_crate_source[cnum].dylib.as_deref()) .collect::>(); let rpath_config = RPathConfig { libs: &*libs, @@ -2265,7 +2271,8 @@ fn linker_with_args( crate_type: CrateType, tmpdir: &Path, out_filename: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, self_contained_components: LinkSelfContainedComponents, codegen_backend: &'static str, @@ -2276,17 +2283,17 @@ fn linker_with_args( path, flavor, self_contained_components.are_any_components_enabled(), - &codegen_results.crate_info.target_cpu, + &crate_info.target_cpu, codegen_backend, ); let link_output_kind = link_output_kind(sess, crate_type); - let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + let mut export_symbols = crate_info.exported_symbols[&crate_type].clone(); if crate_type == CrateType::Cdylib { let mut seen = FxHashSet::default(); - for lib in &codegen_results.crate_info.used_libraries { + for lib in &crate_info.used_libraries { if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind && seen.insert((lib.name, lib.verbatim)) { @@ -2320,12 +2327,7 @@ fn linker_with_args( // Pre-link CRT objects. add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained_crt_objects); - add_linked_symbol_object( - cmd, - sess, - tmpdir, - &codegen_results.crate_info.linked_symbols[&crate_type], - ); + add_linked_symbol_object(cmd, sess, tmpdir, &crate_info.linked_symbols[&crate_type]); // Sanitizer libraries. add_sanitizer_libraries(sess, flavor, crate_type, cmd); @@ -2357,17 +2359,17 @@ fn linker_with_args( // link line. And finally upstream native libraries can't depend on anything // in this DAG so far because they can only depend on other native libraries // and such dependencies are also required to be specified. - add_local_crate_regular_objects(cmd, codegen_results); + add_local_crate_regular_objects(cmd, compiled_modules); add_local_crate_metadata_objects( cmd, sess, archive_builder_builder, crate_type, tmpdir, - codegen_results, + crate_info, metadata, ); - add_local_crate_allocator_objects(cmd, codegen_results, crate_type); + add_local_crate_allocator_objects(cmd, compiled_modules, crate_info, crate_type); // Avoid linking to dynamic libraries unless they satisfy some undefined symbols // at the point at which they are specified on the command line. @@ -2384,7 +2386,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, link_output_kind, ); @@ -2394,7 +2396,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, crate_type, tmpdir, link_output_kind, @@ -2405,7 +2407,7 @@ fn linker_with_args( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, link_output_kind, ); @@ -2428,7 +2430,7 @@ fn linker_with_args( for output_path in raw_dylib::create_raw_dylib_dll_import_libs( sess, archive_builder_builder, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), tmpdir, true, ) { @@ -2437,7 +2439,7 @@ fn linker_with_args( } else { for (link_path, as_needed) in raw_dylib::create_raw_dylib_elf_stub_shared_objects( sess, - codegen_results.crate_info.used_libraries.iter(), + crate_info.used_libraries.iter(), &raw_dylib_dir, ) { // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. @@ -2448,16 +2450,14 @@ fn linker_with_args( // they are used within inlined functions or instantiated generic functions. We do this *after* // handling the raw-dylib symbols in the current crate to make sure that those are chosen first // by the linker. - let dependency_linkage = codegen_results - .crate_info + let dependency_linkage = crate_info .dependency_formats .get(&crate_type) .expect("failed to find crate type in dependency format list"); // We sort the libraries below #[allow(rustc::potential_query_instability)] - let mut native_libraries_from_nonstatics = codegen_results - .crate_info + let mut native_libraries_from_nonstatics = crate_info .native_libraries .iter() .filter_map(|(&cnum, libraries)| { @@ -2499,7 +2499,7 @@ fn linker_with_args( // FIXME: Built-in target specs occasionally use this for linking system libraries, // eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)` // and remove the option. - add_late_link_args(cmd, sess, flavor, crate_type, codegen_results); + add_late_link_args(cmd, sess, flavor, crate_type, crate_info); // ------------ Arbitrary order-independent options ------------ @@ -2512,7 +2512,7 @@ fn linker_with_args( self_contained_components, flavor, crate_type, - codegen_results, + crate_info, out_filename, tmpdir, ); @@ -2552,7 +2552,7 @@ fn add_order_independent_options( self_contained_components: LinkSelfContainedComponents, flavor: LinkerFlavor, crate_type: CrateType, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, out_filename: &Path, tmpdir: &Path, ) { @@ -2597,18 +2597,15 @@ fn add_order_independent_options( "--target", &versioned_llvm_target(sess), "--target-cpu", - &codegen_results.crate_info.target_cpu, + &crate_info.target_cpu, ]); - if codegen_results.crate_info.target_features.len() > 0 { - cmd.link_arg(&format!( - "--target-feature={}", - &codegen_results.crate_info.target_features.join(",") - )); + if crate_info.target_features.len() > 0 { + cmd.link_arg(&format!("--target-feature={}", &crate_info.target_features.join(","))); } } else if flavor == LinkerFlavor::Ptx { - cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); + cmd.link_args(&["--fallback-arch", &crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { - cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]); + cmd.link_args(&["--cpu", &crate_info.target_cpu]); if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features] .into_iter() .find(|feat| !feat.is_empty()) @@ -2625,7 +2622,7 @@ fn add_order_independent_options( if crate_type == CrateType::Executable && sess.target.is_like_windows - && let Some(s) = &codegen_results.crate_info.windows_subsystem + && let Some(s) = &crate_info.windows_subsystem { cmd.windows_subsystem(*s); } @@ -2653,8 +2650,8 @@ fn add_order_independent_options( let natvis_visualizers = collect_natvis_visualizers( tmpdir, sess, - &codegen_results.crate_info.local_crate_name, - &codegen_results.crate_info.natvis_debugger_visualizers, + &crate_info.local_crate_name, + &crate_info.natvis_debugger_visualizers, ); // Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker. @@ -2679,7 +2676,7 @@ fn add_order_independent_options( cmd.ehcont_guard(); } - add_rpath_args(cmd, sess, codegen_results, out_filename); + add_rpath_args(cmd, sess, crate_info, out_filename); } // Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths. @@ -2713,7 +2710,7 @@ fn add_native_libs_from_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, bundled_libs: &FxIndexSet, cnum: CrateNum, @@ -2730,15 +2727,15 @@ fn add_native_libs_from_crate( if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() { // If rlib contains native libs as archives, unpack them to tmpdir. - let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); + let rlib = crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); archive_builder_builder .extract_bundled_libs(rlib, tmpdir, bundled_libs) .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); } let native_libs = match cnum { - LOCAL_CRATE => &codegen_results.crate_info.used_libraries, - _ => &codegen_results.crate_info.native_libraries[&cnum], + LOCAL_CRATE => &crate_info.used_libraries, + _ => &crate_info.native_libraries[&cnum], }; let mut last = (None, NativeLibKind::Unspecified, false); @@ -2814,7 +2811,7 @@ fn add_local_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, ) { @@ -2825,7 +2822,7 @@ fn add_local_native_libraries( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &Default::default(), LOCAL_CRATE, @@ -2839,7 +2836,7 @@ fn add_upstream_rust_crates( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, crate_type: CrateType, tmpdir: &Path, link_output_kind: LinkOutputKind, @@ -2851,8 +2848,7 @@ fn add_upstream_rust_crates( // Linking to a rlib involves just passing it to the linker (the linker // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. - let data = codegen_results - .crate_info + let data = crate_info .dependency_formats .get(&crate_type) .expect("failed to find crate type in dependency format list"); @@ -2866,7 +2862,7 @@ fn add_upstream_rust_crates( cmd.link_or_cc_arg("-bnoipath"); } - for &cnum in &codegen_results.crate_info.used_crates { + for &cnum in &crate_info.used_crates { // We may not pass all crates through to the linker. Some crates may appear statically in // an existing dylib, meaning we'll pick up all the symbols from the dylib. // We must always link crates `compiler_builtins` and `profiler_builtins` statically. @@ -2875,14 +2871,14 @@ fn add_upstream_rust_crates( let linkage = data[cnum]; let link_static_crate = linkage == Linkage::Static || linkage == Linkage::IncludedFromDylib - && (codegen_results.crate_info.compiler_builtins == Some(cnum) - || codegen_results.crate_info.profiler_runtime == Some(cnum)); + && (crate_info.compiler_builtins == Some(cnum) + || crate_info.profiler_runtime == Some(cnum)); let mut bundled_libs = Default::default(); match linkage { Linkage::Static | Linkage::IncludedFromDylib | Linkage::NotLinked => { if link_static_crate { - bundled_libs = codegen_results.crate_info.native_libraries[&cnum] + bundled_libs = crate_info.native_libraries[&cnum] .iter() .filter_map(|lib| lib.filename) .collect(); @@ -2890,7 +2886,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, cnum, &bundled_libs, @@ -2898,7 +2894,7 @@ fn add_upstream_rust_crates( } } Linkage::Dynamic => { - let src = &codegen_results.crate_info.used_crate_source[&cnum]; + let src = &crate_info.used_crate_source[&cnum]; add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap()); } } @@ -2918,7 +2914,7 @@ fn add_upstream_rust_crates( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &bundled_libs, cnum, @@ -2933,11 +2929,11 @@ fn add_upstream_native_libraries( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, link_output_kind: LinkOutputKind, ) { - for &cnum in &codegen_results.crate_info.used_crates { + for &cnum in &crate_info.used_crates { // Static libraries are not linked here, they are linked in `add_upstream_rust_crates`. // FIXME: Merge this function to `add_upstream_rust_crates` so that all native libraries // are linked together with their respective upstream crates, and in their originally @@ -2956,7 +2952,7 @@ fn add_upstream_native_libraries( cmd, sess, archive_builder_builder, - codegen_results, + crate_info, tmpdir, &Default::default(), cnum, @@ -3021,19 +3017,18 @@ fn add_static_crate( cmd: &mut dyn Linker, sess: &Session, archive_builder_builder: &dyn ArchiveBuilderBuilder, - codegen_results: &CodegenResults, + crate_info: &CrateInfo, tmpdir: &Path, cnum: CrateNum, bundled_lib_file_names: &FxIndexSet, ) { - let src = &codegen_results.crate_info.used_crate_source[&cnum]; + let src = &crate_info.used_crate_source[&cnum]; let cratepath = src.rlib.as_ref().unwrap(); let mut link_upstream = |path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false); - if !are_upstream_rust_objects_already_included(sess) - || ignored_for_lto(sess, &codegen_results.crate_info, cnum) + if !are_upstream_rust_objects_already_included(sess) || ignored_for_lto(sess, crate_info, cnum) { link_upstream(cratepath); return; @@ -3048,8 +3043,7 @@ fn add_static_crate( let canonical_name = name.replace('-', "_"); let upstream_rust_objects_already_included = are_upstream_rust_objects_already_included(sess); - let is_builtins = - sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum); + let is_builtins = sess.target.no_builtins || !crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); if let Err(error) = archive.add_archive( diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 9898c1296142a..0d210eacf9a83 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -42,7 +42,7 @@ use crate::back::lto::check_lto_allowed; use crate::errors::ErrorCreatingRemarkDir; use crate::traits::*; use crate::{ - CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, + CachedModuleCodegen, CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, ModuleKind, errors, }; @@ -394,16 +394,8 @@ fn generate_thin_lto_work( .collect() } -pub struct CompiledModules { - pub modules: Vec, - pub allocator_module: Option, -} - enum MaybeLtoModules { - NoLto { - modules: Vec, - allocator_module: Option, - }, + NoLto(CompiledModules), FatLto { cgcx: CodegenContext, exported_symbols_for_lto: Arc>, @@ -443,15 +435,13 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { pub(crate) fn start_async_codegen( backend: B, tcx: TyCtxt<'_>, - target_cpu: String, + crate_info: &CrateInfo, allocator_module: Option>, ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); let no_builtins = find_attr!(tcx, crate, NoBuiltins); - let crate_info = CrateInfo::new(tcx, target_cpu); - let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins); let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins); @@ -461,7 +451,7 @@ pub(crate) fn start_async_codegen( let coordinator_thread = start_executing_work( backend.clone(), tcx, - &crate_info, + crate_info, shared_emitter, codegen_worker_send, coordinator_receive, @@ -473,7 +463,6 @@ pub(crate) fn start_async_codegen( OngoingCodegen { backend, - crate_info, codegen_worker_receive, shared_emitter_main, @@ -1818,12 +1807,12 @@ fn start_executing_work( } } - Ok(MaybeLtoModules::NoLto { + Ok(MaybeLtoModules::NoLto(CompiledModules { modules: compiled_modules, allocator_module: allocator_module.map(|allocator_module| { B::codegen(&cgcx, &prof, &shared_emitter, allocator_module, &allocator_config) }), - }) + })) }) .expect("failed to spawn coordinator thread"); @@ -2139,7 +2128,6 @@ impl Drop for Coordinator { pub struct OngoingCodegen { pub backend: B, - pub crate_info: CrateInfo, pub output_filenames: Arc, // Field order below is intended to terminate the coordinator thread before two fields below // drop and prematurely close channels used by coordinator thread. See `Coordinator`'s @@ -2150,7 +2138,7 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap) { + pub fn join(self, sess: &Session) -> (CompiledModules, FxIndexMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { @@ -2170,9 +2158,9 @@ impl OngoingCodegen { // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules { - MaybeLtoModules::NoLto { modules, allocator_module } => { + MaybeLtoModules::NoLto(compiled_modules) => { drop(shared_emitter); - CompiledModules { modules, allocator_module } + compiled_modules } MaybeLtoModules::FatLto { cgcx, @@ -2256,15 +2244,7 @@ impl OngoingCodegen { self.backend.print_statistics() } - ( - CodegenResults { - crate_info: self.crate_info, - - modules: compiled_modules.modules, - allocator_module: compiled_modules.allocator_module, - }, - work_products, - ) + (compiled_modules, work_products) } pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 3939f145df881..609f54b7a1cf4 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -681,7 +681,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec( backend: B, tcx: TyCtxt<'_>, - target_cpu: String, + crate_info: &CrateInfo, ) -> OngoingCodegen { if tcx.sess.target.need_explicit_cpu && tcx.sess.opts.cg.target_cpu.is_none() { // The target has no default cpu, but none is set explicitly @@ -719,7 +719,7 @@ pub fn codegen_crate( None }; - let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu, allocator_module); + let ongoing_codegen = start_async_codegen(backend.clone(), tcx, crate_info, allocator_module); // For better throughput during parallel processing by LLVM, we used to sort // CGUs largest to smallest. This would lead to better thread utilization diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c7e90d3b3c330..6a0a9e7d51bed 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -209,7 +209,8 @@ impl From<&cstore::NativeLib> for NativeLib { /// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own /// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource` /// and the corresponding properties without referencing information outside of a `CrateInfo`. -#[derive(Debug, Encodable, Decodable)] +// rustc_codegen_cranelift needs a Clone impl for its jit mode, which isn't tested in rust CI +#[derive(Clone, Debug, Encodable, Decodable)] pub struct CrateInfo { pub target_cpu: String, pub target_features: Vec, @@ -251,10 +252,9 @@ pub struct TargetConfig { } #[derive(Encodable, Decodable)] -pub struct CodegenResults { +pub struct CompiledModules { pub modules: Vec, pub allocator_module: Option, - pub crate_info: CrateInfo, } pub enum CodegenErrors { @@ -293,11 +293,12 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool { const RLINK_VERSION: u32 = 1; const RLINK_MAGIC: &[u8] = b"rustlink"; -impl CodegenResults { +impl CompiledModules { pub fn serialize_rlink( sess: &Session, rlink_file: &Path, - codegen_results: &CodegenResults, + compiled_modules: &CompiledModules, + crate_info: &CrateInfo, metadata: &EncodedMetadata, outputs: &OutputFilenames, ) -> Result { @@ -307,7 +308,8 @@ impl CodegenResults { // Encoder's inner representation of `u32`. encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()); encoder.emit_str(sess.cfg_version); - Encodable::encode(codegen_results, &mut encoder); + Encodable::encode(compiled_modules, &mut encoder); + Encodable::encode(crate_info, &mut encoder); Encodable::encode(metadata, &mut encoder); Encodable::encode(outputs, &mut encoder); encoder.finish().map_err(|(_path, err)| err) @@ -316,7 +318,7 @@ impl CodegenResults { pub fn deserialize_rlink( sess: &Session, data: Vec, - ) -> Result<(Self, EncodedMetadata, OutputFilenames), CodegenErrors> { + ) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenErrors> { // The Decodable machinery is not used here because it panics if the input data is invalid // and because its internal representation may change. if !data.starts_with(RLINK_MAGIC) { @@ -346,10 +348,11 @@ impl CodegenResults { }); } - let codegen_results = CodegenResults::decode(&mut decoder); + let compiled_modules = CompiledModules::decode(&mut decoder); + let crate_info = CrateInfo::decode(&mut decoder); let metadata = EncodedMetadata::decode(&mut decoder); let outputs = OutputFilenames::decode(&mut decoder); - Ok((codegen_results, metadata, outputs)) + Ok((compiled_modules, crate_info, metadata, outputs)) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 60f2d4155d4bc..8df1ecc0fff57 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -18,7 +18,7 @@ use super::write::WriteBackendMethods; use crate::back::archive::ArArchiveBuilderBuilder; use crate::back::link::link_binary; use crate::back::write::TargetMachineFactoryFn; -use crate::{CodegenResults, ModuleCodegen, TargetConfig}; +use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; pub trait BackendTypes { type Function: CodegenObject; @@ -103,7 +103,9 @@ pub trait CodegenBackend { fn provide(&self, _providers: &mut Providers) {} - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box; + fn target_cpu(&self, sess: &Session) -> String; + + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, crate_info: &CrateInfo) -> Box; /// This is called on the returned `Box` from [`codegen_crate`](Self::codegen_crate) /// @@ -115,20 +117,22 @@ pub trait CodegenBackend { ongoing_codegen: Box, sess: &Session, outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap); + ) -> (CompiledModules, FxIndexMap); - /// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen). + /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen). fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { link_binary( sess, &ArArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 38a11b427c1f6..86d902b1c6993 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -28,7 +28,7 @@ use std::{env, str}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenErrors, CodegenResults}; +use rustc_codegen_ssa::{CodegenErrors, CompiledModules}; use rustc_data_structures::profiling::{ TimePassesFormat, get_resident_set_size, print_time_passes_entry, }; @@ -556,9 +556,11 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { let rlink_data = fs::read(file).unwrap_or_else(|err| { dcx.emit_fatal(RlinkUnableToRead { err }); }); - let (codegen_results, metadata, outputs) = - match CodegenResults::deserialize_rlink(sess, rlink_data) { - Ok((codegen, metadata, outputs)) => (codegen, metadata, outputs), + let (compiled_modules, crate_info, metadata, outputs) = + match CompiledModules::deserialize_rlink(sess, rlink_data) { + Ok((codegen, crate_info, metadata, outputs)) => { + (codegen, crate_info, metadata, outputs) + } Err(err) => { match err { CodegenErrors::WrongFileType => dcx.emit_fatal(RLinkWrongFileType), @@ -583,7 +585,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { }; } }; - compiler.codegen_backend.link(sess, codegen_results, metadata, &outputs); + compiler.codegen_backend.link(sess, compiled_modules, crate_info, metadata, &outputs); } else { dcx.emit_fatal(RlinkNotAFile {}); } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f36102fdc73f0..49be9cb3382d9 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -520,6 +520,8 @@ declare_features! ( (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)), /// Target features on hexagon. (unstable, hexagon_target_feature, "1.27.0", Some(150250)), + /// Allows `impl(crate) trait Foo` restrictions. + (incomplete, impl_restriction, "CURRENT_RUSTC_VERSION", Some(105077)), /// Allows `impl Trait` to be used inside associated types (RFC 2515). (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)), /// Allows `impl Trait` in bindings (`let`). diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 394622654cf88..3959ee7f94128 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -371,7 +371,7 @@ impl DefKind { ) } - /// Whether the corresponding item has generic parameters, ie. the `generics_of` query works. + /// Whether the corresponding item has generic parameters, i.e. the `generics_of` query works. pub fn has_generics(self) -> bool { match self { DefKind::AnonConst diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 15addd2407857..5d4db9aef003c 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -8,7 +8,7 @@ use std::{env, fs, iter}; use rustc_ast::{self as ast, CRATE_NODE_ID}; use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit}; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns}; @@ -1194,7 +1194,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { pub(crate) fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, -) -> (Box, EncodedMetadata) { +) -> (Box, CrateInfo, EncodedMetadata) { tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen); // Hook for tests. @@ -1221,19 +1221,17 @@ pub(crate) fn start_codegen<'tcx>( let metadata = rustc_metadata::fs::encode_and_write_metadata(tcx); - let codegen = tcx.sess.time("codegen_crate", move || { + let crate_info = CrateInfo::new(tcx, codegen_backend.target_cpu(tcx.sess)); + + let codegen = tcx.sess.time("codegen_crate", || { if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() { // Skip crate items and just output metadata in -Z no-codegen mode. tcx.sess.dcx().abort_if_errors(); // Linker::link will skip join_codegen in case of a CodegenResults Any value. - Box::new(CodegenResults { - modules: vec![], - allocator_module: None, - crate_info: CrateInfo::new(tcx, "".to_owned()), - }) + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } else { - codegen_backend.codegen_crate(tcx) + codegen_backend.codegen_crate(tcx, &crate_info) } }); @@ -1245,7 +1243,7 @@ pub(crate) fn start_codegen<'tcx>( tcx.sess.code_stats.print_type_sizes(); } - (codegen, metadata) + (codegen, crate_info, metadata) } /// Compute and validate the crate name. diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 3799485077ef4..f4fcd4471d3fd 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,8 +1,8 @@ use std::any::Any; use std::sync::Arc; -use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::svh::Svh; use rustc_errors::timings::TimingSection; @@ -21,6 +21,7 @@ pub struct Linker { output_filenames: Arc, // Only present when incr. comp. is enabled. crate_hash: Option, + crate_info: CrateInfo, metadata: EncodedMetadata, ongoing_codegen: Box, } @@ -30,7 +31,7 @@ impl Linker { tcx: TyCtxt<'_>, codegen_backend: &dyn CodegenBackend, ) -> Linker { - let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx); + let (ongoing_codegen, crate_info, metadata) = passes::start_codegen(codegen_backend, tcx); Linker { dep_graph: tcx.dep_graph.clone(), @@ -40,16 +41,17 @@ impl Linker { } else { None }, + crate_info, metadata, ongoing_codegen, } } pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) { - let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || { - match self.ongoing_codegen.downcast::() { + let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { + match self.ongoing_codegen.downcast::() { // This was a check only build - Ok(codegen_results) => (*codegen_results, IndexMap::default()), + Ok(compiled_modules) => (*compiled_modules, IndexMap::default()), Err(ongoing_codegen) => { codegen_backend.join_codegen(ongoing_codegen, sess, &self.output_filenames) @@ -97,10 +99,11 @@ impl Linker { if sess.opts.unstable_opts.no_link { let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT); - CodegenResults::serialize_rlink( + CompiledModules::serialize_rlink( sess, &rlink_file, - &codegen_results, + &compiled_modules, + &self.crate_info, &self.metadata, &self.output_filenames, ) @@ -112,6 +115,12 @@ impl Linker { let _timer = sess.prof.verbose_generic_activity("link_crate"); let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking); - codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames) + codegen_backend.link( + sess, + compiled_modules, + self.crate_info, + self.metadata, + &self.output_filenames, + ) } } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f1b80ec13a307..bacdad25c50b3 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBu use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo, TargetConfig}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; @@ -401,12 +401,12 @@ impl CodegenBackend for DummyCodegenBackend { vec![CrateType::Rlib, CrateType::Executable] } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { - Box::new(CodegenResults { - modules: vec![], - allocator_module: None, - crate_info: CrateInfo::new(tcx, String::new()), - }) + fn target_cpu(&self, _sess: &Session) -> String { + String::new() + } + + fn codegen_crate<'tcx>(&self, _tcx: TyCtxt<'tcx>, _crate_info: &CrateInfo) -> Box { + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } fn join_codegen( @@ -414,24 +414,22 @@ impl CodegenBackend for DummyCodegenBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) } fn link( &self, sess: &Session, - codegen_results: CodegenResults, + compiled_modules: CompiledModules, + crate_info: CrateInfo, metadata: EncodedMetadata, outputs: &OutputFilenames, ) { // JUSTIFICATION: TyCtxt no longer available here #[allow(rustc::bad_opt_access)] - if let Some(&crate_type) = codegen_results - .crate_info - .crate_types - .iter() - .find(|&&crate_type| crate_type != CrateType::Rlib) + if let Some(&crate_type) = + crate_info.crate_types.iter().find(|&&crate_type| crate_type != CrateType::Rlib) && outputs.outputs.should_link() { sess.dcx().fatal(format!( @@ -442,7 +440,8 @@ impl CodegenBackend for DummyCodegenBackend { link_binary( sess, &DummyArchiveBuilderBuilder, - codegen_results, + compiled_modules, + crate_info, metadata, outputs, self.name(), diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 1e1bbf51fcb9b..34c569232fc0d 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -59,7 +59,7 @@ declare_lint! { declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS, INVALID_NULL_ARGUMENTS]); /// This function checks if the expression is from a series of consecutive casts, -/// ie. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either +/// i.e. `(my_fn as *const _ as *mut _).cast_mut()` and whether the original expression is either /// a fn ptr, a reference, or a function call whose definition is /// annotated with `#![rustc_never_returns_null_ptr]`. /// If this situation is present, the function returns the appropriate diagnostic. diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 721cc7fe4d9b3..0a741d32ed61d 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -137,54 +137,23 @@ struct CacheOnDiskIf { block: Block, } +/// See `rustc_middle::query::modifiers` for documentation of each query modifier. struct QueryModifiers { - /// The description of the query. - desc: Desc, - - /// Use this type for the in-memory cache. + // tidy-alphabetical-start + anon: Option, arena_cache: Option, - - /// Cache the query to disk if the `Block` returns true. cache_on_disk_if: Option, - - /// A cycle error for this query aborting the compilation with a fatal error. - cycle_fatal: Option, - - /// A cycle error results in a delay_bug call cycle_delay_bug: Option, - - /// A cycle error results in a stashed cycle error that can be unstashed and canceled later + cycle_fatal: Option, cycle_stash: Option, - - /// Don't hash the result, instead just mark a query red if it runs - no_hash: Option, - - /// Generate a dep node based on the dependencies of the query - anon: Option, - - /// Always evaluate the query, ignoring its dependencies - eval_always: Option, - - /// Whether the query has a call depth limit depth_limit: Option, - - /// Use a separate query provider for local and extern crates - separate_provide_extern: Option, - - /// Generate a `feed` method to set the query's value from another query. + desc: Desc, + eval_always: Option, feedable: Option, - - /// When this query is called via `tcx.ensure_ok()`, it returns - /// `Result<(), ErrorGuaranteed>` instead of `()`. If the query needs to - /// be executed, and that execution returns an error, the error result is - /// returned to the caller. - /// - /// If execution is skipped, a synthetic `Ok(())` is returned, on the - /// assumption that a query with all-green inputs must have succeeded. - /// - /// Can only be applied to queries with a return value of - /// `Result<_, ErrorGuaranteed>`. + no_hash: Option, return_result_from_ensure_ok: Option, + separate_provide_extern: Option, + // tidy-alphabetical-end } fn parse_query_modifiers(input: ParseStream<'_>) -> Result { @@ -272,6 +241,68 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result { }) } +fn make_modifiers_stream(query: &Query, modifiers: &QueryModifiers) -> proc_macro2::TokenStream { + let QueryModifiers { + // tidy-alphabetical-start + anon, + arena_cache, + cache_on_disk_if, + cycle_delay_bug, + cycle_fatal, + cycle_stash, + depth_limit, + desc: _, + eval_always, + feedable, + no_hash, + return_result_from_ensure_ok, + separate_provide_extern, + // tidy-alphabetical-end + } = modifiers; + + let anon = anon.is_some(); + let arena_cache = arena_cache.is_some(); + let cache_on_disk = cache_on_disk_if.is_some(); + + let cycle_error_handling = if cycle_delay_bug.is_some() { + quote! { DelayBug } + } else if cycle_fatal.is_some() { + quote! { Fatal } + } else if cycle_stash.is_some() { + quote! { Stash } + } else { + quote! { Error } + }; + + let depth_limit = depth_limit.is_some(); + let eval_always = eval_always.is_some(); + let feedable = feedable.is_some(); + let no_hash = no_hash.is_some(); + let return_result_from_ensure_ok = return_result_from_ensure_ok.is_some(); + let separate_provide_extern = separate_provide_extern.is_some(); + + // Giving an input span to the modifier names in the modifier list seems + // to give slightly more helpful errors when one of the callback macros + // fails to parse the modifier list. + let query_name_span = query.name.span(); + quote_spanned! { + query_name_span => + // Search for (QMODLIST) to find all occurrences of this query modifier list. + // tidy-alphabetical-start + anon: #anon, + arena_cache: #arena_cache, + cache_on_disk: #cache_on_disk, + cycle_error_handling: #cycle_error_handling, + depth_limit: #depth_limit, + eval_always: #eval_always, + feedable: #feedable, + no_hash: #no_hash, + return_result_from_ensure_ok: #return_result_from_ensure_ok, + separate_provide_extern: #separate_provide_extern, + // tidy-alphabetical-end + } +} + fn doc_comment_from_desc(list: &Punctuated) -> Result { use ::syn::*; let mut iter = list.iter(); @@ -458,51 +489,13 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream { ReturnType::Type(..) => quote! { #return_ty }, }; - let mut modifiers_out = vec![]; - - macro_rules! passthrough { - ( $( $modifier:ident ),+ $(,)? ) => { - $( if let Some($modifier) = &modifiers.$modifier { - modifiers_out.push(quote! { (#$modifier) }); - }; )+ - } - } - - passthrough!( - arena_cache, - cycle_fatal, - cycle_delay_bug, - cycle_stash, - no_hash, - anon, - eval_always, - feedable, - depth_limit, - separate_provide_extern, - return_result_from_ensure_ok, - ); - - // If there was a `cache_on_disk_if` modifier in the real input, pass - // on a synthetic `(cache_on_disk)` modifier that can be inspected by - // macro-rules macros. - if modifiers.cache_on_disk_if.is_some() { - modifiers_out.push(quote! { (cache_on_disk) }); - } - - // This uses the span of the query definition for the commas, - // which can be important if we later encounter any ambiguity - // errors with any of the numerous macro_rules! macros that - // we use. Using the call-site span would result in a span pointing - // at the entire `rustc_queries!` invocation, which wouldn't - // be very useful. - let span = name.span(); - let modifiers_stream = quote_spanned! { span => #(#modifiers_out),* }; + let modifiers_stream = make_modifiers_stream(&query, modifiers); // Add the query to the group query_stream.extend(quote! { #(#doc_comments)* - [#modifiers_stream] - fn #name(#key_ty) #return_ty, + fn #name(#key_ty) #return_ty + { #modifiers_stream } }); if let Some(feedable) = &modifiers.feedable { diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 7efa013c3d999..6f85dba23dd49 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -268,8 +268,10 @@ macro_rules! define_dep_nodes { queries { $( $(#[$q_attr:meta])* - [$($modifiers:tt)*] - fn $q_name:ident($K:ty) -> $V:ty, + fn $q_name:ident($K:ty) -> $V:ty + // Search for (QMODLIST) to find all occurrences of this query modifier list. + // Query modifiers are currently not used here, so skip the whole list. + { $($modifiers:tt)* } )* } non_queries { diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index ff6d87298028f..815c8a1baab61 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -333,44 +333,6 @@ macro_rules! query_helper_param_ty { ($K:ty) => { $K }; } -// Expands to `$yes` if the `arena_cache` modifier is present, `$no` otherwise. -macro_rules! if_arena_cache { - ([] $then:tt $no:tt) => { $no }; - ([(arena_cache) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_arena_cache!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$yes` if the `separate_provide_extern` modifier is present, `$no` otherwise. -macro_rules! if_separate_provide_extern { - ([] $then:tt $no:tt) => { $no }; - ([(separate_provide_extern) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_separate_provide_extern!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$yes` if the `return_result_from_ensure_ok` modifier is present, `$no` otherwise. -macro_rules! if_return_result_from_ensure_ok { - ([] $then:tt $no:tt) => { $no }; - ([(return_result_from_ensure_ok) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_return_result_from_ensure_ok!([$($modifiers)*] $yes $no) - }; -} - -// Expands to `$item` if the `feedable` modifier is present. -macro_rules! item_if_feedable { - ([] $($item:tt)*) => {}; - ([(feedable) $($rest:tt)*] $($item:tt)*) => { - $($item)* - }; - ([$other:tt $($modifiers:tt)*] $($item:tt)*) => { - item_if_feedable! { [$($modifiers)*] $($item)* } - }; -} - macro_rules! define_callbacks { ( // You might expect the key to be `$K:ty`, but it needs to be `$($K:tt)*` so that @@ -378,8 +340,20 @@ macro_rules! define_callbacks { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($($K:tt)*) -> $V:ty, + fn $name:ident($($K:tt)*) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } // Non-queries are unused here. @@ -394,20 +368,31 @@ macro_rules! define_callbacks { pub type Key<'tcx> = $($K)*; pub type Value<'tcx> = $V; - pub type LocalKey<'tcx> = if_separate_provide_extern!( - [$($modifiers)*] - ( as $crate::query::AsLocalQueryKey>::LocalQueryKey) - (Key<'tcx>) - ); - - /// This type alias specifies the type returned from query providers and the type - /// used for decoding. For regular queries this is the declared returned type `V`, - /// but `arena_cache` will use `::Provided` instead. - pub type ProvidedValue<'tcx> = if_arena_cache!( - [$($modifiers)*] - ( as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided) - (Value<'tcx>) - ); + /// Key type used by provider functions in `local_providers`. + /// This query has the `separate_provide_extern` modifier. + #[cfg($separate_provide_extern)] + pub type LocalKey<'tcx> = + as $crate::query::AsLocalQueryKey>::LocalQueryKey; + /// Key type used by provider functions in `local_providers`. + #[cfg(not($separate_provide_extern))] + pub type LocalKey<'tcx> = Key<'tcx>; + + /// Return type of the `.ensure_ok()` method for this query, + /// which has the `return_result_from_ensure_ok` modifier. + #[cfg($return_result_from_ensure_ok)] + pub type EnsureOkReturnType = Result<(), rustc_errors::ErrorGuaranteed>; + /// Return type of the `.ensure_ok()` method for this query, + /// which does _not_ have the `return_result_from_ensure_ok` modifier. + #[cfg(not($return_result_from_ensure_ok))] + pub type EnsureOkReturnType = (); + + /// Type returned from query providers and loaded from disk-cache. + #[cfg($arena_cache)] + pub type ProvidedValue<'tcx> = + as $crate::query::arena_cached::ArenaCached<'tcx>>::Provided; + /// Type returned from query providers and loaded from disk-cache. + #[cfg(not($arena_cache))] + pub type ProvidedValue<'tcx> = Value<'tcx>; /// This helper function takes a value returned by the query provider /// (or loaded from disk, or supplied by query feeding), allocates @@ -420,23 +405,23 @@ macro_rules! define_callbacks { ) -> Erased> { // For queries with the `arena_cache` modifier, store the // provided value in an arena and get a reference to it. - let value: Value<'tcx> = if_arena_cache!( - [$($modifiers)*] - { - as $crate::query::arena_cached::ArenaCached>:: - alloc_in_arena - ( - tcx, - &tcx.query_system.arenas.$name, - provided_value, - ) - } - { - // Otherwise, the provided value is the value (and `tcx` is unused). - let _ = tcx; - provided_value - } - ); + #[cfg($arena_cache)] + let value: Value<'tcx> = { + use $crate::query::arena_cached::ArenaCached; + as ArenaCached>::alloc_in_arena( + tcx, + &tcx.query_system.arenas.$name, + provided_value, + ) + }; + + // Otherwise, the provided value is the value (and `tcx` is unused). + #[cfg(not($arena_cache))] + let value: Value<'tcx> = { + let _ = tcx; + provided_value + }; + erase::erase_val(value) } @@ -480,13 +465,11 @@ macro_rules! define_callbacks { #[derive(Default)] pub struct QueryArenas<'tcx> { $( - pub $name: if_arena_cache!( - [$($modifiers)*] - // Use the `ArenaCached` helper trait to determine the arena's value type. - (TypedArena<<$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated>) - // No arena for this query, so the field type is `()`. - () - ), + // Use the `ArenaCached` helper trait to determine the arena's value type. + #[cfg($arena_cache)] + pub $name: TypedArena< + <$V as $crate::query::arena_cached::ArenaCached<'tcx>>::Allocated, + >, )* } @@ -497,16 +480,14 @@ macro_rules! define_callbacks { pub fn $name( self, key: query_helper_param_ty!($($K)*), - ) -> if_return_result_from_ensure_ok!( - [$($modifiers)*] - (Result<(), ErrorGuaranteed>) - () - ) { - if_return_result_from_ensure_ok!( - [$($modifiers)*] - (crate::query::inner::query_ensure_error_guaranteed) - (crate::query::inner::query_ensure) - )( + ) -> $crate::queries::$name::EnsureOkReturnType { + + #[cfg($return_result_from_ensure_ok)] + let ensure_fn = crate::query::inner::query_ensure_error_guaranteed; + #[cfg(not($return_result_from_ensure_ok))] + let ensure_fn = crate::query::inner::query_ensure; + + ensure_fn( self.tcx, &self.tcx.query_system.query_vtables.$name, $crate::query::IntoQueryParam::into_query_param(key), @@ -560,24 +541,22 @@ macro_rules! define_callbacks { } $( - item_if_feedable! { - [$($modifiers)*] - impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy> - TyCtxtFeed<'tcx, K> - { - $(#[$attr])* - #[inline(always)] - pub fn $name(self, value: $name::ProvidedValue<'tcx>) { - let key = self.key().into_query_param(); - let erased_value = $name::provided_to_erased(self.tcx, value); - $crate::query::inner::query_feed( - self.tcx, - dep_graph::DepKind::$name, - &self.tcx.query_system.query_vtables.$name, - key, - erased_value, - ); - } + #[cfg($feedable)] + impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy> + TyCtxtFeed<'tcx, K> + { + $(#[$attr])* + #[inline(always)] + pub fn $name(self, value: $name::ProvidedValue<'tcx>) { + let key = self.key().into_query_param(); + let erased_value = $name::provided_to_erased(self.tcx, value); + $crate::query::inner::query_feed( + self.tcx, + dep_graph::DepKind::$name, + &self.tcx.query_system.query_vtables.$name, + key, + erased_value, + ); } } )* @@ -602,11 +581,11 @@ macro_rules! define_callbacks { pub struct ExternProviders { $( - pub $name: if_separate_provide_extern!( - [$($modifiers)*] - (for<'tcx> fn(TyCtxt<'tcx>, $name::Key<'tcx>) -> $name::ProvidedValue<'tcx>) - () - ), + #[cfg($separate_provide_extern)] + pub $name: for<'tcx> fn( + TyCtxt<'tcx>, + $name::Key<'tcx>, + ) -> $name::ProvidedValue<'tcx>, )* } @@ -626,13 +605,10 @@ macro_rules! define_callbacks { fn default() -> Self { ExternProviders { $( - $name: if_separate_provide_extern!( - [$($modifiers)*] - (|_, key| $crate::query::plumbing::default_extern_query( - stringify!($name), - &key - )) - () + #[cfg($separate_provide_extern)] + $name: |_, key| $crate::query::plumbing::default_extern_query( + stringify!($name), + &key, ), )* } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 6367c87b1aa95..c501682775524 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -175,7 +175,7 @@ pub struct LeafDef { /// The node in the specialization graph containing the definition of `item`. pub defining_node: Node, - /// The "top-most" (ie. least specialized) specialization graph node that finalized the + /// The "top-most" (i.e. least specialized) specialization graph node that finalized the /// definition of `item`. /// /// Example: @@ -210,7 +210,7 @@ impl LeafDef { } impl<'tcx> Ancestors<'tcx> { - /// Finds the bottom-most (ie. most specialized) definition of an associated + /// Finds the bottom-most (i.e. most specialized) definition of an associated /// item. pub fn leaf_def(mut self, tcx: TyCtxt<'tcx>, trait_item_def_id: DefId) -> Option { let mut finalizing_node = None; diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 655262af8f36a..7b8772eda2b38 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -160,7 +160,7 @@ where /// /// The passed `elaborator` is used to determine what should happen at the drop terminator. It /// decides whether the drop can be statically determined or whether it needs a dynamic drop flag, -/// and whether the drop is "open", ie. should be expanded to drop all subfields of the dropped +/// and whether the drop is "open", i.e. should be expanded to drop all subfields of the dropped /// value. /// /// When this returns, the MIR patch in the `elaborator` contains the necessary changes. diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 721a976eb910a..0c5d8913a8070 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -245,7 +245,7 @@ fn compute_replacement<'tcx>( debug!(?rvalue); match rvalue { // This is a copy, just use the value we have in store for the previous one. - // As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should + // As we are visiting in `assignment_order`, i.e. reverse postorder, `rhs` should // have been visited before. Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => { if let Some(rhs) = place.as_local() diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index a56f04cf48422..4f9f2e5fabb93 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -25,7 +25,7 @@ pub(super) struct SsaLocals { assignment_order: Vec, /// Copy equivalence classes between locals. See `copy_classes` for documentation. copy_classes: IndexVec, - /// Number of "direct" uses of each local, ie. uses that are not dereferences. + /// Number of "direct" uses of each local, i.e. uses that are not dereferences. /// We ignore non-uses (Storage statements, debuginfo). direct_uses: IndexVec, /// Set of SSA locals that are immutably borrowed. @@ -314,7 +314,7 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { continue; } - // We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been + // We visit in `assignment_order`, i.e. reverse post-order, so `rhs` has been // visited before `local`, and we just have to copy the representing local. let head = copies[rhs]; diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index c7e2b67d88d2f..e156ad79e1900 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1269,6 +1269,26 @@ pub(crate) struct IncorrectVisibilityRestriction { pub inner_str: String, } +#[derive(Diagnostic)] +#[diag("incorrect `impl` restriction")] +#[help( + "some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path" +)] +pub(crate) struct IncorrectImplRestriction { + #[primary_span] + #[suggestion( + "help: use `in` to restrict implementations to the path `{$inner_str}`", + code = "in {inner_str}", + applicability = "machine-applicable" + )] + pub span: Span, + pub inner_str: String, +} + #[derive(Diagnostic)] #[diag(" ... else {\"{\"} ... {\"}\"} is not allowed")] pub(crate) struct AssignmentElseNotAllowed { @@ -2403,6 +2423,14 @@ pub(crate) struct TraitAliasCannotBeUnsafe { pub span: Span, } +#[derive(Diagnostic)] +#[diag("trait aliases cannot be `impl`-restricted")] +pub(crate) struct TraitAliasCannotBeImplRestricted { + #[primary_span] + #[label("trait aliases cannot be `impl`-restricted")] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("associated `static` items are not allowed")] pub(crate) struct AssociatedStaticItemNotAllowed { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3421924d1f762..db5be5feaeb6e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1025,17 +1025,79 @@ impl<'a> Parser<'a> { } } - /// Is this an `(const unsafe? auto?| unsafe auto? | auto) trait` item? + /// Is there an `[ impl(in? path) ]? trait` item `dist` tokens ahead? + fn is_trait_with_maybe_impl_restriction_in_front(&self, dist: usize) -> bool { + // `trait` + if self.is_keyword_ahead(dist, &[kw::Trait]) { + return true; + } + // `impl(` + if !self.is_keyword_ahead(dist, &[kw::Impl]) + || !self.look_ahead(dist + 1, |t| t == &token::OpenParen) + { + return false; + } + // `crate | super | self) trait` + if self.is_keyword_ahead(dist + 2, &[kw::Crate, kw::Super, kw::SelfLower]) + && self.look_ahead(dist + 3, |t| t == &token::CloseParen) + && self.is_keyword_ahead(dist + 4, &[kw::Trait]) + { + return true; + } + // `impl(in? something) trait` + // We catch cases where the `in` keyword is missing to provide a + // better error message. This is handled later in + // `self.recover_incorrect_impl_restriction`. + self.tree_look_ahead(dist + 2, |t| { + if let TokenTree::Token(token, _) = t { token.is_keyword(kw::Trait) } else { false } + }) + .unwrap_or(false) + } + + /// Is this an `(const unsafe? auto? [ impl(in? path) ]? | unsafe auto? [ impl(in? path) ]? | auto [ impl(in? path) ]? | [ impl(in? path) ]?) trait` item? fn check_trait_front_matter(&mut self) -> bool { - // auto trait - self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait]) - // unsafe auto trait - || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto]) - || self.check_keyword(exp!(Const)) && ((self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait])) - || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto])) + // `[ impl(in? path) ]? trait` + if self.is_trait_with_maybe_impl_restriction_in_front(0) { + return true; + } + // `auto [ impl(in? path) ]? trait` + if self.check_keyword(exp!(Auto)) && self.is_trait_with_maybe_impl_restriction_in_front(1) { + return true; + } + // `unsafe auto? [ impl(in? path) ]? trait` + if self.check_keyword(exp!(Unsafe)) + && (self.is_trait_with_maybe_impl_restriction_in_front(1) + || self.is_keyword_ahead(1, &[kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(2)) + { + return true; + } + // `const` ... + if !self.check_keyword(exp!(Const)) { + return false; + } + // `const [ impl(in? path) ]? trait` + if self.is_trait_with_maybe_impl_restriction_in_front(1) { + return true; + } + // `const (unsafe | auto) [ impl(in? path) ]? trait` + if self.is_keyword_ahead(1, &[kw::Unsafe, kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(2) + { + return true; + } + // `const unsafe auto [ impl(in? path) ]? trait` + self.is_keyword_ahead(1, &[kw::Unsafe]) + && self.is_keyword_ahead(2, &[kw::Auto]) + && self.is_trait_with_maybe_impl_restriction_in_front(3) } - /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. + /// Parses `const? unsafe? auto? [impl(in? path)]? trait Foo { ... }` or `trait Foo = Bar;`. + /// + /// FIXME(restrictions): The current keyword order follows the grammar specified in RFC 3323. + /// However, whether the restriction should be grouped closer to the visibility modifier + /// (e.g., `pub impl(crate) const unsafe auto trait`) remains an unresolved design question. + /// This ordering must be kept in sync with the logic in `check_trait_front_matter`. fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> { let constness = self.parse_constness(Case::Sensitive); if let Const::Yes(span) = constness { @@ -1050,6 +1112,8 @@ impl<'a> Parser<'a> { IsAuto::No }; + let impl_restriction = self.parse_impl_restriction()?; + self.expect_keyword(exp!(Trait))?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; @@ -1078,6 +1142,9 @@ impl<'a> Parser<'a> { if let Safety::Unsafe(_) = safety { self.dcx().emit_err(errors::TraitAliasCannotBeUnsafe { span: whole_span }); } + if let RestrictionKind::Restricted { .. } = impl_restriction.kind { + self.dcx().emit_err(errors::TraitAliasCannotBeImplRestricted { span: whole_span }); + } self.psess.gated_spans.gate(sym::trait_alias, whole_span); @@ -1090,6 +1157,7 @@ impl<'a> Parser<'a> { constness, is_auto, safety, + impl_restriction, ident, generics, bounds, @@ -2858,8 +2926,8 @@ impl<'a> Parser<'a> { && !self.is_unsafe_foreign_mod() // Rule out `async gen {` and `async gen move {` && !self.is_async_gen_block() - // Rule out `const unsafe auto` and `const unsafe trait`. - && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait]) + // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`. + && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl]) ) }) // `extern ABI fn` diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index fc8c9813457b6..e18d337354288 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -35,8 +35,9 @@ use rustc_ast::util::case::Case; use rustc_ast::util::classify; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, BinOpKind, ByRef, Const, CoroutineKind, - DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, MgcaDisambiguation, - Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, + DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, ImplRestriction, + MgcaDisambiguation, Mutability, Recovered, RestrictionKind, Safety, StrLit, Visibility, + VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::debug_assert_matches; @@ -50,7 +51,10 @@ use token_type::TokenTypeSet; pub use token_type::{ExpKeywordPair, ExpTokenPair, TokenType}; use tracing::debug; -use crate::errors::{self, IncorrectVisibilityRestriction, NonStringAbiLiteral, TokenDescription}; +use crate::errors::{ + self, IncorrectImplRestriction, IncorrectVisibilityRestriction, NonStringAbiLiteral, + TokenDescription, +}; use crate::exp; #[cfg(test)] @@ -1530,6 +1534,60 @@ impl<'a> Parser<'a> { Ok(()) } + /// Parses an optional `impl` restriction. + /// Enforces the `impl_restriction` feature gate whenever an explicit restriction is encountered. + fn parse_impl_restriction(&mut self) -> PResult<'a, ImplRestriction> { + if self.eat_keyword(exp!(Impl)) { + let lo = self.prev_token.span; + // No units or tuples are allowed to follow `impl` here, so we can safely bump `(`. + self.expect(exp!(OpenParen))?; + if self.eat_keyword(exp!(In)) { + let path = self.parse_path(PathStyle::Mod)?; // `in path` + self.expect(exp!(CloseParen))?; // `)` + let restriction = RestrictionKind::Restricted { + path: Box::new(path), + id: ast::DUMMY_NODE_ID, + shorthand: false, + }; + let span = lo.to(self.prev_token.span); + self.psess.gated_spans.gate(sym::impl_restriction, span); + return Ok(ImplRestriction { kind: restriction, span, tokens: None }); + } else if self.look_ahead(1, |t| t == &token::CloseParen) + && self.is_keyword_ahead(0, &[kw::Crate, kw::Super, kw::SelfLower]) + { + let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self` + self.expect(exp!(CloseParen))?; // `)` + let restriction = RestrictionKind::Restricted { + path: Box::new(path), + id: ast::DUMMY_NODE_ID, + shorthand: true, + }; + let span = lo.to(self.prev_token.span); + self.psess.gated_spans.gate(sym::impl_restriction, span); + return Ok(ImplRestriction { kind: restriction, span, tokens: None }); + } else { + self.recover_incorrect_impl_restriction(lo)?; + // Emit diagnostic, but continue with no impl restriction. + } + } + Ok(ImplRestriction { + kind: RestrictionKind::Unrestricted, + span: self.token.span.shrink_to_lo(), + tokens: None, + }) + } + + /// Recovery for e.g. `impl(something) trait` + fn recover_incorrect_impl_restriction(&mut self, lo: Span) -> PResult<'a, ()> { + let path = self.parse_path(PathStyle::Mod)?; + self.expect(exp!(CloseParen))?; // `)` + let path_str = pprust::path_to_string(&path); + self.dcx().emit_err(IncorrectImplRestriction { span: path.span, inner_str: path_str }); + let end = self.prev_token.span; + self.psess.gated_spans.gate(sym::impl_restriction, lo.to(end)); + Ok(()) + } + /// Parses `extern string_literal?`. fn parse_extern(&mut self, case: Case) -> Extern { if self.eat_keyword_case(exp!(Extern), case) { diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs index ceddef5385a58..0f3ef34d936a4 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -130,8 +130,20 @@ macro_rules! define_dep_kind_vtables { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($K:ty) -> $V:ty, + fn $name:ident($K:ty) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } non_queries { @@ -154,9 +166,9 @@ macro_rules! define_dep_kind_vtables { $crate::dep_kind_vtables::make_dep_kind_vtable_for_query::< $crate::query_impl::$name::VTableGetter, >( - is_anon!([$($modifiers)*]), - if_cache_on_disk!([$($modifiers)*] true false), - is_eval_always!([$($modifiers)*]), + $anon, + $cache_on_disk, + $eval_always, ) ),* ]; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 17e6fba8ac9a5..425ca28910073 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -99,125 +99,6 @@ pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> boo tcx.dep_graph.try_mark_green(tcx, dep_node).is_some() } -macro_rules! cycle_error_handling { - ([]) => {{ - rustc_middle::query::CycleErrorHandling::Error - }}; - ([(cycle_fatal) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::Fatal - }}; - ([(cycle_stash) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::Stash - }}; - ([(cycle_delay_bug) $($rest:tt)*]) => {{ - rustc_middle::query::CycleErrorHandling::DelayBug - }}; - ([$other:tt $($modifiers:tt)*]) => { - cycle_error_handling!([$($modifiers)*]) - }; -} - -macro_rules! is_anon { - ([]) => {{ - false - }}; - ([(anon) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_anon!([$($modifiers)*]) - }; -} - -macro_rules! is_eval_always { - ([]) => {{ - false - }}; - ([(eval_always) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_eval_always!([$($modifiers)*]) - }; -} - -macro_rules! is_depth_limit { - ([]) => {{ - false - }}; - ([(depth_limit) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_depth_limit!([$($modifiers)*]) - }; -} - -macro_rules! is_feedable { - ([]) => {{ - false - }}; - ([(feedable) $($rest:tt)*]) => {{ - true - }}; - ([$other:tt $($modifiers:tt)*]) => { - is_feedable!([$($modifiers)*]) - }; -} - -/// Expands to `$yes` if the `no_hash` modifier is present, or `$no` otherwise. -macro_rules! if_no_hash { - ([] $yes:tt $no:tt) => { $no }; - ([(no_hash) $($modifiers:tt)*] $yes:tt $no:tt) => { $yes }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_no_hash!([$($modifiers)*] $yes $no) - } -} - -macro_rules! call_provider { - ([][$tcx:expr, $name:ident, $key:expr]) => {{ - ($tcx.query_system.local_providers.$name)($tcx, $key) - }}; - ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{ - if let Some(key) = $key.as_local_key() { - ($tcx.query_system.local_providers.$name)($tcx, key) - } else { - ($tcx.query_system.extern_providers.$name)($tcx, $key) - } - }}; - ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { - call_provider!([$($modifiers)*][$($args)*]) - }; -} - -/// Expands to one of two token trees, depending on whether the current query -/// has the `cache_on_disk_if` modifier. -macro_rules! if_cache_on_disk { - ([] $yes:tt $no:tt) => { - $no - }; - // The `cache_on_disk_if` modifier generates a synthetic `(cache_on_disk)`, - // modifier, for use by this macro and similar macros. - ([(cache_on_disk) $($rest:tt)*] $yes:tt $no:tt) => { - $yes - }; - ([$other:tt $($modifiers:tt)*] $yes:tt $no:tt) => { - if_cache_on_disk!([$($modifiers)*] $yes $no) - }; -} - -/// Conditionally expands to some token trees, if the current query has the -/// `cache_on_disk_if` modifier. -macro_rules! item_if_cache_on_disk { - ([] $($item:tt)*) => {}; - ([(cache_on_disk) $($rest:tt)*] $($item:tt)*) => { - $($item)* - }; - ([$other:tt $($modifiers:tt)*] $($item:tt)*) => { - item_if_cache_on_disk! { [$($modifiers)*] $($item)* } - }; -} - /// The deferred part of a deferred query stack frame. fn mk_query_stack_frame_extra<'tcx, Cache>( (tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key), @@ -421,8 +302,20 @@ macro_rules! define_queries { queries { $( $(#[$attr:meta])* - [$($modifiers:tt)*] - fn $name:ident($K:ty) -> $V:ty, + fn $name:ident($K:ty) -> $V:ty + { + // Search for (QMODLIST) to find all occurrences of this query modifier list. + anon: $anon:literal, + arena_cache: $arena_cache:literal, + cache_on_disk: $cache_on_disk:literal, + cycle_error_handling: $cycle_error_handling:ident, + depth_limit: $depth_limit:literal, + eval_always: $eval_always:literal, + feedable: $feedable:literal, + no_hash: $no_hash:literal, + return_result_from_ensure_ok: $return_result_from_ensure_ok:literal, + separate_provide_extern: $separate_provide_extern:literal, + } )* } // Non-queries are unused here. @@ -498,7 +391,16 @@ macro_rules! define_queries { let _guard = tracing::span!(tracing::Level::TRACE, stringify!($name), ?key).entered(); // Call the actual provider function for this query. - let provided_value = call_provider!([$($modifiers)*][tcx, $name, key]); + + #[cfg($separate_provide_extern)] + let provided_value = if let Some(local_key) = key.as_local_key() { + (tcx.query_system.local_providers.$name)(tcx, local_key) + } else { + (tcx.query_system.extern_providers.$name)(tcx, key) + }; + + #[cfg(not($separate_provide_extern))] + let provided_value = (tcx.query_system.local_providers.$name)(tcx, key); rustc_middle::ty::print::with_reduced_queries!({ tracing::trace!(?provided_value); @@ -515,64 +417,67 @@ macro_rules! define_queries { { QueryVTable { name: stringify!($name), - anon: is_anon!([$($modifiers)*]), - eval_always: is_eval_always!([$($modifiers)*]), - depth_limit: is_depth_limit!([$($modifiers)*]), - feedable: is_feedable!([$($modifiers)*]), + anon: $anon, + eval_always: $eval_always, + depth_limit: $depth_limit, + feedable: $feedable, dep_kind: dep_graph::DepKind::$name, - cycle_error_handling: cycle_error_handling!([$($modifiers)*]), + cycle_error_handling: + rustc_middle::query::CycleErrorHandling::$cycle_error_handling, state: Default::default(), cache: Default::default(), - will_cache_on_disk_for_key_fn: if_cache_on_disk!([$($modifiers)*] { - Some(::rustc_middle::queries::_cache_on_disk_if_fns::$name) - } { - None - }), + + #[cfg($cache_on_disk)] + will_cache_on_disk_for_key_fn: + Some(rustc_middle::queries::_cache_on_disk_if_fns::$name), + #[cfg(not($cache_on_disk))] + will_cache_on_disk_for_key_fn: None, + call_query_method_fn: |tcx, key| { // Call the query method for its side-effect of loading a value // from disk-cache; the caller doesn't need the value. let _ = tcx.$name(key); }, invoke_provider_fn: self::invoke_provider_fn::__rust_begin_short_backtrace, - try_load_from_disk_fn: if_cache_on_disk!([$($modifiers)*] { - Some(|tcx, key, prev_index, index| { - // Check the `cache_on_disk_if` condition for this key. - if !::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { - return None; - } - - let value: queries::$name::ProvidedValue<'tcx> = - $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?; - - // Arena-alloc the value if appropriate, and erase it. - Some(queries::$name::provided_to_erased(tcx, value)) - }) - } { - None + + #[cfg($cache_on_disk)] + try_load_from_disk_fn: Some(|tcx, key, prev_index, index| { + // Check the `cache_on_disk_if` condition for this key. + if !rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) { + return None; + } + + let value: queries::$name::ProvidedValue<'tcx> = + $crate::plumbing::try_load_from_disk(tcx, prev_index, index)?; + + // Arena-alloc the value if appropriate, and erase it. + Some(queries::$name::provided_to_erased(tcx, value)) }), - is_loadable_from_disk_fn: if_cache_on_disk!([$($modifiers)*] { - Some(|tcx, key, index| -> bool { - ::rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) && - $crate::plumbing::loadable_from_disk(tcx, index) - }) - } { - None + #[cfg(not($cache_on_disk))] + try_load_from_disk_fn: None, + + #[cfg($cache_on_disk)] + is_loadable_from_disk_fn: Some(|tcx, key, index| -> bool { + rustc_middle::queries::_cache_on_disk_if_fns::$name(tcx, key) && + $crate::plumbing::loadable_from_disk(tcx, index) }), + #[cfg(not($cache_on_disk))] + is_loadable_from_disk_fn: None, + value_from_cycle_error: |tcx, cycle, guar| { let result: queries::$name::Value<'tcx> = FromCycleError::from_cycle_error(tcx, cycle, guar); erase::erase_val(result) }, - hash_value_fn: if_no_hash!( - [$($modifiers)*] - None - { - Some(|hcx, erased_value: &erase::Erased>| { - let value = erase::restore_val(*erased_value); - rustc_middle::dep_graph::hash_result(hcx, &value) - }) - } - ), + + #[cfg($no_hash)] + hash_value_fn: None, + #[cfg(not($no_hash))] + hash_value_fn: Some(|hcx, erased_value: &erase::Erased>| { + let value = erase::restore_val(*erased_value); + rustc_middle::dep_graph::hash_result(hcx, &value) + }), + format_value: |value| format!("{:?}", erase::restore_val::>(*value)), description_fn: $crate::queries::_description_fns::$name, execute_query_fn: if incremental { @@ -670,8 +575,8 @@ macro_rules! define_queries { query_result_index: &mut EncodedDepNodeIndex, ) { $( - item_if_cache_on_disk! { - [$($modifiers)*] + #[cfg($cache_on_disk)] + { $crate::plumbing::encode_query_results( tcx, &tcx.query_system.query_vtables.$name, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b3226b9f27699..c776020c21274 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2976,7 +2976,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { corrections.push((import.span, format!("{module_name}::{import_snippet}"))); } else { // Find the binding span (and any trailing commas and spaces). - // ie. `use a::b::{c, d, e};` + // i.e. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( self.tcx.sess, @@ -2988,11 +2988,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut removal_span = binding_span; // If the binding span ended with a closing brace, as in the below example: - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^ // Then expand the span of characters to remove to include the previous // binding's trailing comma. - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^^^ if found_closing_brace && let Some(previous_span) = @@ -3008,7 +3008,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Find the span after the crate name and if it has nested imports immediately // after the crate name already. - // ie. `use a::b::{c, d};` + // i.e. `use a::b::{c, d};` // ^^^^^^^^^ // or `use a::{b, c, d}};` // ^^^^^^^^^^^ @@ -3172,16 +3172,16 @@ fn find_span_of_binding_until_next_binding( let source_map = sess.source_map(); // Find the span of everything after the binding. - // ie. `a, e};` or `a};` + // i.e. `a, e};` or `a};` let binding_until_end = binding_span.with_hi(use_span.hi()); // Find everything after the binding but not including the binding. - // ie. `, e};` or `};` + // i.e. `, e};` or `};` let after_binding_until_end = binding_until_end.with_lo(binding_span.hi()); // Keep characters in the span until we encounter something that isn't a comma or // whitespace. - // ie. `, ` or ``. + // i.e. `, ` or ``. // // Also note whether a closing brace character was encountered. If there // was, then later go backwards to remove any trailing commas that are left. @@ -3195,7 +3195,7 @@ fn find_span_of_binding_until_next_binding( }); // Combine the two spans. - // ie. `a, ` or `a`. + // i.e. `a, ` or `a`. // // Removing these would leave `issue_52891::{d, e};` or `issue_52891::{d, e, };` let span = binding_span.with_hi(after_binding_until_next_binding.hi()); @@ -3219,7 +3219,7 @@ fn extend_span_to_previous_binding(sess: &Session, binding_span: Span) -> Option let source_map = sess.source_map(); // `prev_source` will contain all of the source that came before the span. - // Then split based on a command and take the first (ie. closest to our span) + // Then split based on a command and take the first (i.e. closest to our span) // snippet. In the example, this is a space. let prev_source = source_map.span_to_prev_source(binding_span).ok()?; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f0527740a58c7..7696b4b220d6c 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -70,7 +70,7 @@ pub(crate) enum ImportKind<'ra> { decls: PerNS>>, /// `true` for `...::{self [as target]}` imports, `false` otherwise. type_ns_only: bool, - /// Did this import result from a nested import? ie. `use foo::{bar, baz};` + /// Did this import result from a nested import? i.e. `use foo::{bar, baz};` nested: bool, /// The ID of the `UseTree` that imported this `Import`. /// diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index cd0556de5c22c..ebbbe36878daa 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -328,7 +328,7 @@ impl CheckCfg { return; } - // for `#[cfg(foo)]` (ie. cfg value is none) + // for `#[cfg(foo)]` (i.e. cfg value is none) let no_values = || { let mut values = FxHashSet::default(); values.insert(None); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b7255ba67dfdb..28a7fc3f0e912 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1057,6 +1057,7 @@ symbols! { immediate_abort: "immediate-abort", impl_header_lifetime_elision, impl_lint_pass, + impl_restriction, impl_trait_in_assoc_type, impl_trait_in_bindings, impl_trait_in_fn_trait_return, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 7d061e65df80b..739628f820653 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -160,7 +160,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } // The visitor captures the corresponding `hir::Ty` of the anonymous region -// in the case of structs ie. `hir::TyKind::Path`. +// in the case of structs i.e. `hir::TyKind::Path`. // This visitor would be invoked for each lifetime corresponding to a struct, // and would walk the types like Vec in the above example and Ref looking for the HIR // where that lifetime appears. This allows us to highlight the diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index cf6f9594c0027..885bf376b98ad 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2680,7 +2680,7 @@ impl AsInner for DirEntry { /// /// This function will only ever return an error of kind `NotFound` if the given /// path does not exist. Note that the inverse is not true, -/// ie. if a path does not exist, its removal may fail for a number of reasons, +/// i.e. if a path does not exist, its removal may fail for a number of reasons, /// such as insufficient permissions. /// /// # Examples @@ -3150,7 +3150,7 @@ pub fn create_dir_all>(path: P) -> io::Result<()> { /// /// This function will only ever return an error of kind `NotFound` if the given /// path does not exist. Note that the inverse is not true, -/// ie. if a path does not exist, its removal may fail for a number of reasons, +/// i.e. if a path does not exist, its removal may fail for a number of reasons, /// such as insufficient permissions. /// /// # Examples diff --git a/library/stdarch/Cargo.toml b/library/stdarch/Cargo.toml index 5979096439118..e3963a69879a1 100644 --- a/library/stdarch/Cargo.toml +++ b/library/stdarch/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "1" +resolver = "3" members = [ "crates/*", "examples", diff --git a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 2743896375cf3..a357449d51e3d 100644 --- a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ lld -RUN wget http://ci-mirrors.rust-lang.org/stdarch/sde-external-9.58.0-2025-06-16-lin.tar.xz -O sde.tar.xz +RUN wget http://ci-mirrors.rust-lang.org/stdarch/sde-external-10.5.0-2026-01-13-lin.tar.xz -O sde.tar.xz RUN mkdir intel-sde RUN tar -xJf sde.tar.xz --strip-components=1 -C intel-sde ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="/intel-sde/sde64 \ diff --git a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def index 342f7d83a63e3..acf023ed0dc49 100644 --- a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def +++ b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/cpuid.def @@ -12,7 +12,7 @@ # CPUID_VERSION = 1.0 # Input => Output # EAX ECX => EAX EBX ECX EDX -00000000 ******** => 00000024 756e6547 6c65746e 49656e69 +00000000 ******** => 00000029 756e6547 6c65746e 49656e69 00000001 ******** => 00400f10 00100800 7ffaf3ff bfebfbff 00000002 ******** => 76035a01 00f0b6ff 00000000 00c10000 00000003 ******** => 00000000 00000000 00000000 00000000 @@ -48,6 +48,7 @@ 0000001e 00000001 => 000001ff 00000000 00000000 00000000 00000024 00000000 => 00000001 00070002 00000000 00000000 #AVX10 00000024 00000001 => 00000000 00000000 00000004 00000000 +00000029 ******** => 00000000 00000001 00000000 00000000 80000000 ******** => 80000008 00000000 00000000 00000000 80000001 ******** => 00000000 00000000 00000121 2c100000 80000002 ******** => 00000000 00000000 00000000 00000000 diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 88afaae8b80d3..de64839661d6e 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -14131,26 +14131,7 @@ pub fn vmlaq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlal_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s16)"] @@ -14165,26 +14146,7 @@ pub fn vmlal_high_laneq_s16( c: int16x8_t, ) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlal_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_s32)"] @@ -14195,13 +14157,7 @@ pub fn vmlal_high_laneq_s16( #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlal_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlal_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_s32)"] @@ -14216,13 +14172,7 @@ pub fn vmlal_high_laneq_s32( c: int32x4_t, ) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u16)"] @@ -14237,26 +14187,7 @@ pub fn vmlal_high_lane_u16( c: uint16x4_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u16)"] @@ -14271,26 +14202,7 @@ pub fn vmlal_high_laneq_u16( c: uint16x8_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlal_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlal_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_lane_u32)"] @@ -14305,13 +14217,7 @@ pub fn vmlal_high_lane_u32( c: uint32x2_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlal_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_laneq_u32)"] @@ -14326,13 +14232,7 @@ pub fn vmlal_high_laneq_u32( c: uint32x4_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlal_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlal_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-add long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlal_high_n_s16)"] @@ -14475,26 +14375,7 @@ pub fn vmlsq_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t) -> float64x2_t #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlsl_high_lane_s16(a: int32x4_t, b: int16x8_t, c: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s16)"] @@ -14509,26 +14390,7 @@ pub fn vmlsl_high_laneq_s16( c: int16x8_t, ) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlsl_high_s16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_s16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_s32)"] @@ -14539,13 +14401,7 @@ pub fn vmlsl_high_laneq_s16( #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmlsl_high_lane_s32(a: int64x2_t, b: int32x4_t, c: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlsl_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_s32)"] @@ -14560,13 +14416,7 @@ pub fn vmlsl_high_laneq_s32( c: int32x4_t, ) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_s32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_s32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u16)"] @@ -14581,26 +14431,7 @@ pub fn vmlsl_high_lane_u16( c: uint16x4_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u16)"] @@ -14615,26 +14446,7 @@ pub fn vmlsl_high_laneq_u16( c: uint16x8_t, ) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmlsl_high_u16( - a, - b, - simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmlsl_high_u16(a, b, simd_shuffle!(c, c, [LANE as u32; 8])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_lane_u32)"] @@ -14649,13 +14461,7 @@ pub fn vmlsl_high_lane_u32( c: uint32x2_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmlsl_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_laneq_u32)"] @@ -14670,13 +14476,7 @@ pub fn vmlsl_high_laneq_u32( c: uint32x4_t, ) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmlsl_high_u32( - a, - b, - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmlsl_high_u32(a, b, simd_shuffle!(c, c, [LANE as u32; 4])) } } #[doc = "Multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmlsl_high_n_s16)"] @@ -14975,12 +14775,7 @@ pub fn vmul_lane_f64(a: float64x1_t, b: float64x1_t) -> float64 #[cfg(not(target_arch = "arm64ec"))] pub fn vmul_laneq_f16(a: float16x4_t, b: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - simd_mul( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f16)"] @@ -14992,25 +14787,7 @@ pub fn vmul_laneq_f16(a: float16x4_t, b: float16x8_t) -> float1 #[cfg(not(target_arch = "arm64ec"))] pub fn vmulq_laneq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - simd_mul( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmul_laneq_f64)"] @@ -15104,25 +14881,7 @@ pub fn vmulh_laneq_f16(a: f16, b: float16x8_t) -> f16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_s16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_s16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s16)"] @@ -15133,25 +14892,7 @@ pub fn vmull_high_lane_s16(a: int16x8_t, b: int16x4_t) -> int32 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmull_high_s16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_s16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_s32)"] @@ -15162,12 +14903,7 @@ pub fn vmull_high_laneq_s16(a: int16x8_t, b: int16x8_t) -> int3 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmull_high_s32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_s32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_s32)"] @@ -15178,12 +14914,7 @@ pub fn vmull_high_lane_s32(a: int32x4_t, b: int32x2_t) -> int64 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_s32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_s32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u16)"] @@ -15194,25 +14925,7 @@ pub fn vmull_high_laneq_s32(a: int32x4_t, b: int32x4_t) -> int6 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_u16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_u16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u16)"] @@ -15223,25 +14936,7 @@ pub fn vmull_high_lane_u16(a: uint16x8_t, b: uint16x4_t) -> uin #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> uint32x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmull_high_u16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmull_high_u16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_lane_u32)"] @@ -15252,12 +14947,7 @@ pub fn vmull_high_laneq_u16(a: uint16x8_t, b: uint16x8_t) -> ui #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uint64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmull_high_u32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_u32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_laneq_u32)"] @@ -15268,12 +14958,7 @@ pub fn vmull_high_lane_u32(a: uint32x4_t, b: uint32x2_t) -> uin #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmull_high_laneq_u32(a: uint32x4_t, b: uint32x4_t) -> uint64x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmull_high_u32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmull_high_u32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Multiply long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_high_n_s16)"] @@ -15436,7 +15121,7 @@ pub fn vmull_p64(a: p64, b: p64) -> p128 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulq_lane_f64(a: float64x2_t, b: float64x1_t) -> float64x2_t { static_assert!(LANE == 0); - unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulq_laneq_f64)"] @@ -15447,7 +15132,7 @@ pub fn vmulq_lane_f64(a: float64x2_t, b: float64x1_t) -> float6 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulq_laneq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { simd_mul(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmuls_lane_f32)"] @@ -15599,12 +15284,7 @@ pub fn vmulxq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vmulx_lane_f16(a: float16x4_t, b: float16x4_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulx_f16( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulx_f16(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f16)"] @@ -15616,12 +15296,7 @@ pub fn vmulx_lane_f16(a: float16x4_t, b: float16x4_t) -> float1 #[cfg(not(target_arch = "arm64ec"))] pub fn vmulx_laneq_f16(a: float16x4_t, b: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmulx_f16( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulx_f16(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f16)"] @@ -15633,25 +15308,7 @@ pub fn vmulx_laneq_f16(a: float16x4_t, b: float16x8_t) -> float #[cfg(not(target_arch = "arm64ec"))] pub fn vmulxq_lane_f16(a: float16x8_t, b: float16x4_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulxq_f16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmulxq_f16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f16)"] @@ -15663,25 +15320,7 @@ pub fn vmulxq_lane_f16(a: float16x8_t, b: float16x4_t) -> float #[cfg(not(target_arch = "arm64ec"))] pub fn vmulxq_laneq_f16(a: float16x8_t, b: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(LANE, 3); - unsafe { - vmulxq_f16( - a, - simd_shuffle!( - b, - b, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ), - ) - } + unsafe { vmulxq_f16(a, simd_shuffle!(b, b, [LANE as u32; 8])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f32)"] @@ -15692,7 +15331,7 @@ pub fn vmulxq_laneq_f16(a: float16x8_t, b: float16x8_t) -> floa #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulx_lane_f32(a: float32x2_t, b: float32x2_t) -> float32x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_laneq_f32)"] @@ -15703,7 +15342,7 @@ pub fn vmulx_lane_f32(a: float32x2_t, b: float32x2_t) -> float3 #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulx_laneq_f32(a: float32x2_t, b: float32x4_t) -> float32x2_t { static_assert_uimm_bits!(LANE, 2); - unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulx_f32(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_lane_f32)"] @@ -15714,12 +15353,7 @@ pub fn vmulx_laneq_f32(a: float32x2_t, b: float32x4_t) -> float #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_lane_f32(a: float32x4_t, b: float32x2_t) -> float32x4_t { static_assert_uimm_bits!(LANE, 1); - unsafe { - vmulxq_f32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulxq_f32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f32)"] @@ -15730,12 +15364,7 @@ pub fn vmulxq_lane_f32(a: float32x4_t, b: float32x2_t) -> float #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_laneq_f32(a: float32x4_t, b: float32x4_t) -> float32x4_t { static_assert_uimm_bits!(LANE, 2); - unsafe { - vmulxq_f32( - a, - simd_shuffle!(b, b, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]), - ) - } + unsafe { vmulxq_f32(a, simd_shuffle!(b, b, [LANE as u32; 4])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulxq_laneq_f64)"] @@ -15746,7 +15375,7 @@ pub fn vmulxq_laneq_f32(a: float32x4_t, b: float32x4_t) -> floa #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_laneq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t { static_assert_uimm_bits!(LANE, 1); - unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Floating-point multiply extended"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vmulx_lane_f64)"] @@ -15916,7 +15545,7 @@ pub fn vmulxh_laneq_f16(a: f16, b: float16x8_t) -> f16 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vmulxq_lane_f64(a: float64x2_t, b: float64x1_t) -> float64x2_t { static_assert!(LANE == 0); - unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32, LANE as u32])) } + unsafe { vmulxq_f64(a, simd_shuffle!(b, b, [LANE as u32; 2])) } } #[doc = "Negate"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vneg_f64)"] @@ -17916,8 +17545,7 @@ pub fn vqnegd_s64(a: i64) -> i64 { pub fn vqrdmlah_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlah_s16(a, b, c) } } @@ -17931,7 +17559,7 @@ pub fn vqrdmlah_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4 pub fn vqrdmlah_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlah_s32(a, b, c) } } @@ -17945,8 +17573,7 @@ pub fn vqrdmlah_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2 pub fn vqrdmlah_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlah_s16(a, b, c) } } @@ -17960,7 +17587,7 @@ pub fn vqrdmlah_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x pub fn vqrdmlah_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlah_s32(a, b, c) } } @@ -17974,20 +17601,7 @@ pub fn vqrdmlah_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x pub fn vqrdmlahq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlahq_s16(a, b, c) } } @@ -18001,8 +17615,7 @@ pub fn vqrdmlahq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x pub fn vqrdmlahq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlahq_s32(a, b, c) } } @@ -18016,20 +17629,7 @@ pub fn vqrdmlahq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x pub fn vqrdmlahq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlahq_s16(a, b, c) } } @@ -18043,8 +17643,7 @@ pub fn vqrdmlahq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16 pub fn vqrdmlahq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlahq_s32(a, b, c) } } @@ -18190,8 +17789,7 @@ pub fn vqrdmlahs_s32(a: i32, b: i32, c: i32) -> i32 { pub fn vqrdmlsh_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlsh_s16(a, b, c) } } @@ -18205,7 +17803,7 @@ pub fn vqrdmlsh_lane_s16(a: int16x4_t, b: int16x4_t, c: int16x4 pub fn vqrdmlsh_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlsh_s32(a, b, c) } } @@ -18219,8 +17817,7 @@ pub fn vqrdmlsh_lane_s32(a: int32x2_t, b: int32x2_t, c: int32x2 pub fn vqrdmlsh_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int16x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlsh_s16(a, b, c) } } @@ -18234,7 +17831,7 @@ pub fn vqrdmlsh_laneq_s16(a: int16x4_t, b: int16x4_t, c: int16x pub fn vqrdmlsh_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x4_t) -> int32x2_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32, LANE as u32]); + let c: int32x2_t = simd_shuffle!(c, c, [LANE as u32; 2]); vqrdmlsh_s32(a, b, c) } } @@ -18248,20 +17845,7 @@ pub fn vqrdmlsh_laneq_s32(a: int32x2_t, b: int32x2_t, c: int32x pub fn vqrdmlshq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlshq_s16(a, b, c) } } @@ -18275,8 +17859,7 @@ pub fn vqrdmlshq_lane_s16(a: int16x8_t, b: int16x8_t, c: int16x pub fn vqrdmlshq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x2_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 1); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlshq_s32(a, b, c) } } @@ -18290,20 +17873,7 @@ pub fn vqrdmlshq_lane_s32(a: int32x4_t, b: int32x4_t, c: int32x pub fn vqrdmlshq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(LANE, 3); unsafe { - let c: int16x8_t = simd_shuffle!( - c, - c, - [ - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32, - LANE as u32 - ] - ); + let c: int16x8_t = simd_shuffle!(c, c, [LANE as u32; 8]); vqrdmlshq_s16(a, b, c) } } @@ -18317,8 +17887,7 @@ pub fn vqrdmlshq_laneq_s16(a: int16x8_t, b: int16x8_t, c: int16 pub fn vqrdmlshq_laneq_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t) -> int32x4_t { static_assert_uimm_bits!(LANE, 2); unsafe { - let c: int32x4_t = - simd_shuffle!(c, c, [LANE as u32, LANE as u32, LANE as u32, LANE as u32]); + let c: int32x4_t = simd_shuffle!(c, c, [LANE as u32; 4]); vqrdmlshq_s32(a, b, c) } } @@ -25039,16 +24608,9 @@ pub unsafe fn vst1q_lane_f64(a: *mut f64, b: float64x2_t) { #[inline(always)] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] -#[cfg_attr(test, assert_instr(st1))] +#[cfg_attr(test, assert_instr(stp))] pub unsafe fn vst2_f64(a: *mut f64, b: float64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v1f64.p0" - )] - fn _vst2_f64(a: float64x1_t, b: float64x1_t, ptr: *mut i8); - } - _vst2_f64(b.0, b.1, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_lane_f64)"] @@ -25125,14 +24687,7 @@ pub unsafe fn vst2_lane_u64(a: *mut u64, b: uint64x1x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2f64.p0" - )] - fn _vst2q_f64(a: float64x2_t, b: float64x2_t, ptr: *mut i8); - } - _vst2q_f64(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s64)"] @@ -25143,14 +24698,7 @@ pub unsafe fn vst2q_f64(a: *mut f64, b: float64x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s64(a: *mut i64, b: int64x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2i64.p0" - )] - fn _vst2q_s64(a: int64x2_t, b: int64x2_t, ptr: *mut i8); - } - _vst2q_s64(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_lane_f64)"] @@ -25295,14 +24843,7 @@ pub unsafe fn vst2q_u64(a: *mut u64, b: uint64x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_f64(a: *mut f64, b: float64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v1f64.p0" - )] - fn _vst3_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t, ptr: *mut i8); - } - _vst3_f64(b.0, b.1, b.2, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_lane_f64)"] @@ -25379,14 +24920,7 @@ pub unsafe fn vst3_lane_u64(a: *mut u64, b: uint64x1x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st3))] pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v2f64.p0" - )] - fn _vst3q_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t, ptr: *mut i8); - } - _vst3q_f64(b.0, b.1, b.2, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s64)"] @@ -25397,14 +24931,7 @@ pub unsafe fn vst3q_f64(a: *mut f64, b: float64x2x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st3))] pub unsafe fn vst3q_s64(a: *mut i64, b: int64x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v2i64.p0" - )] - fn _vst3q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t, ptr: *mut i8); - } - _vst3q_s64(b.0, b.1, b.2, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_lane_f64)"] @@ -25549,14 +25076,7 @@ pub unsafe fn vst3q_u64(a: *mut u64, b: uint64x2x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_f64(a: *mut f64, b: float64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v1f64.p0" - )] - fn _vst4_f64(a: float64x1_t, b: float64x1_t, c: float64x1_t, d: float64x1_t, ptr: *mut i8); - } - _vst4_f64(b.0, b.1, b.2, b.3, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f64)"] @@ -25647,14 +25167,7 @@ pub unsafe fn vst4_lane_u64(a: *mut u64, b: uint64x1x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2f64.p0" - )] - fn _vst4q_f64(a: float64x2_t, b: float64x2_t, c: float64x2_t, d: float64x2_t, ptr: *mut i8); - } - _vst4q_f64(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f64, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s64)"] @@ -25665,14 +25178,7 @@ pub unsafe fn vst4q_f64(a: *mut f64, b: float64x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s64(a: *mut i64, b: int64x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2i64.p0" - )] - fn _vst4q_s64(a: int64x2_t, b: int64x2_t, c: int64x2_t, d: int64x2_t, ptr: *mut i8); - } - _vst4q_s64(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i64, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_lane_f64)"] diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs index 2df4ba7443314..2fbd2255aa0fd 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs @@ -1050,6 +1050,14 @@ mod tests { test_vld1q_f16_x2(f16, 16, float16x8x2_t, vst1q_f16_x2, vld1q_f16_x2); test_vld1q_f16_x3(f16, 24, float16x8x3_t, vst1q_f16_x3, vld1q_f16_x3); test_vld1q_f16_x4(f16, 32, float16x8x4_t, vst1q_f16_x4, vld1q_f16_x4); + + test_vld2_f16_x2(f16, 8, float16x4x2_t, vst2_f16, vld2_f16); + test_vld2_f16_x3(f16, 12, float16x4x3_t, vst3_f16, vld3_f16); + test_vld2_f16_x4(f16, 16, float16x4x4_t, vst4_f16, vld4_f16); + + test_vld2q_f16_x2(f16, 16, float16x8x2_t, vst2q_f16, vld2q_f16); + test_vld3q_f16_x3(f16, 24, float16x8x3_t, vst3q_f16, vld3q_f16); + test_vld4q_f16_x4(f16, 32, float16x8x4_t, vst4q_f16, vld4q_f16); } macro_rules! wide_store_load_roundtrip_aes { diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 45c83b880e907..a7c33917a88cc 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -10149,7 +10149,7 @@ pub fn vdotq_u32(a: uint32x4_t, b: uint8x16_t, c: uint8x16_t) -> uint32x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_f16)"] @@ -10174,13 +10174,7 @@ pub fn vdup_lane_f16(a: float16x4_t) -> float16x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_lane_f16(a: float16x4_t) -> float16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_f32)"] @@ -10341,7 +10335,7 @@ pub fn vdupq_lane_u32(a: uint32x2_t) -> uint32x4_t { )] pub fn vdup_lane_p16(a: poly16x4_t) -> poly16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s16)"] @@ -10364,7 +10358,7 @@ pub fn vdup_lane_p16(a: poly16x4_t) -> poly16x4_t { )] pub fn vdup_lane_s16(a: int16x4_t) -> int16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u16)"] @@ -10387,7 +10381,7 @@ pub fn vdup_lane_s16(a: int16x4_t) -> int16x4_t { )] pub fn vdup_lane_u16(a: uint16x4_t) -> uint16x4_t { static_assert_uimm_bits!(N, 2); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p16)"] @@ -10410,13 +10404,7 @@ pub fn vdup_lane_u16(a: uint16x4_t) -> uint16x4_t { )] pub fn vdupq_lane_p16(a: poly16x4_t) -> poly16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s16)"] @@ -10439,13 +10427,7 @@ pub fn vdupq_lane_p16(a: poly16x4_t) -> poly16x8_t { )] pub fn vdupq_lane_s16(a: int16x4_t) -> int16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u16)"] @@ -10468,13 +10450,7 @@ pub fn vdupq_lane_s16(a: int16x4_t) -> int16x8_t { )] pub fn vdupq_lane_u16(a: uint16x4_t) -> uint16x8_t { static_assert_uimm_bits!(N, 2); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_p8)"] @@ -10497,13 +10473,7 @@ pub fn vdupq_lane_u16(a: uint16x4_t) -> uint16x8_t { )] pub fn vdup_lane_p8(a: poly8x8_t) -> poly8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s8)"] @@ -10526,13 +10496,7 @@ pub fn vdup_lane_p8(a: poly8x8_t) -> poly8x8_t { )] pub fn vdup_lane_s8(a: int8x8_t) -> int8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_u8)"] @@ -10555,13 +10519,7 @@ pub fn vdup_lane_s8(a: int8x8_t) -> int8x8_t { )] pub fn vdup_lane_u8(a: uint8x8_t) -> uint8x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_p8)"] @@ -10584,16 +10542,7 @@ pub fn vdup_lane_u8(a: uint8x8_t) -> uint8x8_t { )] pub fn vdupq_lane_p8(a: poly8x8_t) -> poly8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_s8)"] @@ -10616,16 +10565,7 @@ pub fn vdupq_lane_p8(a: poly8x8_t) -> poly8x16_t { )] pub fn vdupq_lane_s8(a: int8x8_t) -> int8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_lane_u8)"] @@ -10648,16 +10588,7 @@ pub fn vdupq_lane_s8(a: int8x8_t) -> int8x16_t { )] pub fn vdupq_lane_u8(a: uint8x8_t) -> uint8x16_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_lane_s64)"] @@ -10728,7 +10659,7 @@ pub fn vdup_lane_u64(a: uint64x1_t) -> uint64x1_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_f16)"] @@ -10753,13 +10684,7 @@ pub fn vdup_laneq_f16(a: float16x8_t) -> float16x4_t { #[cfg(not(target_arch = "arm64ec"))] pub fn vdupq_laneq_f16(a: float16x8_t) -> float16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_f32)"] @@ -10920,7 +10845,7 @@ pub fn vdupq_laneq_u32(a: uint32x4_t) -> uint32x4_t { )] pub fn vdup_laneq_p16(a: poly16x8_t) -> poly16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s16)"] @@ -10943,7 +10868,7 @@ pub fn vdup_laneq_p16(a: poly16x8_t) -> poly16x4_t { )] pub fn vdup_laneq_s16(a: int16x8_t) -> int16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u16)"] @@ -10966,7 +10891,7 @@ pub fn vdup_laneq_s16(a: int16x8_t) -> int16x4_t { )] pub fn vdup_laneq_u16(a: uint16x8_t) -> uint16x4_t { static_assert_uimm_bits!(N, 3); - unsafe { simd_shuffle!(a, a, [N as u32, N as u32, N as u32, N as u32]) } + unsafe { simd_shuffle!(a, a, [N as u32; 4]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p16)"] @@ -10989,13 +10914,7 @@ pub fn vdup_laneq_u16(a: uint16x8_t) -> uint16x4_t { )] pub fn vdupq_laneq_p16(a: poly16x8_t) -> poly16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s16)"] @@ -11018,13 +10937,7 @@ pub fn vdupq_laneq_p16(a: poly16x8_t) -> poly16x8_t { )] pub fn vdupq_laneq_s16(a: int16x8_t) -> int16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u16)"] @@ -11047,13 +10960,7 @@ pub fn vdupq_laneq_s16(a: int16x8_t) -> int16x8_t { )] pub fn vdupq_laneq_u16(a: uint16x8_t) -> uint16x8_t { static_assert_uimm_bits!(N, 3); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_p8)"] @@ -11076,13 +10983,7 @@ pub fn vdupq_laneq_u16(a: uint16x8_t) -> uint16x8_t { )] pub fn vdup_laneq_p8(a: poly8x16_t) -> poly8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s8)"] @@ -11105,13 +11006,7 @@ pub fn vdup_laneq_p8(a: poly8x16_t) -> poly8x8_t { )] pub fn vdup_laneq_s8(a: int8x16_t) -> int8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_u8)"] @@ -11134,13 +11029,7 @@ pub fn vdup_laneq_s8(a: int8x16_t) -> int8x8_t { )] pub fn vdup_laneq_u8(a: uint8x16_t) -> uint8x8_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 8]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_p8)"] @@ -11163,16 +11052,7 @@ pub fn vdup_laneq_u8(a: uint8x16_t) -> uint8x8_t { )] pub fn vdupq_laneq_p8(a: poly8x16_t) -> poly8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_s8)"] @@ -11195,16 +11075,7 @@ pub fn vdupq_laneq_p8(a: poly8x16_t) -> poly8x16_t { )] pub fn vdupq_laneq_s8(a: int8x16_t) -> int8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdupq_laneq_u8)"] @@ -11227,16 +11098,7 @@ pub fn vdupq_laneq_s8(a: int8x16_t) -> int8x16_t { )] pub fn vdupq_laneq_u8(a: uint8x16_t) -> uint8x16_t { static_assert_uimm_bits!(N, 4); - unsafe { - simd_shuffle!( - a, - a, - [ - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, - N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32 - ] - ) - } + unsafe { simd_shuffle!(a, a, [N as u32; 16]) } } #[doc = "Set all vector lanes to the same value"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vdup_laneq_s64)"] @@ -35894,7 +35756,7 @@ pub fn vqdmulhq_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { pub fn vqdmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { static_assert_uimm_bits!(N, 2); unsafe { - let b: int16x4_t = simd_shuffle!(b, b, [N as u32, N as u32, N as u32, N as u32]); + let b: int16x4_t = simd_shuffle!(b, b, [N as u32; 4]); vqdmull_s16(a, b) } } @@ -35920,7 +35782,7 @@ pub fn vqdmull_lane_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { pub fn vqdmull_lane_s32(a: int32x2_t, b: int32x2_t) -> int64x2_t { static_assert_uimm_bits!(N, 1); unsafe { - let b: int32x2_t = simd_shuffle!(b, b, [N as u32, N as u32]); + let b: int32x2_t = simd_shuffle!(b, b, [N as u32; 2]); vqdmull_s32(a, b) } } @@ -37480,17 +37342,7 @@ pub fn vqrshrn_n_u16(a: uint16x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v8i8")] fn _vqrshrn_n_u16(a: uint16x8_t, n: uint16x8_t) -> uint8x8_t; } - unsafe { - _vqrshrn_n_u16( - a, - const { - uint16x8_t([ - -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, - -N as u16, - ]) - }, - ) - } + unsafe { _vqrshrn_n_u16(a, const { uint16x8_t([-N as u16; 8]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u32)"] @@ -37506,12 +37358,7 @@ pub fn vqrshrn_n_u32(a: uint32x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v4i16")] fn _vqrshrn_n_u32(a: uint32x4_t, n: uint32x4_t) -> uint16x4_t; } - unsafe { - _vqrshrn_n_u32( - a, - const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }, - ) - } + unsafe { _vqrshrn_n_u32(a, const { uint32x4_t([-N as u32; 4]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u64)"] @@ -37527,7 +37374,7 @@ pub fn vqrshrn_n_u64(a: uint64x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqrshiftnu.v2i32")] fn _vqrshrn_n_u64(a: uint64x2_t, n: uint64x2_t) -> uint32x2_t; } - unsafe { _vqrshrn_n_u64(a, const { uint64x2_t([-N as u64, -N as u64]) }) } + unsafe { _vqrshrn_n_u64(a, const { uint64x2_t([-N as u64; 2]) }) } } #[doc = "Unsigned signed saturating rounded shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqrshrn_n_u16)"] @@ -38922,17 +38769,7 @@ pub fn vqshrn_n_u16(a: uint16x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v8i8")] fn _vqshrn_n_u16(a: uint16x8_t, n: uint16x8_t) -> uint8x8_t; } - unsafe { - _vqshrn_n_u16( - a, - const { - uint16x8_t([ - -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, - -N as u16, - ]) - }, - ) - } + unsafe { _vqshrn_n_u16(a, const { uint16x8_t([-N as u16; 8]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u32)"] @@ -38948,12 +38785,7 @@ pub fn vqshrn_n_u32(a: uint32x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v4i16")] fn _vqshrn_n_u32(a: uint32x4_t, n: uint32x4_t) -> uint16x4_t; } - unsafe { - _vqshrn_n_u32( - a, - const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }, - ) - } + unsafe { _vqshrn_n_u32(a, const { uint32x4_t([-N as u32; 4]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u64)"] @@ -38969,7 +38801,7 @@ pub fn vqshrn_n_u64(a: uint64x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftnu.v2i32")] fn _vqshrn_n_u64(a: uint64x2_t, n: uint64x2_t) -> uint32x2_t; } - unsafe { _vqshrn_n_u64(a, const { uint64x2_t([-N as u64, -N as u64]) }) } + unsafe { _vqshrn_n_u64(a, const { uint64x2_t([-N as u64; 2]) }) } } #[doc = "Unsigned saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_u16)"] @@ -66001,14 +65833,7 @@ pub unsafe fn vst2q_f16(a: *mut f16, b: float16x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2f32.p0" - )] - fn _vst2_f32(a: float32x2_t, b: float32x2_t, ptr: *mut i8); - } - _vst2_f32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f32, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_f32)"] @@ -66020,14 +65845,7 @@ pub unsafe fn vst2_f32(a: *mut f32, b: float32x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4f32.p0" - )] - fn _vst2q_f32(a: float32x4_t, b: float32x4_t, ptr: *mut i8); - } - _vst2q_f32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(f32, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s8)"] @@ -66039,14 +65857,7 @@ pub unsafe fn vst2q_f32(a: *mut f32, b: float32x4x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v8i8.p0" - )] - fn _vst2_s8(a: int8x8_t, b: int8x8_t, ptr: *mut i8); - } - _vst2_s8(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i8, 8, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s8)"] @@ -66058,14 +65869,7 @@ pub unsafe fn vst2_s8(a: *mut i8, b: int8x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v16i8.p0" - )] - fn _vst2q_s8(a: int8x16_t, b: int8x16_t, ptr: *mut i8); - } - _vst2q_s8(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i8, 16, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s16)"] @@ -66077,14 +65881,7 @@ pub unsafe fn vst2q_s8(a: *mut i8, b: int8x16x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4i16.p0" - )] - fn _vst2_s16(a: int16x4_t, b: int16x4_t, ptr: *mut i8); - } - _vst2_s16(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i16, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s16)"] @@ -66096,14 +65893,7 @@ pub unsafe fn vst2_s16(a: *mut i16, b: int16x4x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v8i16.p0" - )] - fn _vst2q_s16(a: int16x8_t, b: int16x8_t, ptr: *mut i8); - } - _vst2q_s16(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i16, 8, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s32)"] @@ -66115,14 +65905,7 @@ pub unsafe fn vst2q_s16(a: *mut i16, b: int16x8x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v2i32.p0" - )] - fn _vst2_s32(a: int32x2_t, b: int32x2_t, ptr: *mut i8); - } - _vst2_s32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i32, 2, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2q_s32)"] @@ -66134,14 +65917,7 @@ pub unsafe fn vst2_s32(a: *mut i32, b: int32x2x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st2))] pub unsafe fn vst2q_s32(a: *mut i32, b: int32x4x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v4i32.p0" - )] - fn _vst2q_s32(a: int32x4_t, b: int32x4_t, ptr: *mut i8); - } - _vst2q_s32(b.0, b.1, a as _) + crate::core_arch::macros::interleaving_store!(i32, 4, 2, a, b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_f32)"] @@ -66865,11 +66641,7 @@ pub unsafe fn vst2_p64(a: *mut p64, b: poly64x1x2_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst2.v1i64.p0")] - fn _vst2_s64(ptr: *mut i8, a: int64x1_t, b: int64x1_t, size: i32); - } - _vst2_s64(a as _, b.0, b.1, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_s64)"] @@ -66881,14 +66653,7 @@ pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst2_s64(a: *mut i64, b: int64x1x2_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st2.v1i64.p0" - )] - fn _vst2_s64(a: int64x1_t, b: int64x1_t, ptr: *mut i8); - } - _vst2_s64(b.0, b.1, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 2-element structures from two registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst2_u64)"] @@ -67233,11 +66998,7 @@ pub unsafe fn vst3q_f16(a: *mut f16, b: float16x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v2f32")] - fn _vst3_f32(ptr: *mut i8, a: float32x2_t, b: float32x2_t, c: float32x2_t, size: i32); - } - _vst3_f32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(f32, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_f32)"] @@ -67249,11 +67010,7 @@ pub unsafe fn vst3_f32(a: *mut f32, b: float32x2x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4f32")] - fn _vst3q_f32(ptr: *mut i8, a: float32x4_t, b: float32x4_t, c: float32x4_t, size: i32); - } - _vst3q_f32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(f32, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s8)"] @@ -67265,11 +67022,7 @@ pub unsafe fn vst3q_f32(a: *mut f32, b: float32x4x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v8i8")] - fn _vst3_s8(ptr: *mut i8, a: int8x8_t, b: int8x8_t, c: int8x8_t, size: i32); - } - _vst3_s8(a as _, b.0, b.1, b.2, 1) + crate::core_arch::macros::interleaving_store!(i8, 8, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s8)"] @@ -67281,11 +67034,7 @@ pub unsafe fn vst3_s8(a: *mut i8, b: int8x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v16i8")] - fn _vst3q_s8(ptr: *mut i8, a: int8x16_t, b: int8x16_t, c: int8x16_t, size: i32); - } - _vst3q_s8(a as _, b.0, b.1, b.2, 1) + crate::core_arch::macros::interleaving_store!(i8, 16, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s16)"] @@ -67297,11 +67046,7 @@ pub unsafe fn vst3q_s8(a: *mut i8, b: int8x16x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4i16")] - fn _vst3_s16(ptr: *mut i8, a: int16x4_t, b: int16x4_t, c: int16x4_t, size: i32); - } - _vst3_s16(a as _, b.0, b.1, b.2, 2) + crate::core_arch::macros::interleaving_store!(i16, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s16)"] @@ -67313,11 +67058,7 @@ pub unsafe fn vst3_s16(a: *mut i16, b: int16x4x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v8i16")] - fn _vst3q_s16(ptr: *mut i8, a: int16x8_t, b: int16x8_t, c: int16x8_t, size: i32); - } - _vst3q_s16(a as _, b.0, b.1, b.2, 2) + crate::core_arch::macros::interleaving_store!(i16, 8, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s32)"] @@ -67329,11 +67070,7 @@ pub unsafe fn vst3q_s16(a: *mut i16, b: int16x8x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v2i32")] - fn _vst3_s32(ptr: *mut i8, a: int32x2_t, b: int32x2_t, c: int32x2_t, size: i32); - } - _vst3_s32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(i32, 2, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3q_s32)"] @@ -67345,11 +67082,7 @@ pub unsafe fn vst3_s32(a: *mut i32, b: int32x2x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(vst3))] pub unsafe fn vst3q_s32(a: *mut i32, b: int32x4x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v4i32")] - fn _vst3q_s32(ptr: *mut i8, a: int32x4_t, b: int32x4_t, c: int32x4_t, size: i32); - } - _vst3q_s32(a as _, b.0, b.1, b.2, 4) + crate::core_arch::macros::interleaving_store!(i32, 4, 3, a, b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_f32)"] @@ -68153,14 +67886,7 @@ pub unsafe fn vst3_p64(a: *mut p64, b: poly64x1x3_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st3.v1i64.p0" - )] - fn _vst3_s64(a: int64x1_t, b: int64x1_t, c: int64x1_t, ptr: *mut i8); - } - _vst3_s64(b.0, b.1, b.2, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_s64)"] @@ -68172,11 +67898,7 @@ pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst3_s64(a: *mut i64, b: int64x1x3_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst3.p0.v1i64")] - fn _vst3_s64(ptr: *mut i8, a: int64x1_t, b: int64x1_t, c: int64x1_t, size: i32); - } - _vst3_s64(a as _, b.0, b.1, b.2, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 3-element structures from three registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst3_u64)"] @@ -68712,14 +68434,7 @@ pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2f32.p0" - )] - fn _vst4_f32(a: float32x2_t, b: float32x2_t, c: float32x2_t, d: float32x2_t, ptr: *mut i8); - } - _vst4_f32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f32, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_f32)"] @@ -68731,14 +68446,7 @@ pub unsafe fn vst4_f32(a: *mut f32, b: float32x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4f32.p0" - )] - fn _vst4q_f32(a: float32x4_t, b: float32x4_t, c: float32x4_t, d: float32x4_t, ptr: *mut i8); - } - _vst4q_f32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(f32, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s8)"] @@ -68750,14 +68458,7 @@ pub unsafe fn vst4q_f32(a: *mut f32, b: float32x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v8i8.p0" - )] - fn _vst4_s8(a: int8x8_t, b: int8x8_t, c: int8x8_t, d: int8x8_t, ptr: *mut i8); - } - _vst4_s8(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i8, 8, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s8)"] @@ -68769,14 +68470,7 @@ pub unsafe fn vst4_s8(a: *mut i8, b: int8x8x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v16i8.p0" - )] - fn _vst4q_s8(a: int8x16_t, b: int8x16_t, c: int8x16_t, d: int8x16_t, ptr: *mut i8); - } - _vst4q_s8(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i8, 16, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s16)"] @@ -68788,14 +68482,7 @@ pub unsafe fn vst4q_s8(a: *mut i8, b: int8x16x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4i16.p0" - )] - fn _vst4_s16(a: int16x4_t, b: int16x4_t, c: int16x4_t, d: int16x4_t, ptr: *mut i8); - } - _vst4_s16(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i16, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s16)"] @@ -68807,14 +68494,7 @@ pub unsafe fn vst4_s16(a: *mut i16, b: int16x4x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v8i16.p0" - )] - fn _vst4q_s16(a: int16x8_t, b: int16x8_t, c: int16x8_t, d: int16x8_t, ptr: *mut i8); - } - _vst4q_s16(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i16, 8, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s32)"] @@ -68826,14 +68506,7 @@ pub unsafe fn vst4q_s16(a: *mut i16, b: int16x8x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v2i32.p0" - )] - fn _vst4_s32(a: int32x2_t, b: int32x2_t, c: int32x2_t, d: int32x2_t, ptr: *mut i8); - } - _vst4_s32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i32, 2, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4q_s32)"] @@ -68845,14 +68518,7 @@ pub unsafe fn vst4_s32(a: *mut i32, b: int32x2x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(st4))] pub unsafe fn vst4q_s32(a: *mut i32, b: int32x4x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v4i32.p0" - )] - fn _vst4q_s32(a: int32x4_t, b: int32x4_t, c: int32x4_t, d: int32x4_t, ptr: *mut i8); - } - _vst4q_s32(b.0, b.1, b.2, b.3, a as _) + crate::core_arch::macros::interleaving_store!(i32, 4, 4, a, b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_lane_f16)"] @@ -69576,18 +69242,7 @@ pub unsafe fn vst4_p64(a: *mut p64, b: poly64x1x4_t) { #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vst4.p0.v1i64")] - fn _vst4_s64( - ptr: *mut i8, - a: int64x1_t, - b: int64x1_t, - c: int64x1_t, - d: int64x1_t, - size: i32, - ); - } - _vst4_s64(a as _, b.0, b.1, b.2, b.3, 8) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_s64)"] @@ -69599,14 +69254,7 @@ pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(nop))] pub unsafe fn vst4_s64(a: *mut i64, b: int64x1x4_t) { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.st4.v1i64.p0" - )] - fn _vst4_s64(a: int64x1_t, b: int64x1_t, c: int64x1_t, d: int64x1_t, ptr: *mut i8); - } - _vst4_s64(b.0, b.1, b.2, b.3, a as _) + core::ptr::write_unaligned(a.cast(), b) } #[doc = "Store multiple 4-element structures from four registers"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vst4_u64)"] diff --git a/library/stdarch/crates/core_arch/src/macros.rs b/library/stdarch/crates/core_arch/src/macros.rs index 9f6922efeeb7d..00e92428b3e7e 100644 --- a/library/stdarch/crates/core_arch/src/macros.rs +++ b/library/stdarch/crates/core_arch/src/macros.rs @@ -187,6 +187,17 @@ macro_rules! simd_masked_store { }; } +/// The first N indices `[0, 1, 2, ...]`. +pub(crate) const fn identity() -> [u32; N] { + let mut out = [0u32; N]; + let mut i = 0usize; + while i < N { + out[i] = i as u32; + i += 1; + } + out +} + /// The first N even indices `[0, 2, 4, ...]`. pub(crate) const fn even() -> [u32; N] { let mut out = [0u32; N]; @@ -226,12 +237,12 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 2, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::transmute; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 2 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + let w: W = $crate::ptr::read_unaligned($ptr as *const W); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 2, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 2, 1>()); @@ -242,12 +253,20 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 3, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::{MaybeUninit, transmute}; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 3 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + // NOTE: repr(simd) adds padding to make the total size a power of two. + // Hence reading W from ptr might read out of bounds. + let mut mem = MaybeUninit::::uninit(); + $crate::ptr::copy_nonoverlapping( + $ptr.cast::<$elem>(), + mem.as_mut_ptr().cast::<$elem>(), + $lanes * 3, + ); + let w = mem.assume_init(); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 3, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 3, 1>()); @@ -259,12 +278,12 @@ macro_rules! deinterleaving_load { ($elem:ty, $lanes:literal, 4, $ptr:expr) => {{ use $crate::core_arch::macros::deinterleave_mask; use $crate::core_arch::simd::Simd; - use $crate::{mem::transmute, ptr}; + use $crate::mem::transmute; type V = Simd<$elem, $lanes>; type W = Simd<$elem, { $lanes * 4 }>; - let w: W = ptr::read_unaligned($ptr as *const W); + let w: W = $crate::ptr::read_unaligned($ptr as *const W); let v0: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 4, 0>()); let v1: V = simd_shuffle!(w, w, deinterleave_mask::<$lanes, 4, 1>()); @@ -277,3 +296,66 @@ macro_rules! deinterleaving_load { #[allow(unused)] pub(crate) use deinterleaving_load; + +pub(crate) const fn interleave_mask() +-> [u32; LANES] { + let mut out = [0u32; LANES]; + let mut j = 0usize; + while j < LANES { + out[j] = ((j % K) * N + j / K) as u32; + j += 1; + } + out +} + +#[allow(unused)] +macro_rules! interleaving_store { + ($elem:ty, $lanes:literal, 2, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::interleave_mask; + use $crate::core_arch::simd::Simd; + + type W = Simd<$elem, { $lanes * 2 }>; + let w: W = simd_shuffle!($v.0, $v.1, interleave_mask::<{ $lanes * 2 }, $lanes, 2>()); + $crate::ptr::write_unaligned($ptr as *mut W, w); + }}; + + // N = 3 + ($elem:ty, $lanes:literal, 3, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::{identity, interleave_mask}; + use $crate::core_arch::simd::Simd; + + let v0v1: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.0, $v.1, identity::<{ $lanes * 2 }>()); + let v2v2: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.2, $v.2, identity::<{ $lanes * 2 }>()); + + type W = Simd<$elem, { $lanes * 3 }>; + + // NOTE: repr(simd) adds padding to make the total size a power of two. + // Hence writing W to ptr might write out of bounds. + let w: W = simd_shuffle!(v0v1, v2v2, interleave_mask::<{ $lanes * 3 }, $lanes, 3>()); + $crate::ptr::copy_nonoverlapping( + (&w as *const W).cast::<$elem>(), + $ptr.cast::<$elem>(), + $lanes * 3, + ); + }}; + + // N = 4 + ($elem:ty, $lanes:literal, 4, $ptr:expr, $v:expr) => {{ + use $crate::core_arch::macros::{identity, interleave_mask}; + use $crate::core_arch::simd::Simd; + + let v0v1: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.0, $v.1, identity::<{ $lanes * 2 }>()); + let v2v3: Simd<$elem, { $lanes * 2 }> = + simd_shuffle!($v.2, $v.3, identity::<{ $lanes * 2 }>()); + + type W = Simd<$elem, { $lanes * 4 }>; + let w: W = simd_shuffle!(v0v1, v2v3, interleave_mask::<{ $lanes * 4 }, $lanes, 4>()); + $crate::ptr::write_unaligned($ptr as *mut W, w); + }}; +} + +#[allow(unused)] +pub(crate) use interleaving_store; diff --git a/library/stdarch/crates/core_arch/src/x86/avx2.rs b/library/stdarch/crates/core_arch/src/x86/avx2.rs index 04a88e461f752..b49ad9522a412 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx2.rs @@ -2315,7 +2315,7 @@ pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(simd_or(a.as_i32x8(), b.as_i32x8())) } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using signed saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi16) @@ -2323,11 +2323,33 @@ pub const fn _mm256_or_si256(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpacksswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packsswb(a.as_i16x16(), b.as_i16x16())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { + unsafe { + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + let clamped_b = simd_imax(simd_imin(b.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, 08, 10, 12, 14, // a-lo i16 to i8 conversions + 32, 34, 36, 38, 40, 42, 44, 46, // b-lo + 16, 18, 20, 22, 24, 26, 28, 30, // a-hi + 48, 50, 52, 54, 56, 58, 60, 62, // b-hi + ]; + let result: i8x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using signed saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packs_epi32) @@ -2335,11 +2357,33 @@ pub fn _mm256_packs_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packssdw(a.as_i32x8(), b.as_i32x8())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { + unsafe { + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + let clamped_b = simd_imax(simd_imin(b.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + + #[rustfmt::skip] + const IDXS: [u32; 16] = [ + 00, 02, 04, 06, // a-lo i32 to i16 conversions + 16, 18, 20, 22, // b-lo + 08, 10, 12, 14, // a-hi + 24, 26, 28, 30, // b-hi + ]; + let result: i16x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi16) @@ -2347,11 +2391,33 @@ pub fn _mm256_packs_epi32(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packuswb(a.as_i16x16(), b.as_i16x16())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { + unsafe { + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + let clamped_b = simd_imax(simd_imin(b.as_i16x16(), max), min) + .as_m256i() + .as_i8x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, 08, 10, 12, 14, // a-lo i16 to u8 conversions + 32, 34, 36, 38, 40, 42, 44, 46, // b-lo + 16, 18, 20, 22, 24, 26, 28, 30, // a-hi + 48, 50, 52, 54, 56, 58, 60, 62, // b-hi + ]; + let result: i8x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_packus_epi32) @@ -2359,8 +2425,30 @@ pub fn _mm256_packus_epi16(a: __m256i, b: __m256i) -> __m256i { #[target_feature(enable = "avx2")] #[cfg_attr(test, assert_instr(vpackusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i { - unsafe { transmute(packusdw(a.as_i32x8(), b.as_i32x8())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_packus_epi32(a: __m256i, b: __m256i) -> __m256i { + unsafe { + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + let clamped_b = simd_imax(simd_imin(b.as_i32x8(), max), min) + .as_m256i() + .as_i16x16(); + + #[rustfmt::skip] + const IDXS: [u32; 16] = [ + 00, 02, 04, 06, // a-lo i32 to u16 conversions + 16, 18, 20, 22, // b-lo + 08, 10, 12, 14, // a-hi + 24, 26, 28, 30, // b-hi + ]; + let result: i16x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m256i() + } } /// Permutes packed 32-bit integers from `a` according to the content of `b`. @@ -3827,14 +3915,6 @@ unsafe extern "C" { fn mpsadbw(a: u8x32, b: u8x32, imm8: i8) -> u16x16; #[link_name = "llvm.x86.avx2.pmul.hr.sw"] fn pmulhrsw(a: i16x16, b: i16x16) -> i16x16; - #[link_name = "llvm.x86.avx2.packsswb"] - fn packsswb(a: i16x16, b: i16x16) -> i8x32; - #[link_name = "llvm.x86.avx2.packssdw"] - fn packssdw(a: i32x8, b: i32x8) -> i16x16; - #[link_name = "llvm.x86.avx2.packuswb"] - fn packuswb(a: i16x16, b: i16x16) -> u8x32; - #[link_name = "llvm.x86.avx2.packusdw"] - fn packusdw(a: i32x8, b: i32x8) -> u16x16; #[link_name = "llvm.x86.avx2.psad.bw"] fn psadbw(a: u8x32, b: u8x32) -> u64x4; #[link_name = "llvm.x86.avx2.psign.b"] @@ -4988,7 +5068,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packs_epi16() { + const fn test_mm256_packs_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_packs_epi16(a, b); @@ -5004,7 +5084,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packs_epi32() { + const fn test_mm256_packs_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_packs_epi32(a, b); @@ -5014,7 +5094,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packus_epi16() { + const fn test_mm256_packus_epi16() { let a = _mm256_set1_epi16(2); let b = _mm256_set1_epi16(4); let r = _mm256_packus_epi16(a, b); @@ -5030,7 +5110,7 @@ mod tests { } #[simd_test(enable = "avx2")] - fn test_mm256_packus_epi32() { + const fn test_mm256_packus_epi32() { let a = _mm256_set1_epi32(2); let b = _mm256_set1_epi32(4); let r = _mm256_packus_epi32(a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs index 3ba171c0fa50f..b41f8576cfe54 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512bw.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512bw.rs @@ -6523,8 +6523,34 @@ pub fn _mm_maskz_maddubs_epi16(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackssdw(a.as_i32x16(), b.as_i32x16())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { + unsafe { + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + let clamped_b = simd_imax(simd_imin(b.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, + 32, 34, 36, 38, + 08, 10, 12, 14, + 40, 42, 44, 46, + 16, 18, 20, 22, + 48, 50, 52, 54, + 24, 26, 28, 30, + 56, 58, 60, 62, + ]; + let result: i16x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 32-bit integers from a and b to packed 16-bit integers using signed saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6534,7 +6560,13 @@ pub fn _mm512_packs_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_mask_packs_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packs_epi32( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packs_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, src.as_i16x32())) @@ -6548,7 +6580,8 @@ pub fn _mm512_mask_packs_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packs_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, i16x32::ZERO)) @@ -6562,7 +6595,13 @@ pub fn _mm512_maskz_packs_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm256_mask_packs_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packs_epi32( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packs_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, src.as_i16x16())) @@ -6590,7 +6629,8 @@ pub fn _mm256_maskz_packs_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, src.as_i16x8())) @@ -6604,7 +6644,8 @@ pub fn _mm_mask_packs_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) - #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackssdw))] -pub fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, i16x8::ZERO)) @@ -6618,8 +6659,34 @@ pub fn _mm_maskz_packs_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpacksswb(a.as_i16x32(), b.as_i16x32())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { + unsafe { + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + let clamped_b = simd_imax(simd_imin(b.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + + #[rustfmt::skip] + const IDXS: [u32; 64] = [ + 000, 002, 004, 006, 008, 010, 012, 014, + 064, 066, 068, 070, 072, 074, 076, 078, + 016, 018, 020, 022, 024, 026, 028, 030, + 080, 082, 084, 086, 088, 090, 092, 094, + 032, 034, 036, 038, 040, 042, 044, 046, + 096, 098, 100, 102, 104, 106, 108, 110, + 048, 050, 052, 054, 056, 058, 060, 062, + 112, 114, 116, 118, 120, 122, 124, 126, + ]; + let result: i8x64 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 16-bit integers from a and b to packed 8-bit integers using signed saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6629,7 +6696,13 @@ pub fn _mm512_packs_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_mask_packs_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packs_epi16( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packs_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, src.as_i8x64())) @@ -6643,7 +6716,8 @@ pub fn _mm512_mask_packs_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packs_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, i8x64::ZERO)) @@ -6657,7 +6731,13 @@ pub fn _mm512_maskz_packs_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm256_mask_packs_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packs_epi16( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packs_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, src.as_i8x32())) @@ -6671,7 +6751,8 @@ pub fn _mm256_mask_packs_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packs_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, i8x32::ZERO)) @@ -6685,7 +6766,8 @@ pub fn _mm256_maskz_packs_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, src.as_i8x16())) @@ -6699,7 +6781,8 @@ pub fn _mm_mask_packs_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpacksswb))] -pub fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packs_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, i8x16::ZERO)) @@ -6713,8 +6796,34 @@ pub fn _mm_maskz_packs_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackusdw(a.as_i32x16(), b.as_i32x16())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { + unsafe { + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + let clamped_b = simd_imax(simd_imin(b.as_i32x16(), max), min) + .as_m512i() + .as_i16x32(); + + #[rustfmt::skip] + const IDXS: [u32; 32] = [ + 00, 02, 04, 06, + 32, 34, 36, 38, + 08, 10, 12, 14, + 40, 42, 44, 46, + 16, 18, 20, 22, + 48, 50, 52, 54, + 24, 26, 28, 30, + 56, 58, 60, 62, + ]; + let result: i16x32 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 32-bit integers from a and b to packed 16-bit integers using unsigned saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6724,7 +6833,13 @@ pub fn _mm512_packus_epi32(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_mask_packus_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packus_epi32( + src: __m512i, + k: __mmask32, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packus_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, src.as_i16x32())) @@ -6738,7 +6853,8 @@ pub fn _mm512_mask_packus_epi32(src: __m512i, k: __mmask32, a: __m512i, b: __m51 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packus_epi32(a, b).as_i16x32(); transmute(simd_select_bitmask(k, pack, i16x32::ZERO)) @@ -6752,7 +6868,13 @@ pub fn _mm512_maskz_packus_epi32(k: __mmask32, a: __m512i, b: __m512i) -> __m512 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm256_mask_packus_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packus_epi32( + src: __m256i, + k: __mmask16, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packus_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, src.as_i16x16())) @@ -6766,7 +6888,8 @@ pub fn _mm256_mask_packus_epi32(src: __m256i, k: __mmask16, a: __m256i, b: __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packus_epi32(a, b).as_i16x16(); transmute(simd_select_bitmask(k, pack, i16x16::ZERO)) @@ -6780,7 +6903,8 @@ pub fn _mm256_maskz_packus_epi32(k: __mmask16, a: __m256i, b: __m256i) -> __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, src.as_i16x8())) @@ -6794,7 +6918,8 @@ pub fn _mm_mask_packus_epi32(src: __m128i, k: __mmask8, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackusdw))] -pub fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi32(a, b).as_i16x8(); transmute(simd_select_bitmask(k, pack, i16x8::ZERO)) @@ -6808,8 +6933,34 @@ pub fn _mm_maskz_packus_epi32(k: __mmask8, a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { - unsafe { transmute(vpackuswb(a.as_i16x32(), b.as_i16x32())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { + unsafe { + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + let clamped_b = simd_imax(simd_imin(b.as_i16x32(), max), min) + .as_m512i() + .as_i8x64(); + + #[rustfmt::skip] + const IDXS: [u32; 64] = [ + 000, 002, 004, 006, 008, 010, 012, 014, + 064, 066, 068, 070, 072, 074, 076, 078, + 016, 018, 020, 022, 024, 026, 028, 030, + 080, 082, 084, 086, 088, 090, 092, 094, + 032, 034, 036, 038, 040, 042, 044, 046, + 096, 098, 100, 102, 104, 106, 108, 110, + 048, 050, 052, 054, 056, 058, 060, 062, + 112, 114, 116, 118, 120, 122, 124, 126, + ]; + let result: i8x64 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m512i() + } } /// Convert packed signed 16-bit integers from a and b to packed 8-bit integers using unsigned saturation, and store the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set). @@ -6819,7 +6970,13 @@ pub fn _mm512_packus_epi16(a: __m512i, b: __m512i) -> __m512i { #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_mask_packus_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_mask_packus_epi16( + src: __m512i, + k: __mmask64, + a: __m512i, + b: __m512i, +) -> __m512i { unsafe { let pack = _mm512_packus_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, src.as_i8x64())) @@ -6833,7 +6990,8 @@ pub fn _mm512_mask_packus_epi16(src: __m512i, k: __mmask64, a: __m512i, b: __m51 #[target_feature(enable = "avx512bw")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512i { unsafe { let pack = _mm512_packus_epi16(a, b).as_i8x64(); transmute(simd_select_bitmask(k, pack, i8x64::ZERO)) @@ -6847,7 +7005,13 @@ pub fn _mm512_maskz_packus_epi16(k: __mmask64, a: __m512i, b: __m512i) -> __m512 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm256_mask_packus_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_mask_packus_epi16( + src: __m256i, + k: __mmask32, + a: __m256i, + b: __m256i, +) -> __m256i { unsafe { let pack = _mm256_packus_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, src.as_i8x32())) @@ -6861,7 +7025,8 @@ pub fn _mm256_mask_packus_epi16(src: __m256i, k: __mmask32, a: __m256i, b: __m25 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256i { unsafe { let pack = _mm256_packus_epi16(a, b).as_i8x32(); transmute(simd_select_bitmask(k, pack, i8x32::ZERO)) @@ -6875,7 +7040,8 @@ pub fn _mm256_maskz_packus_epi16(k: __mmask32, a: __m256i, b: __m256i) -> __m256 #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, src.as_i8x16())) @@ -6889,7 +7055,8 @@ pub fn _mm_mask_packus_epi16(src: __m128i, k: __mmask16, a: __m128i, b: __m128i) #[target_feature(enable = "avx512bw,avx512vl")] #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpackuswb))] -pub fn _mm_maskz_packus_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_maskz_packus_epi16(k: __mmask16, a: __m128i, b: __m128i) -> __m128i { unsafe { let pack = _mm_packus_epi16(a, b).as_i8x16(); transmute(simd_select_bitmask(k, pack, i8x16::ZERO)) @@ -12606,15 +12773,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.pmaddubs.w.512"] fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32; - #[link_name = "llvm.x86.avx512.packssdw.512"] - fn vpackssdw(a: i32x16, b: i32x16) -> i16x32; - #[link_name = "llvm.x86.avx512.packsswb.512"] - fn vpacksswb(a: i16x32, b: i16x32) -> i8x64; - #[link_name = "llvm.x86.avx512.packusdw.512"] - fn vpackusdw(a: i32x16, b: i32x16) -> u16x32; - #[link_name = "llvm.x86.avx512.packuswb.512"] - fn vpackuswb(a: i16x32, b: i16x32) -> u8x64; - #[link_name = "llvm.x86.avx512.psll.w.512"] fn vpsllw(a: i16x32, count: i16x8) -> i16x32; @@ -17702,7 +17860,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packs_epi32() { + const fn test_mm512_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1); let r = _mm512_packs_epi32(a, b); @@ -17713,7 +17871,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packs_epi32() { + const fn test_mm512_mask_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1 << 16 | 1); let r = _mm512_mask_packs_epi32(a, 0, a, b); @@ -17726,7 +17884,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packs_epi32() { + const fn test_mm512_maskz_packs_epi32() { let a = _mm512_set1_epi32(i32::MAX); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_packs_epi32(0, a, b); @@ -17739,7 +17897,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packs_epi32() { + const fn test_mm256_mask_packs_epi32() { let a = _mm256_set1_epi32(i32::MAX); let b = _mm256_set1_epi32(1 << 16 | 1); let r = _mm256_mask_packs_epi32(a, 0, a, b); @@ -17763,7 +17921,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packs_epi32() { + const fn test_mm_mask_packs_epi32() { let a = _mm_set1_epi32(i32::MAX); let b = _mm_set1_epi32(1 << 16 | 1); let r = _mm_mask_packs_epi32(a, 0, a, b); @@ -17774,7 +17932,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packs_epi32() { + const fn test_mm_maskz_packs_epi32() { let a = _mm_set1_epi32(i32::MAX); let b = _mm_set1_epi32(1); let r = _mm_maskz_packs_epi32(0, a, b); @@ -17785,7 +17943,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packs_epi16() { + const fn test_mm512_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1); let r = _mm512_packs_epi16(a, b); @@ -17798,7 +17956,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packs_epi16() { + const fn test_mm512_mask_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1 << 8 | 1); let r = _mm512_mask_packs_epi16(a, 0, a, b); @@ -17818,7 +17976,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packs_epi16() { + const fn test_mm512_maskz_packs_epi16() { let a = _mm512_set1_epi16(i16::MAX); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_packs_epi16(0, a, b); @@ -17837,7 +17995,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packs_epi16() { + const fn test_mm256_mask_packs_epi16() { let a = _mm256_set1_epi16(i16::MAX); let b = _mm256_set1_epi16(1 << 8 | 1); let r = _mm256_mask_packs_epi16(a, 0, a, b); @@ -17850,7 +18008,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packs_epi16() { + const fn test_mm256_maskz_packs_epi16() { let a = _mm256_set1_epi16(i16::MAX); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_packs_epi16(0, a, b); @@ -17863,7 +18021,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packs_epi16() { + const fn test_mm_mask_packs_epi16() { let a = _mm_set1_epi16(i16::MAX); let b = _mm_set1_epi16(1 << 8 | 1); let r = _mm_mask_packs_epi16(a, 0, a, b); @@ -17875,7 +18033,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packs_epi16() { + const fn test_mm_maskz_packs_epi16() { let a = _mm_set1_epi16(i16::MAX); let b = _mm_set1_epi16(1); let r = _mm_maskz_packs_epi16(0, a, b); @@ -17887,7 +18045,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packus_epi32() { + const fn test_mm512_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1); let r = _mm512_packus_epi32(a, b); @@ -17898,7 +18056,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packus_epi32() { + const fn test_mm512_mask_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1 << 16 | 1); let r = _mm512_mask_packus_epi32(a, 0, a, b); @@ -17911,7 +18069,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packus_epi32() { + const fn test_mm512_maskz_packus_epi32() { let a = _mm512_set1_epi32(-1); let b = _mm512_set1_epi32(1); let r = _mm512_maskz_packus_epi32(0, a, b); @@ -17924,7 +18082,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packus_epi32() { + const fn test_mm256_mask_packus_epi32() { let a = _mm256_set1_epi32(-1); let b = _mm256_set1_epi32(1 << 16 | 1); let r = _mm256_mask_packus_epi32(a, 0, a, b); @@ -17935,7 +18093,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packus_epi32() { + const fn test_mm256_maskz_packus_epi32() { let a = _mm256_set1_epi32(-1); let b = _mm256_set1_epi32(1); let r = _mm256_maskz_packus_epi32(0, a, b); @@ -17946,7 +18104,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packus_epi32() { + const fn test_mm_mask_packus_epi32() { let a = _mm_set1_epi32(-1); let b = _mm_set1_epi32(1 << 16 | 1); let r = _mm_mask_packus_epi32(a, 0, a, b); @@ -17957,7 +18115,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packus_epi32() { + const fn test_mm_maskz_packus_epi32() { let a = _mm_set1_epi32(-1); let b = _mm_set1_epi32(1); let r = _mm_maskz_packus_epi32(0, a, b); @@ -17968,7 +18126,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_packus_epi16() { + const fn test_mm512_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1); let r = _mm512_packus_epi16(a, b); @@ -17981,7 +18139,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_mask_packus_epi16() { + const fn test_mm512_mask_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1 << 8 | 1); let r = _mm512_mask_packus_epi16(a, 0, a, b); @@ -18001,7 +18159,7 @@ mod tests { } #[simd_test(enable = "avx512bw")] - fn test_mm512_maskz_packus_epi16() { + const fn test_mm512_maskz_packus_epi16() { let a = _mm512_set1_epi16(-1); let b = _mm512_set1_epi16(1); let r = _mm512_maskz_packus_epi16(0, a, b); @@ -18020,7 +18178,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_mask_packus_epi16() { + const fn test_mm256_mask_packus_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(1 << 8 | 1); let r = _mm256_mask_packus_epi16(a, 0, a, b); @@ -18033,7 +18191,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm256_maskz_packus_epi16() { + const fn test_mm256_maskz_packus_epi16() { let a = _mm256_set1_epi16(-1); let b = _mm256_set1_epi16(1); let r = _mm256_maskz_packus_epi16(0, a, b); @@ -18046,7 +18204,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_mask_packus_epi16() { + const fn test_mm_mask_packus_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(1 << 8 | 1); let r = _mm_mask_packus_epi16(a, 0, a, b); @@ -18057,7 +18215,7 @@ mod tests { } #[simd_test(enable = "avx512bw,avx512vl")] - fn test_mm_maskz_packus_epi16() { + const fn test_mm_maskz_packus_epi16() { let a = _mm_set1_epi16(-1); let b = _mm_set1_epi16(1); let r = _mm_maskz_packus_epi16(0, a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 2c4439a3f3a55..3f7781cc7dc4c 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -2816,14 +2816,32 @@ mod tests { let aa = &[3.0f32, 12.0, 23.0, NAN]; let bb = &[3.0f32, 47.5, 1.5, NAN]; - let ee = &[1i32, 0, 1, 0]; + let ee = &[0i32, 0, 1, 0]; for i in 0..4 { let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0); let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0); - let r = _mm_comige_ss(a, b); + let r = _mm_comigt_ss(a, b); + assert_eq!( + ee[i], r, + "_mm_comigt_ss({:?}, {:?}) = {}, expected: {} (i={})", + a, b, r, ee[i], i + ); + } + } + + #[simd_test(enable = "sse")] + fn test_mm_comige_ss() { + let aa = &[3.0f32, 23.0, 12.0, NAN]; + let bb = &[3.0f32, 1.5, 47.5, NAN]; + let ee = &[1i32, 1, 0, 0]; + + for i in 0..4 { + let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0); + let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0); + let r = _mm_comige_ss(a, b); assert_eq!( ee[i], r, "_mm_comige_ss({:?}, {:?}) = {}, expected: {} (i={})", diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index f339a003df4d1..1f97f3c69d0e3 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -1484,7 +1484,7 @@ pub const fn _mm_move_epi64(a: __m128i) -> __m128i { } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using signed saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi16) @@ -1492,11 +1492,29 @@ pub const fn _mm_move_epi64(a: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packsswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packsswb(a.as_i16x8(), b.as_i16x8())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { + unsafe { + let max = simd_splat(i8::MAX as i16); + let min = simd_splat(i8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + + // Shuffle the low i8 of each i16 from two concatenated vectors into + // the low bits of the result register. + const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; + let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using signed saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32) @@ -1504,11 +1522,25 @@ pub fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packssdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packssdw(a.as_i32x4(), b.as_i32x4())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { + unsafe { + let max = simd_splat(i16::MAX as i32); + let min = simd_splat(i16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min); + let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min); + + let clamped_a: i16x4 = simd_cast(clamped_a); + let clamped_b: i16x4 = simd_cast(clamped_b); + + let a: i64 = transmute(clamped_a); + let b: i64 = transmute(clamped_b); + i64x2::new(a, b).as_m128i() + } } -/// Converts packed 16-bit integers from `a` and `b` to packed 8-bit integers +/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers /// using unsigned saturation. /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi16) @@ -1516,8 +1548,28 @@ pub fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse2")] #[cfg_attr(test, assert_instr(packuswb))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packuswb(a.as_i16x8(), b.as_i16x8())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i { + unsafe { + let max = simd_splat(u8::MAX as i16); + let min = simd_splat(u8::MIN as i16); + + let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min) + .as_m128i() + .as_i8x16(); + + // Shuffle the low bytes of each i16 from two concatenated vectors into + // the low bits of the result register. + // Without `simd_shuffle`, this intrinsic will cause the AVX-512BW + // `_mm_mask_packus_epi16` and `_mm_maskz_packus_epi16` tests to fail. + const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; + let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } /// Returns the `imm8` element of `a`. @@ -3217,12 +3269,6 @@ unsafe extern "C" { fn cvtps2dq(a: __m128) -> i32x4; #[link_name = "llvm.x86.sse2.maskmov.dqu"] fn maskmovdqu(a: i8x16, mask: i8x16, mem_addr: *mut i8); - #[link_name = "llvm.x86.sse2.packsswb.128"] - fn packsswb(a: i16x8, b: i16x8) -> i8x16; - #[link_name = "llvm.x86.sse2.packssdw.128"] - fn packssdw(a: i32x4, b: i32x4) -> i16x8; - #[link_name = "llvm.x86.sse2.packuswb.128"] - fn packuswb(a: i16x8, b: i16x8) -> u8x16; #[link_name = "llvm.x86.sse2.max.sd"] fn maxsd(a: __m128d, b: __m128d) -> __m128d; #[link_name = "llvm.x86.sse2.max.pd"] @@ -4286,7 +4332,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packs_epi16() { + const fn test_mm_packs_epi16() { let a = _mm_setr_epi16(0x80, -0x81, 0, 0, 0, 0, 0, 0); let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -0x81, 0x80); let r = _mm_packs_epi16(a, b); @@ -4300,7 +4346,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packs_epi32() { + const fn test_mm_packs_epi32() { let a = _mm_setr_epi32(0x8000, -0x8001, 0, 0); let b = _mm_setr_epi32(0, 0, -0x8001, 0x8000); let r = _mm_packs_epi32(a, b); @@ -4311,7 +4357,7 @@ mod tests { } #[simd_test(enable = "sse2")] - fn test_mm_packus_epi16() { + const fn test_mm_packus_epi16() { let a = _mm_setr_epi16(0x100, -1, 0, 0, 0, 0, 0, 0); let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -1, 0x100); let r = _mm_packus_epi16(a, b); diff --git a/library/stdarch/crates/core_arch/src/x86/sse41.rs b/library/stdarch/crates/core_arch/src/x86/sse41.rs index 7ad4306f36f21..4ebf7d3bd39a8 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse41.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse41.rs @@ -418,7 +418,7 @@ pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { unsafe { simd_imin(a.as_u32x4(), b.as_u32x4()).as_m128i() } } -/// Converts packed 32-bit integers from `a` and `b` to packed 16-bit integers +/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers /// using unsigned saturation /// /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi32) @@ -426,8 +426,26 @@ pub const fn _mm_min_epu32(a: __m128i, b: __m128i) -> __m128i { #[target_feature(enable = "sse4.1")] #[cfg_attr(test, assert_instr(packusdw))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { - unsafe { transmute(packusdw(a.as_i32x4(), b.as_i32x4())) } +#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")] +pub const fn _mm_packus_epi32(a: __m128i, b: __m128i) -> __m128i { + unsafe { + let max = simd_splat(u16::MAX as i32); + let min = simd_splat(u16::MIN as i32); + + let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min) + .as_m128i() + .as_i16x8(); + let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min) + .as_m128i() + .as_i16x8(); + + // Shuffle the low u16 of each i32 from two concatenated vectors into + // the low bits of the result register. + const IDXS: [u32; 8] = [0, 2, 4, 6, 8, 10, 12, 14]; + let result: i16x8 = simd_shuffle!(clamped_a, clamped_b, IDXS); + + result.as_m128i() + } } /// Compares packed 64-bit integers in `a` and `b` for equality @@ -1166,8 +1184,6 @@ pub unsafe fn _mm_stream_load_si128(mem_addr: *const __m128i) -> __m128i { unsafe extern "C" { #[link_name = "llvm.x86.sse41.insertps"] fn insertps(a: __m128, b: __m128, imm8: u8) -> __m128; - #[link_name = "llvm.x86.sse41.packusdw"] - fn packusdw(a: i32x4, b: i32x4) -> u16x8; #[link_name = "llvm.x86.sse41.dppd"] fn dppd(a: __m128d, b: __m128d, imm8: u8) -> __m128d; #[link_name = "llvm.x86.sse41.dpps"] @@ -1455,7 +1471,7 @@ mod tests { } #[simd_test(enable = "sse4.1")] - fn test_mm_packus_epi32() { + const fn test_mm_packus_epi32() { let a = _mm_setr_epi32(1, 2, 3, 4); let b = _mm_setr_epi32(-1, -2, -3, -4); let r = _mm_packus_epi32(a, b); diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 9190c8518a667..8574aacee6671 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -4567,20 +4567,11 @@ intrinsics: unsafe: [neon] attr: - *neon-stable - assert_instr: [st1] + assert_instr: [stp] types: - - ['f64', float64x1x2_t, float64x1_t] + - ['f64', float64x1x2_t] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -4591,19 +4582,10 @@ intrinsics: - *neon-stable assert_instr: [st2] types: - - [i64, int64x2x2_t, int64x2_t] - - [f64, float64x2x2_t, float64x2_t] + - [i64, int64x2x2_t, "2"] + - [f64, float64x2x2_t, "2"] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "2", a, b], [], true] - name: "vst2{neon_type[1].lane_nox}" doc: "Store multiple 2-element structures from two registers" @@ -4781,19 +4763,9 @@ intrinsics: safety: unsafe: [neon] types: - - [f64, float64x1x3_t, float64x1_t] + - [f64, float64x1x3_t] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].lane_nox}" doc: "Store multiple 3-element structures from three registers" @@ -4860,20 +4832,10 @@ intrinsics: safety: unsafe: [neon] types: - - [i64, int64x2x3_t, int64x2_t] - - [f64, float64x2x3_t, float64x2_t] + - [i64, int64x2x3_t, "2"] + - [f64, float64x2x3_t, "2"] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "3", a, b], [], true] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -4995,20 +4957,9 @@ intrinsics: safety: unsafe: [neon] types: - - [f64, float64x1x4_t, float64x1_t] + - [f64, float64x1x4_t] compose: - - LLVMLink: - name: 'st4.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].lane_nox}" doc: "Store multiple 4-element structures from four registers" @@ -5075,21 +5026,10 @@ intrinsics: safety: unsafe: [neon] types: - - [i64, int64x2x4_t, int64x2_t] - - [f64, float64x2x4_t, float64x2_t] + - [i64, int64x2x4_t, "2"] + - [f64, float64x2x4_t, "2"] compose: - - LLVMLink: - name: 'st4.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "4", a, b], [], true] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" @@ -5434,7 +5374,7 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ["q_lane_f64", float64x2_t, float64x1_t, "q_f64", '[LANE as u32, LANE as u32]'] + - ["q_lane_f64", float64x2_t, float64x1_t, "q_f64", '[LANE as u32; 2]'] compose: - FnCall: [static_assert!, ['LANE == 0']] - FnCall: @@ -5503,11 +5443,11 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ['_lane_f32', float32x2_t, float32x2_t, '1', '_f32', '[LANE as u32, LANE as u32]'] - - ['_laneq_f32', float32x2_t, float32x4_t, '2', '_f32', '[LANE as u32, LANE as u32]'] - - ['q_lane_f32', float32x4_t, float32x2_t, '1', 'q_f32', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f32', float32x4_t, float32x4_t, '2', 'q_f32', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f64', float64x2_t, float64x2_t, '1', 'q_f64', '[LANE as u32, LANE as u32]'] + - ['_lane_f32', float32x2_t, float32x2_t, '1', '_f32', '[LANE as u32; 2]'] + - ['_laneq_f32', float32x2_t, float32x4_t, '2', '_f32', '[LANE as u32; 2]'] + - ['q_lane_f32', float32x4_t, float32x2_t, '1', 'q_f32', '[LANE as u32; 4]'] + - ['q_laneq_f32', float32x4_t, float32x4_t, '2', 'q_f32', '[LANE as u32; 4]'] + - ['q_laneq_f64', float64x2_t, float64x2_t, '1', 'q_f64', '[LANE as u32; 2]'] compose: - FnCall: [static_assert_uimm_bits!, ['LANE', "{type[3]}"]] - FnCall: @@ -5533,10 +5473,10 @@ intrinsics: static_defs: ["const LANE: i32"] safety: safe types: - - ['_lane_f16', float16x4_t, float16x4_t, '2', '_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['_laneq_f16', float16x4_t, float16x8_t, '3', '_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_lane_f16', float16x8_t, float16x4_t, '2', 'q_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - ['q_laneq_f16', float16x8_t, float16x8_t, '3', 'q_f16', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - ['_lane_f16', float16x4_t, float16x4_t, '2', '_f16', '[LANE as u32; 4]'] + - ['_laneq_f16', float16x4_t, float16x8_t, '3', '_f16', '[LANE as u32; 4]'] + - ['q_lane_f16', float16x8_t, float16x4_t, '2', 'q_f16', '[LANE as u32; 8]'] + - ['q_laneq_f16', float16x8_t, float16x8_t, '3', 'q_f16', '[LANE as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, ['LANE', "{type[3]}"]] - FnCall: @@ -7815,14 +7755,14 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]'] - - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]'] - - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32; 4]'] + - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32; 4]'] + - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32; 2]'] + - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32; 2]'] + - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']] - Let: [c, "{type[1]}", {FnCall: [simd_shuffle!, [c, c, "{type[5]}"]]}] @@ -7899,14 +7839,14 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32, LANE as u32]'] - - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32, LANE as u32]'] - - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, int16x4_t, '2', '[LANE as u32; 4]'] + - [_laneq_s16, int16x4_t, int16x4_t, int16x8_t, '3', '[LANE as u32; 4]'] + - [q_lane_s16, int16x8_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [q_laneq_s16, int16x8_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [_lane_s32, int32x2_t, int32x2_t, int32x2_t, '1', '[LANE as u32; 2]'] + - [_laneq_s32, int32x2_t, int32x2_t, int32x4_t, '2', '[LANE as u32; 2]'] + - [q_lane_s32, int32x4_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [q_laneq_s32, int32x4_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[4]}']] - Let: [c, "{type[1]}", {FnCall: [simd_shuffle!, [c, c, "{type[5]}"]]}] @@ -11198,7 +11138,7 @@ intrinsics: - FnCall: - simd_mul - - a - - FnCall: ["simd_shuffle!", [b, b, '[LANE as u32, LANE as u32]']] + - FnCall: ["simd_shuffle!", [b, b, '[LANE as u32; 2]']] - name: "vmuld_lane_f64" doc: "Floating-point multiply" @@ -11255,7 +11195,7 @@ intrinsics: - FnCall: - simd_mul - - a - - FnCall: [simd_shuffle!, [b, b, '[LANE as u32, LANE as u32]']] + - FnCall: [simd_shuffle!, [b, b, '[LANE as u32; 2]']] # vmulq_laneq_f16 @@ -11272,8 +11212,8 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [float16x4_t, float16x8_t, '_lane', "[LANE as u32, LANE as u32, LANE as u32, LANE as u32]"] - - [float16x8_t, float16x8_t, 'q_lane', "[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]"] + - [float16x4_t, float16x8_t, '_lane', "[LANE as u32; 4]"] + - [float16x8_t, float16x8_t, 'q_lane', "[LANE as u32; 8]"] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '3']] - FnCall: @@ -11395,10 +11335,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: @@ -11418,10 +11358,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32; 8]'] + - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32; 8]'] + - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32; 4]'] + - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: @@ -11720,10 +11660,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int16x8_t, int16x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int16x8_t, int16x8_t, int32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int32x2_t, int64x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int32x4_t, int64x2_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int16x8_t, int16x4_t, int32x4_t, '2', '[LANE as u32; 8]'] + - [int16x8_t, int16x8_t, int32x4_t, '3', '[LANE as u32; 8]'] + - [int32x4_t, int32x2_t, int64x2_t, '1', '[LANE as u32; 4]'] + - [int32x4_t, int32x4_t, int64x2_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]] - FnCall: @@ -11742,10 +11682,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint16x8_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint16x8_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint16x8_t, uint16x4_t, uint32x4_t, '2', '[LANE as u32; 8]'] + - [uint16x8_t, uint16x8_t, uint32x4_t, '3', '[LANE as u32; 8]'] + - [uint32x4_t, uint32x2_t, uint64x2_t, '1', '[LANE as u32; 4]'] + - [uint32x4_t, uint32x4_t, uint64x2_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, "{type[3]}"]] - FnCall: @@ -12033,10 +11973,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [int32x4_t, int16x8_t, int16x4_t, '2', '[LANE as u32; 8]'] + - [int32x4_t, int16x8_t, int16x8_t, '3', '[LANE as u32; 8]'] + - [int64x2_t, int32x4_t, int32x2_t, '1', '[LANE as u32; 4]'] + - [int64x2_t, int32x4_t, int32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: ['vmlal_high_{neon_type[2]}', [a, b, {FnCall: [simd_shuffle!, [c, c, '{type[4]}']]}]] @@ -12052,10 +11992,10 @@ intrinsics: static_defs: ['const LANE: i32'] safety: safe types: - - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] - - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32, LANE as u32, LANE as u32, LANE as u32]'] + - [uint32x4_t, uint16x8_t, uint16x4_t, '2', '[LANE as u32; 8]'] + - [uint32x4_t, uint16x8_t, uint16x8_t, '3', '[LANE as u32; 8]'] + - [uint64x2_t, uint32x4_t, uint32x2_t, '1', '[LANE as u32; 4]'] + - [uint64x2_t, uint32x4_t, uint32x4_t, '2', '[LANE as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [LANE, '{type[3]}']] - FnCall: ['vmlal_high_{neon_type[2]}', [a, b, {FnCall: [simd_shuffle!, [c, c, '{type[4]}']]}]] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 8e10fff984ac7..5104ae607ccff 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -1439,12 +1439,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_s8, int8x8_t, int8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_s8, int8x8_t, int8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_u8, uint8x8_t, uint8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_u8, uint8x8_t, uint8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_p8, poly8x8_t, poly8x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_p8, poly8x8_t, poly8x16_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_s8, int8x8_t, int8x8_t, '3', '[N as u32; 8]'] + - [q_lane_s8, int8x8_t, int8x16_t, '3', '[N as u32; 16]'] + - [_lane_u8, uint8x8_t, uint8x8_t, '3', '[N as u32; 8]'] + - [q_lane_u8, uint8x8_t, uint8x16_t, '3', '[N as u32; 16]'] + - [_lane_p8, poly8x8_t, poly8x8_t, '3', '[N as u32; 8]'] + - [q_lane_p8, poly8x8_t, poly8x16_t, '3', '[N as u32; 16]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1463,12 +1463,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_s8, int8x16_t, int8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_s8, int8x16_t, int8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_u8, uint8x16_t, uint8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_u8, uint8x16_t, uint8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_p8, poly8x16_t, poly8x16_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_p8, poly8x16_t, poly8x8_t, '4', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_s8, int8x16_t, int8x16_t, '4', '[N as u32; 16]'] + - [_laneq_s8, int8x16_t, int8x8_t, '4', '[N as u32; 8]'] + - [q_laneq_u8, uint8x16_t, uint8x16_t, '4', '[N as u32; 16]'] + - [_laneq_u8, uint8x16_t, uint8x8_t, '4', '[N as u32; 8]'] + - [q_laneq_p8, poly8x16_t, poly8x16_t, '4', '[N as u32; 16]'] + - [_laneq_p8, poly8x16_t, poly8x8_t, '4', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1487,12 +1487,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_s16, int16x4_t, int16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_s16, int16x4_t, int16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_u16, uint16x4_t, uint16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_lane_p16, poly16x4_t, poly16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_p16, poly16x4_t, poly16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_s16, int16x4_t, int16x4_t, '2', '[N as u32; 4]'] + - [q_lane_s16, int16x4_t, int16x8_t, '2', '[N as u32; 8]'] + - [_lane_u16, uint16x4_t, uint16x4_t, '2', '[N as u32; 4]'] + - [q_lane_u16, uint16x4_t, uint16x8_t, '2', '[N as u32; 8]'] + - [_lane_p16, poly16x4_t, poly16x4_t, '2', '[N as u32; 4]'] + - [q_lane_p16, poly16x4_t, poly16x8_t, '2', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1511,12 +1511,12 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_s16, int16x8_t, int16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_u16, uint16x8_t, uint16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_laneq_p16, poly16x8_t, poly16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_p16, poly16x8_t, poly16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_s16, int16x8_t, int16x8_t, '3', '[N as u32; 8]'] + - [_laneq_s16, int16x8_t, int16x4_t, '3', '[N as u32; 4]'] + - [q_laneq_u16, uint16x8_t, uint16x8_t, '3', '[N as u32; 8]'] + - [_laneq_u16, uint16x8_t, uint16x4_t, '3', '[N as u32; 4]'] + - [q_laneq_p16, poly16x8_t, poly16x8_t, '3', '[N as u32; 8]'] + - [_laneq_p16, poly16x8_t, poly16x4_t, '3', '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1538,8 +1538,8 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [q_laneq_f16, float16x8_t, float16x8_t, '3', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] - - [_laneq_f16, float16x8_t, float16x4_t, '3', '[N as u32, N as u32, N as u32, N as u32]'] + - [q_laneq_f16, float16x8_t, float16x8_t, '3', '[N as u32; 8]'] + - [_laneq_f16, float16x8_t, float16x4_t, '3', '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -1578,8 +1578,8 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [_lane_f16, float16x4_t, float16x4_t, '2', '[N as u32, N as u32, N as u32, N as u32]'] - - [q_lane_f16, float16x4_t, float16x8_t, '2', '[N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32, N as u32]'] + - [_lane_f16, float16x4_t, float16x4_t, '2', '[N as u32; 4]'] + - [q_lane_f16, float16x4_t, float16x8_t, '2', '[N as u32; 8]'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[3]}"]] - FnCall: [simd_shuffle!, [a, a, "{type[4]}"]] @@ -5049,17 +5049,7 @@ intrinsics: types: - [i64, int64x1x2_t, int64x1_t] compose: - - LLVMLink: - name: 'vst2.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst2.v{neon_type[1].lane}{type[0]}.p0' - arch: arm - - FnCall: ['_vst2{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5092,16 +5082,7 @@ intrinsics: types: - [i64, int64x1x2_t, int64x1_t] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5113,26 +5094,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x2_t, int8x8_t] - - [i16, int16x4x2_t, int16x4_t] - - [i32, int32x2x2_t, int32x2_t] - - [i8, int8x16x2_t, int8x16_t] - - [i16, int16x8x2_t, int16x8_t] - - [i32, int32x4x2_t, int32x4_t] - - [f32, float32x2x2_t, float32x2_t] - - [f32, float32x4x2_t, float32x4_t] + - [i8, int8x8x2_t, "8"] + - [i16, int16x4x2_t, "4"] + - [i32, int32x2x2_t, "2"] + - [i8, int8x16x2_t, "16"] + - [i16, int16x8x2_t, "8"] + - [i32, int32x4x2_t, "4"] + - [f32, float32x2x2_t, "2"] + - [f32, float32x4x2_t, "4"] compose: - - LLVMLink: - name: 'st2.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st2.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst2{neon_type[1].nox}', ['b.0', 'b.1', 'a as _']] - + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "2", a, b], [], true] - name: "vst2{neon_type[1].nox}" doc: "Store multiple 2-element structures from two registers" @@ -5426,17 +5397,7 @@ intrinsics: types: - [i64, int64x1x3_t, int64x1_t] compose: - - LLVMLink: - name: 'st3.{neon_type[1].nox}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st3.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst3{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -5471,18 +5432,7 @@ intrinsics: types: - [i64, int64x1x3_t, int64x1_t] compose: - - LLVMLink: - name: 'vst3.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst3{neon_type[1].nox}" doc: "Store multiple 3-element structures from three registers" @@ -5571,27 +5521,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x3_t, int8x8_t, '1'] - - [i16, int16x4x3_t, int16x4_t, '2'] - - [i32, int32x2x3_t, int32x2_t, '4'] - - [i8, int8x16x3_t, int8x16_t, '1'] - - [i16, int16x8x3_t, int16x8_t, '2'] - - [i32, int32x4x3_t, int32x4_t, '4'] - - [f32, float32x2x3_t, float32x2_t, '4'] - - [f32, float32x4x3_t, float32x4_t, '4'] + - [i8, int8x8x3_t, '8'] + - [i16, int16x4x3_t, '4'] + - [i32, int32x2x3_t, '2'] + - [i8, int8x16x3_t, '16'] + - [i16, int16x8x3_t, '8'] + - [i32, int32x4x3_t, '4'] + - [f32, float32x2x3_t, '2'] + - [f32, float32x4x3_t, '4'] compose: - - LLVMLink: - name: 'vst3.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst3.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst3{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', "{type[3]}"]] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "3", a, b], [], true] - name: "vst3{neon_type[1].nox}" @@ -5853,19 +5792,7 @@ intrinsics: types: - [i64, int64x1x4_t, int64x1_t] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'ptr: *mut i8' - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'size: i32' - links: - - link: 'llvm.arm.neon.vst4.p0.v{neon_type[1].lane}{type[0]}' - arch: arm - - FnCall: ['_vst4{neon_type[1].nox}', ['a as _', 'b.0', 'b.1', 'b.2', 'b.3', '8']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" @@ -5879,18 +5806,7 @@ intrinsics: types: - [i64, int64x1x4_t, int64x1_t] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.{neon_type[2]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: [core::ptr::write_unaligned, ['a.cast()', b]] - name: "vst4{neon_type[1].nox}" doc: "Store multiple 4-element structures from four registers" @@ -6114,27 +6030,16 @@ intrinsics: safety: unsafe: [neon] types: - - [i8, int8x8x4_t, int8x8_t] - - [i16, int16x4x4_t, int16x4_t] - - [i32, int32x2x4_t, int32x2_t] - - [i8, int8x16x4_t, int8x16_t] - - [i16, int16x8x4_t, int16x8_t] - - [i32, int32x4x4_t, int32x4_t] - - [f32, float32x2x4_t, float32x2_t] - - [f32, float32x4x4_t, float32x4_t] + - [i8, int8x8x4_t, "8"] + - [i16, int16x4x4_t, "4"] + - [i32, int32x2x4_t, "2"] + - [i8, int8x16x4_t, "16"] + - [i16, int16x8x4_t, "8"] + - [i32, int32x4x4_t, "4"] + - [f32, float32x2x4_t, "2"] + - [f32, float32x4x4_t, "4"] compose: - - LLVMLink: - name: 'vst4.{neon_type[1]}' - arguments: - - 'a: {type[2]}' - - 'b: {type[2]}' - - 'c: {type[2]}' - - 'd: {type[2]}' - - 'ptr: *mut i8' - links: - - link: 'llvm.aarch64.neon.st4.v{neon_type[1].lane}{type[0]}.p0' - arch: aarch64,arm64ec - - FnCall: ['_vst4{neon_type[1].nox}', ['b.0', 'b.1', 'b.2', 'b.3', 'a as _']] + - FnCall: ["crate::core_arch::macros::interleaving_store!", [{ Type: "{type[0]}" }, "{type[2]}", "4", a, b], [], true] - name: "vst4{neon_type[1].nox}" @@ -7675,7 +7580,7 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int16x4_t, int16x4_t, int32x4_t, '[N as u32, N as u32, N as u32, N as u32]'] + - [int16x4_t, int16x4_t, int32x4_t, '[N as u32; 4]'] compose: - FnCall: [static_assert_uimm_bits!, [N, '2']] - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}] @@ -7695,7 +7600,7 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int32x2_t, int32x2_t, int64x2_t, '[N as u32, N as u32]'] + - [int32x2_t, int32x2_t, int64x2_t, '[N as u32; 2]'] compose: - FnCall: [static_assert_uimm_bits!, [N, '1']] - Let: [b, "{neon_type[0]}", {FnCall: [simd_shuffle!, [b, b, "{type[3]}"]]}] @@ -8320,9 +8225,9 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }'] - - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }'] - - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { uint64x2_t([-N as u64, -N as u64]) }'] + - [uint16x8_t, uint8x8_t, 'N >= 1 && N <= 8', 'const { uint16x8_t([-N as u16; 8]) }'] + - [uint32x4_t, uint16x4_t, 'N >= 1 && N <= 16', 'const { uint32x4_t([-N as u32; 4]) }'] + - [uint64x2_t, uint32x2_t, 'N >= 1 && N <= 32', 'const { uint64x2_t([-N as u64; 2]) }'] compose: - FnCall: [static_assert!, ["{type[2]}"]] - LLVMLink: @@ -10789,9 +10694,9 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [uint16x8_t, uint8x8_t, '8', 'const { uint16x8_t([-N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16, -N as u16]) }'] - - [uint32x4_t, uint16x4_t, '16', 'const { uint32x4_t([-N as u32, -N as u32, -N as u32, -N as u32]) }'] - - [uint64x2_t, uint32x2_t, '32', 'const { uint64x2_t([-N as u64, -N as u64]) }'] + - [uint16x8_t, uint8x8_t, '8', 'const { uint16x8_t([-N as u16; 8]) }'] + - [uint32x4_t, uint16x4_t, '16', 'const { uint32x4_t([-N as u32; 4]) }'] + - [uint64x2_t, uint32x2_t, '32', 'const { uint64x2_t([-N as u64; 2]) }'] compose: - FnCall: [static_assert!, ['N >= 1 && N <= {type[2]}']] - LLVMLink: diff --git a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs index 4136463f197fd..2ac05e28cb4ce 100644 --- a/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs +++ b/library/stdarch/crates/stdarch-verify/tests/x86-intel.rs @@ -246,7 +246,6 @@ fn verify_all_signatures() { "_xend", "_xabort_code", // Aliases - "_mm_comige_ss", "_mm_cvt_ss2si", "_mm_cvtt_ss2si", "_mm_cvt_si2ss", diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md index 4caeaa106b495..dfe036bf1bb19 100644 --- a/src/doc/rustc/src/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -53,7 +53,7 @@ To check for the _none_ value (ie `#[cfg(foo)]`) one can use the `none()` predic `values()`: `values(none())`. It can be followed or preceded by any number of `"value"`. To enable checking of values, but to provide an *none*/empty set of expected values -(ie. expect `#[cfg(name)]`), use these forms: +(i.e. expect `#[cfg(name)]`), use these forms: ```bash rustc --check-cfg 'cfg(name)' diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 352b8526b0217..8191857755052 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { // special handling for self trait bounds as these are not considered generics - // ie. trait Foo: Display {} + // i.e. trait Foo: Display {} if let Item { kind: ItemKind::Trait(_, _, _, _, _, bounds, ..), .. diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 67ae1dcef81be..50cfb0ed89dec 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -449,6 +449,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { constness: lc, is_auto: la, safety: lu, + impl_restriction: liprt, ident: li, generics: lg, bounds: lb, @@ -458,6 +459,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { constness: rc, is_auto: ra, safety: ru, + impl_restriction: riprt, ident: ri, generics: rg, bounds: rb, @@ -467,6 +469,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) && la == ra && matches!(lu, Safety::Default) == matches!(ru, Safety::Default) + && eq_impl_restriction(liprt, riprt) && eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound) @@ -834,6 +837,29 @@ pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool { } } +pub fn eq_impl_restriction(l: &ImplRestriction, r: &ImplRestriction) -> bool { + eq_restriction_kind(&l.kind, &r.kind) +} + +fn eq_restriction_kind(l: &RestrictionKind, r: &RestrictionKind) -> bool { + match (l, r) { + (RestrictionKind::Unrestricted, RestrictionKind::Unrestricted) => true, + ( + RestrictionKind::Restricted { + path: l_path, + shorthand: l_short, + id: _, + }, + RestrictionKind::Restricted { + path: r_path, + shorthand: r_short, + id: _, + }, + ) => l_short == r_short && eq_path(l_path, r_path), + _ => false, + } +} + pub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool { eq_fn_ret_ty(&l.output, &r.output) && over(&l.inputs, &r.inputs, |l, r| { diff --git a/src/tools/miri/tests/fail/shims/shim_arg_size.rs b/src/tools/miri/tests/fail/shims/shim_arg_size.rs index 3d7bc25bf5d31..4129dec6c4d34 100644 --- a/src/tools/miri/tests/fail/shims/shim_arg_size.rs +++ b/src/tools/miri/tests/fail/shims/shim_arg_size.rs @@ -1,6 +1,6 @@ fn main() { extern "C" { - // Use the wrong type (ie. not `i32`) for the `c` argument. + // Use the wrong type (i.e. not `i32`) for the `c` argument. fn memchr(s: *const std::ffi::c_void, c: u8, n: usize) -> *mut std::ffi::c_void; } diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index 94793a3618e18..151aba82a2033 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -742,7 +742,7 @@ impl CrateGraphBuilder { deps.into_iter() } - /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate + /// Returns all crates in the graph, sorted in topological order (i.e. dependencies of a crate /// come before the crate itself). fn crates_in_topological_order(&self) -> Vec { let mut res = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index a1645de6ec236..ccd001df69b41 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -146,7 +146,7 @@ impl Visibility { /// Returns the most permissive visibility of `self` and `other`. /// - /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only + /// If there is no subset relation between `self` and `other`, returns `None` (i.e. they're only /// visible in unrelated modules). pub(crate) fn max( self, @@ -212,7 +212,7 @@ impl Visibility { /// Returns the least permissive visibility of `self` and `other`. /// - /// If there is no subset relation between `self` and `other`, returns `None` (ie. they're only + /// If there is no subset relation between `self` and `other`, returns `None` (i.e. they're only /// visible in unrelated modules). pub(crate) fn min( self, diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 2c5fcf09c9f16..a4251a9a3bd4e 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1158,6 +1158,7 @@ pub(crate) fn format_trait( constness, is_auto, safety, + ref impl_restriction, ident, ref generics, ref bounds, @@ -1166,11 +1167,12 @@ pub(crate) fn format_trait( let mut result = String::with_capacity(128); let header = format!( - "{}{}{}{}trait ", + "{}{}{}{}{}trait ", format_visibility(context, &item.vis), format_constness(constness), format_safety(safety), format_auto(is_auto), + format_impl_restriction(context, impl_restriction), ); result.push_str(&header); diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index b676803379f7c..b052e74d8bf20 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use rustc_ast::YieldKind; use rustc_ast::ast::{ - self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility, - VisibilityKind, + self, Attribute, ImplRestriction, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, + RestrictionKind, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol}; @@ -74,6 +74,40 @@ pub(crate) fn format_visibility( } } +pub(crate) fn format_impl_restriction( + context: &RewriteContext<'_>, + impl_restriction: &ImplRestriction, +) -> String { + format_restriction("impl", context, &impl_restriction.kind) +} + +fn format_restriction( + kw: &'static str, + context: &RewriteContext<'_>, + restriction: &RestrictionKind, +) -> String { + match restriction { + RestrictionKind::Unrestricted => String::new(), + RestrictionKind::Restricted { + ref path, + id: _, + shorthand, + } => { + let Path { ref segments, .. } = **path; + let mut segments_iter = segments.iter().map(|seg| rewrite_ident(context, seg.ident)); + if path.is_global() && segments_iter.next().is_none() { + panic!("non-global path in {kw}(restricted)?"); + } + // FIXME use `segments_iter.intersperse("::").collect::()` once + // `#![feature(iter_intersperse)]` is re-stabilized. + let path = itertools::join(segments_iter, "::"); + let in_str = if *shorthand { "" } else { "in " }; + + format!("{kw}({in_str}{path}) ") + } + } +} + #[inline] pub(crate) fn format_coro(coroutine_kind: &ast::CoroutineKind) -> &'static str { match coroutine_kind { diff --git a/src/tools/rustfmt/tests/source/impl-restriction.rs b/src/tools/rustfmt/tests/source/impl-restriction.rs new file mode 100644 index 0000000000000..4459d9a8ba2b5 --- /dev/null +++ b/src/tools/rustfmt/tests/source/impl-restriction.rs @@ -0,0 +1,41 @@ +#![feature(impl_restriction)] + +pub +impl(crate) +trait Foo {} + +pub impl +( in +crate ) +trait +Bar +{} + +pub +impl ( in foo +:: +bar ) +trait Baz {} + +pub +const +impl +(self) +trait QuxConst {} + +pub +auto impl( +super +) +trait QuxAuto {} + +pub +unsafe impl +(in crate) +trait QuxUnsafe {} + +pub const +unsafe impl +(in super +::foo) +trait QuxConstUnsafe {} diff --git a/src/tools/rustfmt/tests/target/impl-restriction.rs b/src/tools/rustfmt/tests/target/impl-restriction.rs new file mode 100644 index 0000000000000..4ff617af0f257 --- /dev/null +++ b/src/tools/rustfmt/tests/target/impl-restriction.rs @@ -0,0 +1,15 @@ +#![feature(impl_restriction)] + +pub impl(crate) trait Foo {} + +pub impl(in crate) trait Bar {} + +pub impl(in foo::bar) trait Baz {} + +pub const impl(self) trait QuxConst {} + +pub auto impl(super) trait QuxAuto {} + +pub unsafe impl(in crate) trait QuxUnsafe {} + +pub const unsafe impl(in super::foo) trait QuxConstUnsafe {} diff --git a/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs b/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs index e72a649a530a8..fb520d38df3ca 100644 --- a/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs +++ b/tests/codegen-llvm/riscv-abi/call-llvm-intrinsics.rs @@ -1,17 +1,20 @@ +//@ add-minicore //@ compile-flags: -C no-prepopulate-passes - -//@ only-riscv64 +//@ revisions: riscv32gc riscv64gc +//@ [riscv32gc] compile-flags: --target riscv32gc-unknown-linux-gnu +//@ [riscv32gc] needs-llvm-components: riscv +//@ [riscv64gc] compile-flags: --target riscv64gc-unknown-linux-gnu +//@ [riscv64gc] needs-llvm-components: riscv +//@ min-llvm-version: 21 #![feature(link_llvm_intrinsics)] +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] #![crate_type = "lib"] -struct A; - -impl Drop for A { - fn drop(&mut self) { - println!("A"); - } -} +extern crate minicore; +use minicore::*; extern "C" { #[link_name = "llvm.sqrt.f32"] @@ -19,12 +22,9 @@ extern "C" { } pub fn do_call() { - let _a = A; - unsafe { // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them - // CHECK: store float 4.000000e+00, ptr %{{.}}, align 4 - // CHECK: call float @llvm.sqrt.f32(float %{{.}} + // CHECK: call float @llvm.sqrt.f32(float 4.000000e+00) sqrt(4.0); } } diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 7b8b760ea333b..a5df237b7fddc 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -1,7 +1,7 @@ //! This checks the output of `--print=cfg` //! //! Specifically it checks that output is correctly formatted -//! (ie. no duplicated cfgs, values are between "", names are not). +//! (i.e. no duplicated cfgs, values are between "", names are not). //! //! It also checks that some targets have the correct set cfgs. diff --git a/tests/run-make/remap-path-prefix-std/rmake.rs b/tests/run-make/remap-path-prefix-std/rmake.rs index f5179038a9b11..bf8bdf039f347 100644 --- a/tests/run-make/remap-path-prefix-std/rmake.rs +++ b/tests/run-make/remap-path-prefix-std/rmake.rs @@ -1,5 +1,5 @@ // This test makes sure that we do not leak paths to the checkout -// (ie. /checkout in CI) in the distributed `libstd` debuginfo. +// (i.e. /checkout in CI) in the distributed `libstd` debuginfo. // // This test only runs on Linux and dist builder (or with `rust.remap-debuginfo = true` // set in your `bootstrap.toml`). diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index c15c2dea4c196..5dd11b0a016e3 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -18,7 +18,7 @@ extern crate rustc_target; use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; -use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_data_structures::fx::FxIndexMap; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -33,12 +33,12 @@ impl CodegenBackend for TheBackend { "the-backend" } - fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { - Box::new(CodegenResults { - modules: vec![], - allocator_module: None, - crate_info: CrateInfo::new(tcx, "fake_target_cpu".to_string()), - }) + fn target_cpu(&self, _sess: &Session) -> String { + "fake_target_cpu".to_owned() + } + + fn codegen_crate(&self, _tcx: TyCtxt<'_>, _crate_info: &CrateInfo) -> Box { + Box::new(CompiledModules { modules: vec![], allocator_module: None }) } fn join_codegen( @@ -46,17 +46,18 @@ impl CodegenBackend for TheBackend { ongoing_codegen: Box, _sess: &Session, _outputs: &OutputFilenames, - ) -> (CodegenResults, FxIndexMap) { + ) -> (CompiledModules, FxIndexMap) { let codegen_results = ongoing_codegen - .downcast::() - .expect("in join_codegen: ongoing_codegen is not a CodegenResults"); + .downcast::() + .expect("in join_codegen: ongoing_codegen is not a CompiledModules"); (*codegen_results, FxIndexMap::default()) } fn link( &self, sess: &Session, - codegen_results: CodegenResults, + _compiled_modules: CompiledModules, + crate_info: CrateInfo, _metadata: EncodedMetadata, outputs: &OutputFilenames, ) { @@ -65,7 +66,7 @@ impl CodegenBackend for TheBackend { use rustc_session::config::{CrateType, OutFileName}; use rustc_session::output::out_filename; - let crate_name = codegen_results.crate_info.local_crate_name; + let crate_name = crate_info.local_crate_name; for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::Rlib { sess.dcx().fatal(format!("Crate type is {:?}", crate_type)); diff --git a/tests/ui/README.md b/tests/ui/README.md index 3ebbe4918a2de..689a61b472691 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -705,6 +705,11 @@ This test category revolves around trait objects with `Sized` having illegal ope Tests on lifetime elision in impl function signatures. See [Lifetime elision | Nomicon](https://doc.rust-lang.org/nomicon/lifetime-elision.html). +## `tests/ui/impl-restriction/` +Tests for `#![feature(impl_restriction)]`. See [Tracking issue for restrictions #105077 +](https://github.com/rust-lang/rust/issues/105077). + + ## `tests/ui/impl-trait/` Tests for trait impls. diff --git a/tests/ui/associated-types/defaults-in-other-trait-items.rs b/tests/ui/associated-types/defaults-in-other-trait-items.rs index f263809552fdf..3de64e0d0db6d 100644 --- a/tests/ui/associated-types/defaults-in-other-trait-items.rs +++ b/tests/ui/associated-types/defaults-in-other-trait-items.rs @@ -1,7 +1,7 @@ #![feature(associated_type_defaults)] // Associated type defaults may not be assumed inside the trait defining them. -// ie. they only resolve to `::A`, not the actual type `()` +// i.e. they only resolve to `::A`, not the actual type `()` trait Tr { type A = (); //~ NOTE associated type defaults can't be assumed inside the trait defining them diff --git a/tests/ui/associated-types/issue-54182-1.rs b/tests/ui/associated-types/issue-54182-1.rs index 1ebcca758c0fc..57cf93dfee92f 100644 --- a/tests/ui/associated-types/issue-54182-1.rs +++ b/tests/ui/associated-types/issue-54182-1.rs @@ -3,7 +3,7 @@ // Tests that the return type of trait methods is correctly normalized when // checking that a method in an impl matches the trait definition when the // return type involves a defaulted associated type. -// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`, +// i.e. the trait has a method with return type `-> Self::R`, and `type R = ()`, // but the impl leaves out the return type (resulting in `()`). // Note that specialization is not involved in this test; no items in // implementations may be overridden. If they were, the normalization wouldn't diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.rs b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs new file mode 100644 index 0000000000000..95a050fe444ab --- /dev/null +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs @@ -0,0 +1,43 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +//@[with_gate] check-pass + +#![cfg_attr(with_gate, feature(impl_restriction))] +#![cfg_attr(with_gate, allow(incomplete_features))] +#![feature(auto_traits, const_trait_impl)] + +pub impl(crate) trait Bar {} //[without_gate]~ ERROR `impl` restrictions are experimental +pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental + +mod foo { + pub impl(in crate::foo) trait Baz {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe impl(super) trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub auto impl(self) trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const impl(in self) trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental + + mod foo_inner { + pub impl(in crate::foo::foo_inner) trait Qux {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + } + + #[cfg(false)] + pub impl(crate) trait Bar {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub unsafe impl(self) trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub auto impl(in super) trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + #[cfg(false)] + pub const impl(super) trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + + #[cfg(false)] + mod cfged_out_foo { + pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + } + + // auto traits cannot be const, so we do not include these combinations in the test. +} diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr new file mode 100644 index 0000000000000..4f99d962d4bb7 --- /dev/null +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr @@ -0,0 +1,173 @@ +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:9:5 + | +LL | pub impl(crate) trait Bar {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:10:5 + | +LL | pub impl(in crate) trait BarInCrate {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:13:9 + | +LL | pub impl(in crate::foo) trait Baz {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:14:16 + | +LL | pub unsafe impl(super) trait BazUnsafeSuper {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:15:14 + | +LL | pub auto impl(self) trait BazAutoSelf {} + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:16:15 + | +LL | pub const impl(in self) trait BazConst {} + | ^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:19:13 + | +LL | pub impl(in crate::foo::foo_inner) trait Qux {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:20:25 + | +LL | ... pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:21:26 + | +LL | ... pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:25:9 + | +LL | pub impl(crate) trait Bar {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:27:9 + | +LL | pub impl(in crate) trait BarInCrate {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:29:16 + | +LL | pub unsafe impl(self) trait BazUnsafeSelf {} + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:31:14 + | +LL | pub auto impl(in super) trait BazAutoSuper {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:33:15 + | +LL | pub const impl(super) trait BazConstSuper {} + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:37:13 + | +LL | pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:38:25 + | +LL | ... pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/feature-gate-impl-restriction.rs:39:26 + | +LL | ... pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 17 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs new file mode 100644 index 0000000000000..d6490d5b4f978 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs @@ -0,0 +1,20 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +#![cfg_attr(with_gate, feature(impl_restriction))] +//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes +#![feature(auto_traits, const_trait_impl)] + +mod foo { + pub impl(crate::foo) trait Baz {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub unsafe impl(crate::foo) trait BazUnsafe {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub auto impl(crate::foo) trait BazAuto {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub const impl(crate::foo) trait BazConst {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub const unsafe impl(crate::foo) trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental + pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction + //[without_gate]~^ ERROR `impl` restrictions are experimental +} diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr new file mode 100644 index 0000000000000..ad183b23e0138 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr @@ -0,0 +1,107 @@ +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub impl(in crate::foo) trait Baz {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub auto impl(in crate::foo) trait BazAuto {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const impl(in crate::foo) trait BazConst {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} + | ++ + +warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/recover-incorrect-impl-restriction.rs:3:32 + | +LL | #![cfg_attr(with_gate, feature(impl_restriction))] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 6 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr new file mode 100644 index 0000000000000..d949172ffb458 --- /dev/null +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr @@ -0,0 +1,159 @@ +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:8:14 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub impl(in crate::foo) trait Baz {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:10:21 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:12:19 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub auto impl(in crate::foo) trait BazAuto {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:14:20 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const impl(in crate::foo) trait BazConst {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:16:27 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} + | ++ + +error: incorrect `impl` restriction + --> $DIR/recover-incorrect-impl-restriction.rs:18:26 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^ + | + = help: some possible `impl` restrictions are: + `impl(crate)`: can only be implemented in the current crate + `impl(super)`: can only be implemented in the parent module + `impl(self)`: can only be implemented in current module + `impl(in path::to::module)`: can only be implemented in the specified path +help: help: use `in` to restrict implementations to the path `crate::foo` + | +LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} + | ++ + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:8:9 + | +LL | pub impl(crate::foo) trait Baz {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:10:16 + | +LL | pub unsafe impl(crate::foo) trait BazUnsafe {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:12:14 + | +LL | pub auto impl(crate::foo) trait BazAuto {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:14:15 + | +LL | pub const impl(crate::foo) trait BazConst {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:16:22 + | +LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/recover-incorrect-impl-restriction.rs:18:21 + | +LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs new file mode 100644 index 0000000000000..62622e1d55861 --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs @@ -0,0 +1,28 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: with_gate without_gate +#![cfg_attr(with_gate, feature(impl_restriction))] +//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes +#![feature(auto_traits, const_trait_impl, trait_alias)] + +impl(crate) trait Alias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//[without_gate]~^ ERROR `impl` restrictions are experimental +auto impl(in crate) trait AutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//~^ ERROR trait aliases cannot be `auto` +//[without_gate]~| ERROR `impl` restrictions are experimental +unsafe impl(self) trait UnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//~^ ERROR trait aliases cannot be `unsafe` +//[without_gate]~| ERROR `impl` restrictions are experimental +const impl(in self) trait ConstAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +//[without_gate]~^ ERROR `impl` restrictions are experimental + +mod foo { + impl(super) trait InnerAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //[without_gate]~^ ERROR `impl` restrictions are experimental + const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //~^ ERROR trait aliases cannot be `unsafe` + //[without_gate]~| ERROR `impl` restrictions are experimental + unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + //~^ ERROR trait aliases cannot be `auto` + //~^^ ERROR trait aliases cannot be `unsafe` + //[without_gate]~| ERROR `impl` restrictions are experimental +} diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr new file mode 100644 index 0000000000000..70287aca42aad --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr @@ -0,0 +1,83 @@ +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:32 + | +LL | #![cfg_attr(with_gate, feature(impl_restriction))] + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 12 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr new file mode 100644 index 0000000000000..7bff90396708d --- /dev/null +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr @@ -0,0 +1,145 @@ +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:1 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:1 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:5 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error: trait aliases cannot be `auto` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` + +error: trait aliases cannot be `unsafe` + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` + +error: trait aliases cannot be `impl`-restricted + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:5 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 + | +LL | impl(crate) trait Alias = Copy; + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:6 + | +LL | auto impl(in crate) trait AutoAlias = Copy; + | ^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:8 + | +LL | unsafe impl(self) trait UnsafeAlias = Copy; + | ^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:7 + | +LL | const impl(in self) trait ConstAlias = Copy; + | ^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:19:5 + | +LL | impl(super) trait InnerAlias = Copy; + | ^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:21:18 + | +LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `impl` restrictions are experimental + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:24:17 + | +LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #105077 for more information + = help: add `#![feature(impl_restriction)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 890b429b4ac7d..f4f66745372b5 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -800,6 +800,111 @@ macro_rules! p { }; } +#[test] +fn test_impl_restriction() { + assert_eq!( + stringify!(pub impl(crate) trait Foo {}), + "pub impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in crate) trait Foo {}), + "pub impl(in crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(super) trait Foo {}), + "pub impl(super) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in super) trait Foo {}), + "pub impl(in super) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(self) trait Foo {}), + "pub impl(self) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in self) trait Foo {}), + "pub impl(in self) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in path::to) trait Foo {}), + "pub impl(in path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in ::path::to) trait Foo {}), + "pub impl(in ::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in self::path::to) trait Foo {}), + "pub impl(in self::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in super::path::to) trait Foo {}), + "pub impl(in super::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub impl(in crate::path::to) trait Foo {}), + "pub impl(in crate::path::to) trait Foo {}" + ); + + assert_eq!( + stringify!(pub auto impl(crate) trait Foo {}), + "pub auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub auto impl(in crate::path::to) trait Foo {}), + "pub auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe impl(crate) trait Foo {}), + "pub unsafe impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe impl(in crate::path::to) trait Foo {}), + "pub unsafe impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const impl(crate) trait Foo {}), + "pub const impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const impl(in crate::path::to) trait Foo {}), + "pub const impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe auto impl(crate) trait Foo {}), + "pub unsafe auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub unsafe auto impl(in crate::path::to) trait Foo {}), + "pub unsafe auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const auto impl(crate) trait Foo {}), + "pub const auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const auto impl(in crate::path::to) trait Foo {}), + "pub const auto impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe impl(crate) trait Foo {}), + "pub const unsafe impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe impl(in crate::path::to) trait Foo {}), + "pub const unsafe impl(in crate::path::to) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe auto impl(crate) trait Foo {}), + "pub const unsafe auto impl(crate) trait Foo {}" + ); + assert_eq!( + stringify!(pub const unsafe auto impl(in crate::path::to) trait Foo {}), + "pub const unsafe auto impl(in crate::path::to) trait Foo {}" + ); +} + #[test] fn test_punct() { // For all these cases, we should preserve spaces between the tokens. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs index b3953c2e8d029..eb1da3f6ecf3b 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/struct.rs @@ -39,7 +39,7 @@ fn main() { // Everything below this is expected to compile successfully. // We only test matching here as we cannot create non-exhaustive -// structs from another crate. ie. they'll never pass in run-pass tests. +// structs from another crate. i.e. they'll never pass in run-pass tests. fn match_structs(ns: NormalStruct, ts: TupleStruct, us: UnitStruct) { let NormalStruct { first_field, second_field, .. } = ns; diff --git a/tests/ui/rmeta/no_optitimized_mir.rs b/tests/ui/rmeta/no_optimized_mir.rs similarity index 75% rename from tests/ui/rmeta/no_optitimized_mir.rs rename to tests/ui/rmeta/no_optimized_mir.rs index c8ed00b039b23..dbf612cd03cc7 100644 --- a/tests/ui/rmeta/no_optitimized_mir.rs +++ b/tests/ui/rmeta/no_optimized_mir.rs @@ -10,4 +10,5 @@ fn main() { rmeta_meta::missing_optimized_mir(); } +//~? ERROR crate `rmeta_meta` required to be available in rlib format, but was not found in this form //~? ERROR missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` diff --git a/tests/ui/rmeta/no_optitimized_mir.stderr b/tests/ui/rmeta/no_optimized_mir.stderr similarity index 69% rename from tests/ui/rmeta/no_optitimized_mir.stderr rename to tests/ui/rmeta/no_optimized_mir.stderr index 254f100aa7b5e..91aa98172fe56 100644 --- a/tests/ui/rmeta/no_optitimized_mir.stderr +++ b/tests/ui/rmeta/no_optimized_mir.stderr @@ -1,3 +1,5 @@ +error: crate `rmeta_meta` required to be available in rlib format, but was not found in this form + error: missing optimized MIR for `missing_optimized_mir` in the crate `rmeta_meta` | note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled with `--emit=metadata`?) @@ -6,5 +8,5 @@ note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled w LL | pub fn missing_optimized_mir() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors