diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 04bad6142b6cc..455e5dd6c0b2f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3547,6 +3547,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 }`. @@ -3746,6 +3759,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..8fec629161eac 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, }; @@ -338,7 +338,11 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) } } - Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)) + let linker = Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend); + + tcx.report_unused_features(); + + Some(linker) }); // Linking is done outside the `compiler.enter()` so that the @@ -556,9 +560,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 +589,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_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index eab919f08ab50..ada99296f8d55 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,9 +7,7 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![cfg_attr(bootstrap, feature(assert_matches))] #![feature(associated_type_defaults)] -#![feature(box_patterns)] #![feature(default_field_values)] -#![feature(error_reporter)] #![feature(macro_metavar_expr_concat)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index db8f459ef0451..db6e9298e235e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1330,7 +1330,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ safety: AttributeSafety::Normal, template: template!(NameValueStr: "name"), duplicates: ErrorFollowing, - gate: Gated{ + gate: Gated { feature: sym::rustc_attrs, message: "use of an internal attribute", check: Features::rustc_attrs, diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 619726f0d5d8f..9d046bdef1cf3 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -137,5 +137,5 @@ pub use builtin_attrs::{ pub use removed::REMOVED_LANG_FEATURES; pub use unstable::{ DEPENDENT_FEATURES, EnabledLangFeature, EnabledLibFeature, Features, INCOMPATIBLE_FEATURES, - UNSTABLE_LANG_FEATURES, + TRACK_FEATURE, UNSTABLE_LANG_FEATURES, }; diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f36102fdc73f0..3b15183be0b2d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -3,11 +3,18 @@ use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; +use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::FxHashSet; use rustc_span::{Span, Symbol, sym}; use super::{Feature, to_nonzero}; +fn default_track_feature(_: Symbol) {} + +/// Recording used features in the dependency graph so incremental can +/// replay used features when needed. +pub static TRACK_FEATURE: AtomicRef = AtomicRef::new(&(default_track_feature as _)); + #[derive(PartialEq)] enum FeatureStatus { Default, @@ -103,7 +110,12 @@ impl Features { /// Is the given feature enabled (via `#[feature(...)]`)? pub fn enabled(&self, feature: Symbol) -> bool { - self.enabled_features.contains(&feature) + if self.enabled_features.contains(&feature) { + TRACK_FEATURE(feature); + true + } else { + false + } } } @@ -124,7 +136,7 @@ macro_rules! declare_features { impl Features { $( pub fn $feature(&self) -> bool { - self.enabled_features.contains(&sym::$feature) + self.enabled(sym::$feature) } )* @@ -520,6 +532,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/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index 4a1da0f50cc23..9ddbc496e6d43 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -12,8 +12,9 @@ use std::fmt; use rustc_errors::DiagInner; -use rustc_middle::dep_graph::TaskDepsRef; +use rustc_middle::dep_graph::{DepNodeIndex, QuerySideEffect, TaskDepsRef}; use rustc_middle::ty::tls; +use rustc_span::Symbol; fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { tls::with_context_opt(|icx| { @@ -51,6 +52,25 @@ fn track_diagnostic(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) }) } +fn track_feature(feature: Symbol) { + tls::with_context_opt(|icx| { + let Some(icx) = icx else { + return; + }; + let tcx = icx.tcx; + + if let Some(dep_node_index) = tcx.sess.used_features.lock().get(&feature).copied() { + tcx.dep_graph.read_index(DepNodeIndex::from_u32(dep_node_index)); + } else { + let dep_node_index = tcx + .dep_graph + .encode_side_effect(tcx, QuerySideEffect::CheckFeature { symbol: feature }); + tcx.sess.used_features.lock().insert(feature, dep_node_index.as_u32()); + tcx.dep_graph.read_index(dep_node_index); + } + }) +} + /// This is a callback from `rustc_hir` as it cannot access the implicit state /// in `rustc_middle` otherwise. fn def_id_debug(def_id: rustc_hir::def_id::DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -70,4 +90,5 @@ pub fn setup_callbacks() { rustc_span::SPAN_TRACK.swap(&(track_span_parent as fn(_))); rustc_hir::def_id::DEF_ID_DEBUG.swap(&(def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); rustc_errors::TRACK_DIAGNOSTIC.swap(&(track_diagnostic as _)); + rustc_feature::TRACK_FEATURE.swap(&(track_feature as _)); } 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_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 8d498b32cd8af..c1df8aac6f319 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1088,11 +1088,6 @@ declare_lint! { /// crate-level [`feature` attributes]. /// /// [`feature` attributes]: https://doc.rust-lang.org/nightly/unstable-book/ - /// - /// Note: This lint is currently not functional, see [issue #44232] for - /// more details. - /// - /// [issue #44232]: https://github.com/rust-lang/rust/issues/44232 pub UNUSED_FEATURES, Warn, "unused features found in crate-level `#[feature]` directives" diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index a71373c62f38e..882e859247782 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -17,6 +17,7 @@ use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::Session; +use rustc_span::Symbol; use tracing::{debug, instrument}; #[cfg(debug_assertions)] use {super::debug::EdgeFilter, std::env}; @@ -45,6 +46,11 @@ pub enum QuerySideEffect { /// the query as green, as that query will have the side /// effect dep node as a dependency. Diagnostic(DiagInner), + /// Records the feature used during query execution. + /// This feature will be inserted into `sess.used_features` + /// if we mark the query as green, as that query will have + /// the side effect dep node as a dependency. + CheckFeature { symbol: Symbol }, } #[derive(Clone)] pub struct DepGraph { @@ -514,29 +520,40 @@ impl DepGraph { } } - /// This encodes a diagnostic by creating a node with an unique index and associating - /// `diagnostic` with it, for use in the next session. + /// This encodes a side effect by creating a node with an unique index and associating + /// it with the node, for use in the next session. #[inline] pub fn record_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) { if let Some(ref data) = self.data { read_deps(|task_deps| match task_deps { TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return, TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => { - self.read_index(data.encode_diagnostic(tcx, diagnostic)); + let dep_node_index = data + .encode_side_effect(tcx, QuerySideEffect::Diagnostic(diagnostic.clone())); + self.read_index(dep_node_index); } }) } } - /// This forces a diagnostic node green by running its side effect. `prev_index` would - /// refer to a node created used `encode_diagnostic` in the previous session. + /// This forces a side effect node green by running its side effect. `prev_index` would + /// refer to a node created used `encode_side_effect` in the previous session. #[inline] - pub fn force_diagnostic_node<'tcx>( + pub fn force_side_effect<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) { + if let Some(ref data) = self.data { + data.force_side_effect(tcx, prev_index); + } + } + + #[inline] + pub fn encode_side_effect<'tcx>( &self, tcx: TyCtxt<'tcx>, - prev_index: SerializedDepNodeIndex, - ) { + side_effect: QuerySideEffect, + ) -> DepNodeIndex { if let Some(ref data) = self.data { - data.force_diagnostic_node(tcx, prev_index); + data.encode_side_effect(tcx, side_effect) + } else { + self.next_virtual_depnode_index() } } @@ -673,10 +690,14 @@ impl DepGraphData { self.debug_loaded_from_disk.lock().insert(dep_node); } - /// This encodes a diagnostic by creating a node with an unique index and associating - /// `diagnostic` with it, for use in the next session. + /// This encodes a side effect by creating a node with an unique index and associating + /// it with the node, for use in the next session. #[inline] - fn encode_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) -> DepNodeIndex { + fn encode_side_effect<'tcx>( + &self, + tcx: TyCtxt<'tcx>, + side_effect: QuerySideEffect, + ) -> DepNodeIndex { // Use `send_new` so we get an unique index, even though the dep node is not. let dep_node_index = self.current.encoder.send_new( DepNode { @@ -684,28 +705,21 @@ impl DepGraphData { key_fingerprint: PackedFingerprint::from(Fingerprint::ZERO), }, Fingerprint::ZERO, - // We want the side effect node to always be red so it will be forced and emit the - // diagnostic. + // We want the side effect node to always be red so it will be forced and run the + // side effect. std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(), ); - let side_effect = QuerySideEffect::Diagnostic(diagnostic.clone()); tcx.store_side_effect(dep_node_index, side_effect); dep_node_index } - /// This forces a diagnostic node green by running its side effect. `prev_index` would - /// refer to a node created used `encode_diagnostic` in the previous session. + /// This forces a side effect node green by running its side effect. `prev_index` would + /// refer to a node created used `encode_side_effect` in the previous session. #[inline] - fn force_diagnostic_node<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) { + fn force_side_effect<'tcx>(&self, tcx: TyCtxt<'tcx>, prev_index: SerializedDepNodeIndex) { with_deps(TaskDepsRef::Ignore, || { let side_effect = tcx.load_side_effect(prev_index).unwrap(); - match &side_effect { - QuerySideEffect::Diagnostic(diagnostic) => { - tcx.dcx().emit_diagnostic(diagnostic.clone()); - } - } - // Use `send_and_color` as `promote_node_and_deps_to_current` expects all // green dependencies. `send_and_color` will also prevent multiple nodes // being encoded for concurrent calls. @@ -720,6 +734,16 @@ impl DepGraphData { std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(), true, ); + + match &side_effect { + QuerySideEffect::Diagnostic(diagnostic) => { + tcx.dcx().emit_diagnostic(diagnostic.clone()); + } + QuerySideEffect::CheckFeature { symbol } => { + tcx.sess.used_features.lock().insert(*symbol, dep_node_index.as_u32()); + } + } + // This will just overwrite the same value for concurrent calls. tcx.store_side_effect(dep_node_index, side_effect); }) 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_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 27f2a534adb59..68819445a06c4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -36,7 +36,7 @@ use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState}; use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; -use rustc_hir::{self as hir, HirId, Node, TraitCandidate, find_attr}; +use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::Session; @@ -1688,6 +1688,36 @@ impl<'tcx> TyCtxt<'tcx> { self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error }); } } + + pub fn report_unused_features(self) { + // Collect first to avoid holding the lock while linting. + let used_features = self.sess.used_features.lock(); + let unused_features = self + .features() + .enabled_features_iter_stable_order() + .filter(|(f, _)| { + !used_features.contains_key(f) + // FIXME: `restricted_std` is used to tell a standard library built + // for a platform that it doesn't know how to support. But it + // could only gate a private mod (see `__restricted_std_workaround`) + // with `cfg(not(restricted_std))`, so it cannot be recorded as used + // in downstream crates. It should never be linted, but should we + // hack this in the linter to ignore it? + && f.as_str() != "restricted_std" + }) + .collect::>(); + + for (feature, span) in unused_features { + self.node_span_lint( + rustc_session::lint::builtin::UNUSED_FEATURES, + CRATE_HIR_ID, + span, + |lint| { + lint.primary_message(format!("feature `{}` is declared but not used", feature)); + }, + ); + } + } } macro_rules! nop_lift { 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..c0f1a13c35a9f 100644 --- a/compiler/rustc_query_impl/src/dep_kind_vtables.rs +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -40,7 +40,7 @@ mod non_query { is_eval_always: false, key_fingerprint_style: KeyFingerprintStyle::Unit, force_from_dep_node_fn: Some(|tcx, _, prev_index| { - tcx.dep_graph.force_diagnostic_node(tcx, prev_index); + tcx.dep_graph.force_side_effect(tcx, prev_index); true }), promote_from_disk_fn: None, 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_session/src/session.rs b/compiler/rustc_session/src/session.rs index dc18b05c75763..30840a4872733 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -166,6 +166,11 @@ pub struct Session { /// Used by `-Zmir-opt-bisect-limit` to assign an index to each /// optimization-pass execution candidate during this compilation. pub mir_opt_bisect_eval_count: AtomicUsize, + + /// Enabled features that are used in the current compilation. + /// + /// The value is the `DepNodeIndex` of the node encodes the used feature. + pub used_features: Lock>, } #[derive(Clone, Copy)] @@ -1096,6 +1101,7 @@ pub fn build_session( replaced_intrinsics: FxHashSet::default(), // filled by `run_compiler` thin_lto_supported: true, // filled by `run_compiler` mir_opt_bisect_eval_count: AtomicUsize::new(0), + used_features: Lock::default(), }; validate_commandline_args_with_session_available(&sess); 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/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 60b26126cf6be..699a5010282b0 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -1,6 +1,5 @@ #![feature(allocator_api)] #![feature(binary_heap_pop_if)] -#![feature(btree_merge)] #![feature(const_heap)] #![feature(deque_extend_front)] #![feature(iter_array_chunks)] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index ef937fccb47f3..ff483f4062ac9 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1521,7 +1521,11 @@ impl f16 { // Functions in this module fall into `core_float_math` // #[unstable(feature = "core_float_math", issue = "137578")] #[cfg(not(test))] -#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] +#[doc(test(attr( + feature(cfg_target_has_reliable_f16_f128), + expect(internal_features), + allow(unused_features) +)))] impl f16 { /// Returns the largest integer less than or equal to `self`. /// diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 7cd946dc9a03f..d150d2f622d9d 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -51,7 +51,6 @@ #![feature(f16)] #![feature(f128)] #![feature(float_algebraic)] -#![feature(float_bits_const)] #![feature(float_exact_integer_constants)] #![feature(float_gamma)] #![feature(float_minimum_maximum)] 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/std/src/num/f16.rs b/library/std/src/num/f16.rs index 318a0b3af86a2..7ca266c8a5f60 100644 --- a/library/std/src/num/f16.rs +++ b/library/std/src/num/f16.rs @@ -16,6 +16,7 @@ use crate::intrinsics; use crate::sys::cmath; #[cfg(not(test))] +#[doc(test(attr(allow(unused_features))))] impl f16 { /// Raises a number to a floating point power. /// diff --git a/library/std/src/process.rs b/library/std/src/process.rs index a682873f969c8..321b68b3225ad 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1381,6 +1381,7 @@ impl Output { /// # Examples /// /// ``` + /// # #![allow(unused_features)] /// #![feature(exit_status_error)] /// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] { /// use std::process::Command; @@ -1960,6 +1961,7 @@ impl crate::sealed::Sealed for ExitStatusError {} pub struct ExitStatusError(imp::ExitStatusError); #[unstable(feature = "exit_status_error", issue = "84908")] +#[doc(test(attr(allow(unused_features))))] impl ExitStatusError { /// Reports the exit code, if applicable, from an `ExitStatusError`. /// 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/src/lib.rs b/src/tools/miri/src/lib.rs index 32cadddc33aa3..e5791d333fd78 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -41,6 +41,8 @@ clippy::len_zero, // We are not implementing queries here so it's fine rustc::potential_query_instability, + // FIXME: Unused features should be removed in the future + unused_features, )] #![warn( rust_2018_idioms, 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/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index 68b3afc3e8414..e83ddb859498b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -10,7 +10,7 @@ feature = "sysroot-abi", feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span) )] -#![allow(internal_features)] +#![allow(internal_features, unused_features)] #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #[cfg(feature = "in-rust-tree")] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 65de804404831..734cb4ecc1693 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -18,7 +18,8 @@ internal_features, clippy::disallowed_types, clippy::print_stderr, - unused_crate_dependencies + unused_crate_dependencies, + unused_features )] #![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)] 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/incremental/add_private_fn_at_krate_root_cc/struct_point.rs b/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs index 0367af8d53b8d..be1f27e7bae3e 100644 --- a/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs +++ b/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs @@ -9,7 +9,6 @@ //@ ignore-backends: gcc #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![crate_type = "rlib"] diff --git a/tests/incremental/change_add_field/struct_point.rs b/tests/incremental/change_add_field/struct_point.rs index fb363c9ce496f..024812bd4bebb 100644 --- a/tests/incremental/change_add_field/struct_point.rs +++ b/tests/incremental/change_add_field/struct_point.rs @@ -9,7 +9,6 @@ //@ ignore-backends: gcc #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![crate_type = "rlib"] diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs index 4fd0c345aad21..d08e76c47527b 100644 --- a/tests/incremental/change_crate_dep_kind.rs +++ b/tests/incremental/change_crate_dep_kind.rs @@ -8,7 +8,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ ignore-backends: gcc -#![feature(panic_unwind)] +#![cfg_attr(cfail1, feature(panic_unwind))] // Turn the panic_unwind crate from an explicit into an implicit query: #[cfg(cfail1)] diff --git a/tests/incremental/change_private_fn/struct_point.rs b/tests/incremental/change_private_fn/struct_point.rs index cce26fa7a3e6e..2c2560309d27e 100644 --- a/tests/incremental/change_private_fn/struct_point.rs +++ b/tests/incremental/change_private_fn/struct_point.rs @@ -7,7 +7,6 @@ //@ ignore-backends: gcc #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![crate_type = "rlib"] diff --git a/tests/incremental/change_private_fn_cc/struct_point.rs b/tests/incremental/change_private_fn_cc/struct_point.rs index 87392ca857ed7..cfe26be225d30 100644 --- a/tests/incremental/change_private_fn_cc/struct_point.rs +++ b/tests/incremental/change_private_fn_cc/struct_point.rs @@ -9,7 +9,6 @@ #![crate_type = "rlib"] #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="cfail2")] diff --git a/tests/incremental/change_private_impl_method/struct_point.rs b/tests/incremental/change_private_impl_method/struct_point.rs index dc0ba82c0a311..42793b53378d4 100644 --- a/tests/incremental/change_private_impl_method/struct_point.rs +++ b/tests/incremental/change_private_impl_method/struct_point.rs @@ -7,7 +7,6 @@ //@ ignore-backends: gcc #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![crate_type = "rlib"] diff --git a/tests/incremental/change_private_impl_method_cc/struct_point.rs b/tests/incremental/change_private_impl_method_cc/struct_point.rs index eb51af7209495..c554a2f3db96b 100644 --- a/tests/incremental/change_private_impl_method_cc/struct_point.rs +++ b/tests/incremental/change_private_impl_method_cc/struct_point.rs @@ -9,7 +9,6 @@ #![crate_type = "rlib"] #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![rustc_partition_reused(module="struct_point-fn_read_field", cfg="cfail2")] diff --git a/tests/incremental/change_pub_inherent_method_body/struct_point.rs b/tests/incremental/change_pub_inherent_method_body/struct_point.rs index b8e06d070a3c7..d024432266694 100644 --- a/tests/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/tests/incremental/change_pub_inherent_method_body/struct_point.rs @@ -7,7 +7,6 @@ #![crate_type = "rlib"] #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] #![rustc_partition_codegened(module="struct_point-point", cfg="cfail2")] diff --git a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs index 3672ec268010e..5c24199df6aa8 100644 --- a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs @@ -7,7 +7,6 @@ #![crate_type = "rlib"] #![feature(rustc_attrs)] -#![feature(stmt_expr_attributes)] #![allow(dead_code)] // These are expected to require codegen. diff --git a/tests/incremental/lint-unused-features.rs b/tests/incremental/lint-unused-features.rs new file mode 100644 index 0000000000000..a7f66504f6a0c --- /dev/null +++ b/tests/incremental/lint-unused-features.rs @@ -0,0 +1,41 @@ +//@ revisions: rpass cfail +//@ ignore-backends: gcc + +#![deny(unused_features)] + +// Used language features +#![feature(box_patterns)] +#![feature(decl_macro)] +#![cfg_attr(all(), feature(rustc_attrs))] + +// Used library features +#![feature(error_iter)] +//[cfail]~^ ERROR feature `error_iter` is declared but not used +#![cfg_attr(all(), feature(allocator_api))] +//[cfail]~^ ERROR feature `allocator_api` is declared but not used + +pub fn use_box_patterns(b: Box) -> i32 { + let box x = b; + x +} + +macro m() {} +pub fn use_decl_macro() { + m!(); +} + +#[rustc_dummy] +pub fn use_rustc_attrs() {} + +#[cfg(rpass)] +pub fn use_error_iter(e: &(dyn std::error::Error + 'static)) { + for _ in e.sources() {} +} + +#[cfg(rpass)] +pub fn use_allocator_api() { + use std::alloc::Global; + let _ = Vec::::new_in(Global); +} + +fn main() {} 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-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index 8e97b773db567..d823e76b93cd0 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -6,7 +6,6 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(ascii_char, ascii_char_variants)] extern crate rustc_driver; extern crate rustc_hir; diff --git a/tests/ui-fulldeps/rustc_public/check_transform.rs b/tests/ui-fulldeps/rustc_public/check_transform.rs index f8aa40e474468..000f1f4cb365a 100644 --- a/tests/ui-fulldeps/rustc_public/check_transform.rs +++ b/tests/ui-fulldeps/rustc_public/check_transform.rs @@ -6,7 +6,6 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; extern crate rustc_middle; 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/allocator/xcrate-use2.rs b/tests/ui/allocator/xcrate-use2.rs index a48b0beeb07e3..4580d0f908bbc 100644 --- a/tests/ui/allocator/xcrate-use2.rs +++ b/tests/ui/allocator/xcrate-use2.rs @@ -5,7 +5,6 @@ //@ aux-build:helper.rs //@ no-prefer-dynamic -#![feature(allocator_api)] extern crate custom; extern crate custom_as_global; diff --git a/tests/ui/associated-types/associated-types-impl-redirect.rs b/tests/ui/associated-types/associated-types-impl-redirect.rs index 64cae31e5693b..11812c7212bb6 100644 --- a/tests/ui/associated-types/associated-types-impl-redirect.rs +++ b/tests/ui/associated-types/associated-types-impl-redirect.rs @@ -9,7 +9,6 @@ // for `ByRef`. The right answer was to consider the result ambiguous // until more type information was available. -#![feature(lang_items)] #![no_implicit_prelude] use std::marker::Sized; diff --git a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs index 0de7617943c65..fd40438704420 100644 --- a/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs +++ b/tests/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs @@ -8,7 +8,6 @@ // for `ByRef`. The right answer was to consider the result ambiguous // until more type information was available. -#![feature(lang_items)] #![no_implicit_prelude] use std::marker::Sized; 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/async-await/async-drop/async-drop-initial.rs b/tests/ui/async-await/async-drop/async-drop-initial.rs index cd33c143fba01..427ed54fa6caa 100644 --- a/tests/ui/async-await/async-drop/async-drop-initial.rs +++ b/tests/ui/async-await/async-drop/async-drop-initial.rs @@ -5,7 +5,7 @@ // please consider modifying miri's async drop test at // `src/tools/miri/tests/pass/async-drop.rs`. -#![feature(async_drop, impl_trait_in_assoc_type)] +#![feature(async_drop)] #![allow(incomplete_features, dead_code)] //@ edition: 2021 diff --git a/tests/ui/backtrace/line-tables-only.rs b/tests/ui/backtrace/line-tables-only.rs index 7dac41119a324..b3ae8a1971b98 100644 --- a/tests/ui/backtrace/line-tables-only.rs +++ b/tests/ui/backtrace/line-tables-only.rs @@ -18,7 +18,6 @@ //@ needs-unwind //@ aux-build: line-tables-only-helper.rs -#![feature(backtrace_frames)] extern crate line_tables_only_helper; diff --git a/tests/ui/borrowck/super-let-lifetime-and-drop.rs b/tests/ui/borrowck/super-let-lifetime-and-drop.rs index 380470f792fe1..a103a6a804cc0 100644 --- a/tests/ui/borrowck/super-let-lifetime-and-drop.rs +++ b/tests/ui/borrowck/super-let-lifetime-and-drop.rs @@ -7,7 +7,7 @@ //@ [borrowck] check-fail #![allow(dropping_references)] -#![feature(super_let, stmt_expr_attributes)] +#![feature(super_let)] use std::convert::identity; diff --git a/tests/ui/cfg/cfg_stmt_expr.rs b/tests/ui/cfg/cfg_stmt_expr.rs index 361b159a354fd..128321a23320a 100644 --- a/tests/ui/cfg/cfg_stmt_expr.rs +++ b/tests/ui/cfg/cfg_stmt_expr.rs @@ -3,7 +3,6 @@ #![allow(unused_mut)] #![allow(unused_variables)] #![deny(non_snake_case)] -#![feature(stmt_expr_attributes)] fn main() { let a = 413; diff --git a/tests/ui/const-generics/transmute.rs b/tests/ui/const-generics/transmute.rs index e8ab8637932dd..6108139f3ce5c 100644 --- a/tests/ui/const-generics/transmute.rs +++ b/tests/ui/const-generics/transmute.rs @@ -1,6 +1,5 @@ //@ run-pass #![feature(generic_const_exprs)] -#![feature(transmute_generic_consts)] #![allow(incomplete_features)] fn ident(v: [[u32; H]; W]) -> [[u32; H]; W] { diff --git a/tests/ui/consts/const-fn-type-name.rs b/tests/ui/consts/const-fn-type-name.rs index 733ab79b7cdb8..5da86de8f67c8 100644 --- a/tests/ui/consts/const-fn-type-name.rs +++ b/tests/ui/consts/const-fn-type-name.rs @@ -1,7 +1,6 @@ //@ run-pass #![feature(core_intrinsics)] -#![feature(const_type_name)] #![allow(dead_code)] const fn type_name_wrapper(_: &T) -> &'static str { diff --git a/tests/ui/consts/const-ptr-nonnull-rpass.rs b/tests/ui/consts/const-ptr-nonnull-rpass.rs index 48ad72df63091..ebea036c16476 100644 --- a/tests/ui/consts/const-ptr-nonnull-rpass.rs +++ b/tests/ui/consts/const-ptr-nonnull-rpass.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(ptr_internals, test)] +#![feature(test)] extern crate test; use test::black_box as b; // prevent promotion of the argument and const-propagation of the result diff --git a/tests/ui/consts/try-operator.rs b/tests/ui/consts/try-operator.rs index cd0bf8ea57167..54a6ed26241c6 100644 --- a/tests/ui/consts/try-operator.rs +++ b/tests/ui/consts/try-operator.rs @@ -1,7 +1,6 @@ //@ ignore-backends: gcc //@ run-pass -#![feature(try_trait_v2)] #![feature(const_trait_impl)] #![feature(const_try)] diff --git a/tests/ui/contracts/internal_machinery/lowering/basics.rs b/tests/ui/contracts/internal_machinery/lowering/basics.rs index 7b3a769af8258..f4f5dc5ab1056 100644 --- a/tests/ui/contracts/internal_machinery/lowering/basics.rs +++ b/tests/ui/contracts/internal_machinery/lowering/basics.rs @@ -1,6 +1,6 @@ //@ run-pass #![expect(incomplete_features)] -#![feature(contracts, cfg_contract_checks, contracts_internals, core_intrinsics)] +#![feature(contracts, contracts_internals, core_intrinsics)] extern crate core; diff --git a/tests/ui/coroutine/control-flow.rs b/tests/ui/coroutine/control-flow.rs index f64b6f7388366..fe611b1c1c319 100644 --- a/tests/ui/coroutine/control-flow.rs +++ b/tests/ui/coroutine/control-flow.rs @@ -3,7 +3,7 @@ //@ revisions: default nomiropt //@[nomiropt]compile-flags: -Z mir-opt-level=0 -#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] +#![feature(coroutines, coroutine_trait)] use std::ops::{CoroutineState, Coroutine}; use std::pin::Pin; diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed index 128f09a118439..9bda140ce58c5 100644 --- a/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed +++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed @@ -1,6 +1,6 @@ //@ run-rustfix -#![feature(coroutines, gen_blocks, stmt_expr_attributes)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { let _ = #[coroutine] || yield; diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs index dc95259149609..d8af486e6d05a 100644 --- a/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs +++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs @@ -1,6 +1,6 @@ //@ run-rustfix -#![feature(coroutines, gen_blocks, stmt_expr_attributes)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { let _ = || yield; diff --git a/tests/ui/coroutine/non-static-is-unpin.rs b/tests/ui/coroutine/non-static-is-unpin.rs index b28bf1977145b..7dc036077f90c 100644 --- a/tests/ui/coroutine/non-static-is-unpin.rs +++ b/tests/ui/coroutine/non-static-is-unpin.rs @@ -3,7 +3,7 @@ //@[next] compile-flags: -Znext-solver //@ run-pass -#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] +#![feature(coroutines)] #![allow(dropping_copy_types)] use std::marker::PhantomPinned; diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs index 5f4584ee0226e..e13a0abcbfd63 100644 --- a/tests/ui/coroutine/other-attribute-on-gen.rs +++ b/tests/ui/coroutine/other-attribute-on-gen.rs @@ -2,7 +2,6 @@ //@ run-pass #![feature(gen_blocks)] #![feature(optimize_attribute)] -#![feature(stmt_expr_attributes)] #![feature(async_iterator)] #![allow(dead_code)] diff --git a/tests/ui/coroutine/pin-box-coroutine.rs b/tests/ui/coroutine/pin-box-coroutine.rs index d030f3ef214d1..d9674ed7341be 100644 --- a/tests/ui/coroutine/pin-box-coroutine.rs +++ b/tests/ui/coroutine/pin-box-coroutine.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] +#![feature(coroutines, coroutine_trait)] use std::ops::Coroutine; diff --git a/tests/ui/coroutine/xcrate.rs b/tests/ui/coroutine/xcrate.rs index 406152a0bf10c..6b4d81fc983f8 100644 --- a/tests/ui/coroutine/xcrate.rs +++ b/tests/ui/coroutine/xcrate.rs @@ -2,7 +2,7 @@ //@ aux-build:xcrate.rs -#![feature(coroutines, coroutine_trait)] +#![feature(coroutine_trait)] extern crate xcrate; diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index c13df48e99217..b60a1dd0b2156 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -7,7 +7,6 @@ //@ ignore-windows // Tests EIIs with default implementations. // When there's no explicit declaration, the default should be called from the declaring crate. -#![feature(extern_item_impls)] extern crate decl_with_default; diff --git a/tests/ui/eii/default/call_default_panics.rs b/tests/ui/eii/default/call_default_panics.rs index f71fddb71ba26..96b2742aa8e0a 100644 --- a/tests/ui/eii/default/call_default_panics.rs +++ b/tests/ui/eii/default/call_default_panics.rs @@ -23,7 +23,6 @@ // ``` // This is a simple test to make sure that we can unwind through these, // and that this wrapper function effectively doesn't show up in the trace. -#![feature(extern_item_impls)] extern crate decl_with_default_panics; diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index 94b2aa552a1e1..b887697574892 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -9,7 +9,6 @@ // Tests EIIs with default implementations. // When an explicit implementation is given in one dependency, and the declaration is in another, // the explicit implementation is preferred. -#![feature(extern_item_impls)] extern crate decl_with_default; extern crate impl1; diff --git a/tests/ui/eii/linking/codegen_cross_crate.rs b/tests/ui/eii/linking/codegen_cross_crate.rs index 4016712e7504a..2958a0f10521b 100644 --- a/tests/ui/eii/linking/codegen_cross_crate.rs +++ b/tests/ui/eii/linking/codegen_cross_crate.rs @@ -6,7 +6,6 @@ // FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 //@ ignore-windows // Tests whether calling EIIs works with the declaration in another crate. -#![feature(extern_item_impls)] extern crate codegen_cross_crate_other_crate as codegen; diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs index 72aec83d2cee0..60bf36074e0ae 100644 --- a/tests/ui/eii/privacy1.rs +++ b/tests/ui/eii/privacy1.rs @@ -5,7 +5,6 @@ // FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 //@ ignore-windows // Tests whether re-exports work. -#![feature(extern_item_impls)] extern crate other_crate_privacy1 as codegen; diff --git a/tests/ui/extern/extern-prelude-core.rs b/tests/ui/extern/extern-prelude-core.rs index 5108c02517c3d..05d3750ae6563 100644 --- a/tests/ui/extern/extern-prelude-core.rs +++ b/tests/ui/extern/extern-prelude-core.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(lang_items)] #![no_std] extern crate std as other; diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed index 525f78d162fc0..a2b920880221f 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed @@ -22,7 +22,6 @@ //@ [future_feature] compile-flags: -Z unstable-options #![cfg_attr(future_feature, feature(explicit_extern_abis))] -#![cfg_attr(current_feature, feature(explicit_extern_abis))] extern "C" fn _foo() {} //[current]~^ WARN `extern` declarations without an explicit ABI are deprecated diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr index cf927807c7c3c..f5cc09bef5e5d 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr @@ -1,5 +1,5 @@ warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + --> $DIR/feature-gate-explicit-extern-abis.rs:26:1 | LL | extern fn _foo() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` @@ -7,13 +7,13 @@ LL | extern fn _foo() {} = note: `#[warn(missing_abi)]` on by default warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:32:8 | LL | unsafe extern fn _bar() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:38:8 | LL | unsafe extern {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed index 525f78d162fc0..a2b920880221f 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed @@ -22,7 +22,6 @@ //@ [future_feature] compile-flags: -Z unstable-options #![cfg_attr(future_feature, feature(explicit_extern_abis))] -#![cfg_attr(current_feature, feature(explicit_extern_abis))] extern "C" fn _foo() {} //[current]~^ WARN `extern` declarations without an explicit ABI are deprecated diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr index cf927807c7c3c..f5cc09bef5e5d 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr @@ -1,5 +1,5 @@ warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + --> $DIR/feature-gate-explicit-extern-abis.rs:26:1 | LL | extern fn _foo() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` @@ -7,13 +7,13 @@ LL | extern fn _foo() {} = note: `#[warn(missing_abi)]` on by default warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:32:8 | LL | unsafe extern fn _bar() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:38:8 | LL | unsafe extern {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed index 525f78d162fc0..a2b920880221f 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed @@ -22,7 +22,6 @@ //@ [future_feature] compile-flags: -Z unstable-options #![cfg_attr(future_feature, feature(explicit_extern_abis))] -#![cfg_attr(current_feature, feature(explicit_extern_abis))] extern "C" fn _foo() {} //[current]~^ WARN `extern` declarations without an explicit ABI are deprecated diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr index cf927807c7c3c..f5cc09bef5e5d 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr @@ -1,5 +1,5 @@ warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + --> $DIR/feature-gate-explicit-extern-abis.rs:26:1 | LL | extern fn _foo() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` @@ -7,13 +7,13 @@ LL | extern fn _foo() {} = note: `#[warn(missing_abi)]` on by default warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:32:8 | LL | unsafe extern fn _bar() {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` warning: `extern` declarations without an explicit ABI are deprecated - --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:38:8 | LL | unsafe extern {} | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr index 096a6f4341699..3fad1cc76dd7c 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr @@ -1,5 +1,5 @@ error: `extern` declarations without an explicit ABI are disallowed - --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + --> $DIR/feature-gate-explicit-extern-abis.rs:26:1 | LL | extern fn _foo() {} | ^^^^^^ help: specify an ABI: `extern ""` @@ -7,7 +7,7 @@ LL | extern fn _foo() {} = help: prior to Rust 2024, a default ABI was inferred error: `extern` declarations without an explicit ABI are disallowed - --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:32:8 | LL | unsafe extern fn _bar() {} | ^^^^^^ help: specify an ABI: `extern ""` @@ -15,7 +15,7 @@ LL | unsafe extern fn _bar() {} = help: prior to Rust 2024, a default ABI was inferred error: `extern` declarations without an explicit ABI are disallowed - --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + --> $DIR/feature-gate-explicit-extern-abis.rs:38:8 | LL | unsafe extern {} | ^^^^^^ help: specify an ABI: `extern ""` diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs index 379c45f589907..2ddc817768a16 100644 --- a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs @@ -22,7 +22,6 @@ //@ [future_feature] compile-flags: -Z unstable-options #![cfg_attr(future_feature, feature(explicit_extern_abis))] -#![cfg_attr(current_feature, feature(explicit_extern_abis))] extern fn _foo() {} //[current]~^ WARN `extern` declarations without an explicit ABI are deprecated diff --git a/tests/ui/float/classify-runtime-const.rs b/tests/ui/float/classify-runtime-const.rs index ca852ea2468bc..fb7361f9cbad5 100644 --- a/tests/ui/float/classify-runtime-const.rs +++ b/tests/ui/float/classify-runtime-const.rs @@ -6,8 +6,6 @@ // This tests the float classification functions, for regular runtime code and for const evaluation. -#![feature(f16)] -#![feature(f128)] use std::num::FpCategory::*; diff --git a/tests/ui/float/conv-bits-runtime-const.rs b/tests/ui/float/conv-bits-runtime-const.rs index 1373001b74dab..e7b306714bb85 100644 --- a/tests/ui/float/conv-bits-runtime-const.rs +++ b/tests/ui/float/conv-bits-runtime-const.rs @@ -3,9 +3,10 @@ // This tests the float classification functions, for regular runtime code and for const evaluation. -#![feature(f16)] -#![feature(f128)] #![feature(cfg_target_has_reliable_f16_f128)] +#![cfg_attr(target_has_reliable_f16, feature(f16))] +#![cfg_attr(target_has_reliable_f128, feature(f128))] + #![allow(unused_macro_rules)] // expect the unexpected (`target_has_reliable_*` are not "known" configs since they are unstable) #![expect(unexpected_cfgs)] diff --git a/tests/ui/fmt/format-macro-no-std.rs b/tests/ui/fmt/format-macro-no-std.rs index d096b4de01390..31c3a9a950668 100644 --- a/tests/ui/fmt/format-macro-no-std.rs +++ b/tests/ui/fmt/format-macro-no-std.rs @@ -4,7 +4,6 @@ //@ ignore-emscripten no no_std executables //@ ignore-wasm different `main` convention -#![feature(lang_items)] #![no_std] #![no_main] diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs index df1b9e164c768..2f25f0078eecd 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -6,8 +6,8 @@ #![allow(unreachable_patterns)] #![feature(cfg_target_has_reliable_f16_f128)] -#![feature(f128)] -#![feature(f16)] +#![cfg_attr(target_has_reliable_f16, feature(f16))] +#![cfg_attr(target_has_reliable_f128, feature(f128))] macro_rules! yes { ($scrutinee:expr, $($t:tt)+) => { diff --git a/tests/ui/hygiene/xcrate.rs b/tests/ui/hygiene/xcrate.rs index 0dd9136e4d562..aa221cb5ad2a3 100644 --- a/tests/ui/hygiene/xcrate.rs +++ b/tests/ui/hygiene/xcrate.rs @@ -3,7 +3,6 @@ //@ aux-build:xcrate.rs -#![feature(decl_macro)] extern crate xcrate; 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/impl-trait/example-calendar.rs b/tests/ui/impl-trait/example-calendar.rs index c3c01f0103669..972ee5f4b63b4 100644 --- a/tests/ui/impl-trait/example-calendar.rs +++ b/tests/ui/impl-trait/example-calendar.rs @@ -1,7 +1,6 @@ //@ run-pass -#![feature(fn_traits, - step_trait, +#![feature(step_trait, unboxed_closures, )] diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index 5fee6b0b39783..242eea1f8407d 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(core_intrinsics, rustc_attrs)] +#![feature(rustc_attrs)] #[cfg(any( target_os = "aix", diff --git a/tests/ui/io-checks/write-macro-error.rs b/tests/ui/io-checks/write-macro-error.rs index 857ea0024e16c..90b9537b56da6 100644 --- a/tests/ui/io-checks/write-macro-error.rs +++ b/tests/ui/io-checks/write-macro-error.rs @@ -4,7 +4,6 @@ //@ run-pass //@ needs-unwind -#![feature(io_error_uncategorized)] use std::fmt; use std::io::{self, Error, Write}; diff --git a/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs b/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs index 48ca39300f41c..6f66e6c0f67fd 100644 --- a/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs +++ b/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs @@ -15,7 +15,7 @@ #![allow(incomplete_features)] #![feature(raw_dylib_elf)] -#![feature(native_link_modifiers_as_needed)] +#![cfg_attr(not(no_modifier), feature(native_link_modifiers_as_needed))] #[cfg_attr( as_needed, diff --git a/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs b/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs index eb110869e44e8..77ef6fab16cd1 100644 --- a/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs +++ b/tests/ui/lint/lint-expr-stmt-attrs-for-early-lints.rs @@ -1,6 +1,5 @@ //@ run-pass -#![feature(stmt_expr_attributes)] #![deny(unused_parens)] // Tests that lint attributes on statements/expressions are diff --git a/tests/ui/lint/lint-unknown-feature.rs b/tests/ui/lint/lint-unknown-feature.rs index 188617467974e..b598f0d0106b1 100644 --- a/tests/ui/lint/lint-unknown-feature.rs +++ b/tests/ui/lint/lint-unknown-feature.rs @@ -4,6 +4,5 @@ #![allow(stable_features)] // FIXME(#44232) we should warn that this isn't used. -#![feature(rust1)] fn main() {} diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed index d554bbfcc98c9..a3d8b1d32a89c 100644 --- a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.fixed @@ -2,7 +2,7 @@ //@ edition:2021 #![deny(unused_qualifications)] #![deny(unused_imports)] -#![feature(coroutines, coroutine_trait)] +#![feature(coroutine_trait)] use std::ops::{ Coroutine, diff --git a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs index 4d79f5ab74530..2da45507e3e74 100644 --- a/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs +++ b/tests/ui/lint/unnecessary-qualification/lint-unnecessary-qualification-issue-121331.rs @@ -2,7 +2,7 @@ //@ edition:2021 #![deny(unused_qualifications)] #![deny(unused_imports)] -#![feature(coroutines, coroutine_trait)] +#![feature(coroutine_trait)] use std::ops::{ Coroutine, diff --git a/tests/ui/lint/unused-features/unused-language-features.rs b/tests/ui/lint/unused-features/unused-language-features.rs new file mode 100644 index 0000000000000..9334c1df0408a --- /dev/null +++ b/tests/ui/lint/unused-features/unused-language-features.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] +#![deny(unused_features)] + +// Unused language features +#![feature(coroutines)] +//~^ ERROR feature `coroutines` is declared but not used +#![feature(coroutine_clone)] +//~^ ERROR feature `coroutine_clone` is declared but not used +#![feature(stmt_expr_attributes)] +//~^ ERROR feature `stmt_expr_attributes` is declared but not used +#![feature(asm_unwind)] +//~^ ERROR feature `asm_unwind` is declared but not used + +// Enabled via cfg_attr, unused +#![cfg_attr(all(), feature(negative_impls))] +//~^ ERROR feature `negative_impls` is declared but not used + +// Not enabled via cfg_attr, so should not warn even if unused +#![cfg_attr(any(), feature(never_type))] + +macro_rules! use_asm_unwind { + () => { + unsafe { std::arch::asm!("", options(may_unwind)) }; + } +} diff --git a/tests/ui/lint/unused-features/unused-language-features.stderr b/tests/ui/lint/unused-features/unused-language-features.stderr new file mode 100644 index 0000000000000..3cede1a6fe726 --- /dev/null +++ b/tests/ui/lint/unused-features/unused-language-features.stderr @@ -0,0 +1,38 @@ +error: feature `coroutines` is declared but not used + --> $DIR/unused-language-features.rs:5:12 + | +LL | #![feature(coroutines)] + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-language-features.rs:2:9 + | +LL | #![deny(unused_features)] + | ^^^^^^^^^^^^^^^ + +error: feature `coroutine_clone` is declared but not used + --> $DIR/unused-language-features.rs:7:12 + | +LL | #![feature(coroutine_clone)] + | ^^^^^^^^^^^^^^^ + +error: feature `stmt_expr_attributes` is declared but not used + --> $DIR/unused-language-features.rs:9:12 + | +LL | #![feature(stmt_expr_attributes)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: feature `asm_unwind` is declared but not used + --> $DIR/unused-language-features.rs:11:12 + | +LL | #![feature(asm_unwind)] + | ^^^^^^^^^^ + +error: feature `negative_impls` is declared but not used + --> $DIR/unused-language-features.rs:15:28 + | +LL | #![cfg_attr(all(), feature(negative_impls))] + | ^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/lint/unused-features/unused-library-features.rs b/tests/ui/lint/unused-features/unused-library-features.rs new file mode 100644 index 0000000000000..75afd32e56cb3 --- /dev/null +++ b/tests/ui/lint/unused-features/unused-library-features.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] +#![deny(unused_features)] + +// Unused library features +#![feature(step_trait)] +//~^ ERROR feature `step_trait` is declared but not used +#![feature(is_sorted)] +//~^ ERROR feature `is_sorted` is declared but not used +//~^^ WARN the feature `is_sorted` has been stable since 1.82.0 and no longer requires an attribute to enable + +// Enabled via cfg_attr, unused +#![cfg_attr(all(), feature(slice_ptr_get))] +//~^ ERROR feature `slice_ptr_get` is declared but not used diff --git a/tests/ui/lint/unused-features/unused-library-features.stderr b/tests/ui/lint/unused-features/unused-library-features.stderr new file mode 100644 index 0000000000000..e259058d6c33b --- /dev/null +++ b/tests/ui/lint/unused-features/unused-library-features.stderr @@ -0,0 +1,34 @@ +warning: the feature `is_sorted` has been stable since 1.82.0 and no longer requires an attribute to enable + --> $DIR/unused-library-features.rs:7:12 + | +LL | #![feature(is_sorted)] + | ^^^^^^^^^ + | + = note: `#[warn(stable_features)]` on by default + +error: feature `step_trait` is declared but not used + --> $DIR/unused-library-features.rs:5:12 + | +LL | #![feature(step_trait)] + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-library-features.rs:2:9 + | +LL | #![deny(unused_features)] + | ^^^^^^^^^^^^^^^ + +error: feature `is_sorted` is declared but not used + --> $DIR/unused-library-features.rs:7:12 + | +LL | #![feature(is_sorted)] + | ^^^^^^^^^ + +error: feature `slice_ptr_get` is declared but not used + --> $DIR/unused-library-features.rs:12:28 + | +LL | #![cfg_attr(all(), feature(slice_ptr_get))] + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted + diff --git a/tests/ui/lint/unused-features/used-language-features.rs b/tests/ui/lint/unused-features/used-language-features.rs new file mode 100644 index 0000000000000..7da4866a00d15 --- /dev/null +++ b/tests/ui/lint/unused-features/used-language-features.rs @@ -0,0 +1,22 @@ +//@ check-pass + +#![crate_type = "lib"] +#![deny(unused_features)] + +// Used language features +#![feature(box_patterns)] +#![feature(decl_macro)] +#![cfg_attr(all(), feature(rustc_attrs))] + +pub fn use_box_patterns(b: Box) -> i32 { + let box x = b; + x +} + +macro m() {} +pub fn use_decl_macro() { + m!(); +} + +#[rustc_dummy] +pub fn use_rustc_attrs() {} diff --git a/tests/ui/lint/unused-features/used-library-features.rs b/tests/ui/lint/unused-features/used-library-features.rs new file mode 100644 index 0000000000000..1747c7741880e --- /dev/null +++ b/tests/ui/lint/unused-features/used-library-features.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![crate_type = "lib"] +#![deny(unused_features)] + +// Used library features +#![feature(error_iter)] +#![cfg_attr(all(), feature(allocator_api))] + +pub fn use_error_iter(e: &(dyn std::error::Error + 'static)) { + for _ in e.sources() {} +} + +pub fn use_allocator_api() { + use std::alloc::Global; + let _ = Vec::::new_in(Global); +} diff --git a/tests/ui/lint/unused/unused_attributes-must_use.fixed b/tests/ui/lint/unused/unused_attributes-must_use.fixed index fa596da95ccd1..082096f12080a 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.fixed +++ b/tests/ui/lint/unused/unused_attributes-must_use.fixed @@ -1,6 +1,6 @@ //@ run-rustfix -#![allow(dead_code, path_statements)] +#![allow(dead_code, path_statements, unused_features)] #![deny(unused_attributes, unused_must_use)] #![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)] diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs index 3e72dd1e43833..b4b17476d0b1b 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.rs +++ b/tests/ui/lint/unused/unused_attributes-must_use.rs @@ -1,6 +1,6 @@ //@ run-rustfix -#![allow(dead_code, path_statements)] +#![allow(dead_code, path_statements, unused_features)] #![deny(unused_attributes, unused_must_use)] #![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)] diff --git a/tests/ui/lowering/issue-96847.rs b/tests/ui/lowering/issue-96847.rs index a1fd105d9dd4a..6ee40338043f6 100644 --- a/tests/ui/lowering/issue-96847.rs +++ b/tests/ui/lowering/issue-96847.rs @@ -3,7 +3,6 @@ // Test that this doesn't abort during AST lowering. In #96847 it did abort // because the attribute was being lowered twice. -#![feature(stmt_expr_attributes)] #![feature(lang_items)] fn main() { diff --git a/tests/ui/lowering/issue-96847.stderr b/tests/ui/lowering/issue-96847.stderr index 2cded32f9fb86..26bc6645ce6d4 100644 --- a/tests/ui/lowering/issue-96847.stderr +++ b/tests/ui/lowering/issue-96847.stderr @@ -1,5 +1,5 @@ error[E0522]: definition of an unknown lang item: `foo` - --> $DIR/issue-96847.rs:11:9 + --> $DIR/issue-96847.rs:10:9 | LL | #![lang="foo"] | ^^^^^^^^^^^^^^ definition of unknown lang item `foo` diff --git a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs index ae1bc00236f0f..4382c00ab13cd 100644 --- a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs +++ b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs @@ -6,7 +6,6 @@ // This test captures the behavior of macro-generating-macros with fragment // specifiers across edition boundaries. -#![feature(macro_metavar_expr)] #![allow(incomplete_features)] extern crate metavar_2018; diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs b/tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs index de7dbb9052edb..b470cd622d03c 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs @@ -5,7 +5,7 @@ //@ needs-unwind Asserting on contents of error message #![allow(path_statements, unused_allocation)] -#![feature(core_intrinsics, generic_assert)] +#![feature(generic_assert)] macro_rules! test { ( diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs b/tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs index 1600fd0af3f30..2165037244dca 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs @@ -4,7 +4,7 @@ //@ run-pass //@ needs-unwind Asserting on contents of error message -#![feature(core_intrinsics, generic_assert)] +#![feature(generic_assert)] extern crate common; diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs b/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs index 2a27164f9cba2..d75eb8b0d761b 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs @@ -3,7 +3,6 @@ //@ compile-flags: --test -Zpanic_abort_tests //@ run-pass -#![feature(core_intrinsics, generic_assert)] #[should_panic(expected = "Custom user message")] #[test] diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs b/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs index 6e5f8d6cd12d4..be4456604f627 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs @@ -3,7 +3,7 @@ //@ run-pass //@ needs-unwind Asserting on contents of error message -#![feature(core_intrinsics, generic_assert)] +#![feature(generic_assert)] extern crate common; diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs b/tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs index 254d59076e531..a5ceb3d2ecd4c 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs @@ -4,7 +4,7 @@ // ignore-tidy-linelength //@ run-pass -#![feature(core_intrinsics, generic_assert)] +#![feature(generic_assert)] use std::fmt::{Debug, Formatter}; diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 890b429b4ac7d..3f331b0dd5f14 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -9,12 +9,10 @@ #![feature(const_trait_impl)] #![feature(coroutines)] #![feature(decl_macro)] -#![feature(explicit_tail_calls)] #![feature(more_qualified_paths)] #![feature(never_patterns)] #![feature(trait_alias)] #![feature(try_blocks)] -#![feature(type_ascription)] #![feature(yeet_expr)] #![deny(unused_macros)] @@ -800,6 +798,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/match/match-float.rs b/tests/ui/match/match-float.rs index 279bb5927ac45..504740add5371 100644 --- a/tests/ui/match/match-float.rs +++ b/tests/ui/match/match-float.rs @@ -3,8 +3,8 @@ // Makes sure we use `==` (not bitwise) semantics for float comparison. #![feature(cfg_target_has_reliable_f16_f128)] -#![feature(f128)] -#![feature(f16)] +#![cfg_attr(target_has_reliable_f16, feature(f16))] +#![cfg_attr(target_has_reliable_f128, feature(f128))] #[cfg(target_has_reliable_f16)] fn check_f16() { diff --git a/tests/ui/methods/supertrait-shadowing/out-of-scope.rs b/tests/ui/methods/supertrait-shadowing/out-of-scope.rs index bd263be59cc7d..8e0f5ba978e3a 100644 --- a/tests/ui/methods/supertrait-shadowing/out-of-scope.rs +++ b/tests/ui/methods/supertrait-shadowing/out-of-scope.rs @@ -1,7 +1,6 @@ //@ run-pass //@ check-run-results -#![feature(supertrait_item_shadowing)] #![allow(dead_code)] mod out_of_scope { diff --git a/tests/ui/nll/issue-48623-coroutine.rs b/tests/ui/nll/issue-48623-coroutine.rs index 63348a2047c07..57f579106b7a9 100644 --- a/tests/ui/nll/issue-48623-coroutine.rs +++ b/tests/ui/nll/issue-48623-coroutine.rs @@ -2,7 +2,7 @@ #![allow(path_statements)] #![allow(dead_code)] -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines)] struct WithDrop; diff --git a/tests/ui/overloaded/overloaded-calls-simple.rs b/tests/ui/overloaded/overloaded-calls-simple.rs index 34b674357d89c..b53686aa94643 100644 --- a/tests/ui/overloaded/overloaded-calls-simple.rs +++ b/tests/ui/overloaded/overloaded-calls-simple.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(lang_items, unboxed_closures, fn_traits)] +#![feature(unboxed_closures, fn_traits)] struct S1 { x: i32, 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 diff --git a/tests/ui/sanitizer/memory-passing.rs b/tests/ui/sanitizer/memory-passing.rs index 6ac41b178fe7f..d41f62b310b05 100644 --- a/tests/ui/sanitizer/memory-passing.rs +++ b/tests/ui/sanitizer/memory-passing.rs @@ -13,7 +13,6 @@ // This test case intentionally limits the usage of the std, // since it will be linked with an uninstrumented version of it. -#![feature(core_intrinsics)] #![allow(invalid_value)] #![no_main] diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index ba952cdb0dc60..c86c2448cc683 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -4,12 +4,12 @@ //@ ignore-backends: gcc #![feature( repr_simd, - core_intrinsics, intrinsics, adt_const_params, unsized_const_params, generic_const_exprs )] +#![cfg_attr(old, feature(core_intrinsics))] #![allow(incomplete_features)] #[path = "../../auxiliary/minisimd.rs"] diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs index 058f06732b927..b86cdebfe19ae 100644 --- a/tests/ui/structs-enums/rec-align-u32.rs +++ b/tests/ui/structs-enums/rec-align-u32.rs @@ -3,7 +3,7 @@ #![allow(unused_unsafe)] // Issue #2303 -#![feature(core_intrinsics, rustc_attrs)] +#![feature(rustc_attrs)] use std::mem; diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs index 41b196dc5c222..e49726c7d438f 100644 --- a/tests/ui/structs-enums/rec-align-u64.rs +++ b/tests/ui/structs-enums/rec-align-u64.rs @@ -4,7 +4,7 @@ // Issue #2303 -#![feature(core_intrinsics, rustc_attrs)] +#![feature(rustc_attrs)] use std::mem; diff --git a/tests/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs b/tests/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs index 4d3c4e8accd88..4eda8fab1b63b 100644 --- a/tests/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs +++ b/tests/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs @@ -1,4 +1,5 @@ -#![feature(cfg_target_thread_local, thread_local)] +#![feature(cfg_target_thread_local)] +#![cfg_attr(target_thread_local, feature(thread_local))] #![crate_type = "lib"] #[cfg(target_thread_local)] diff --git a/tests/ui/threads-sendsync/thread-local-extern-static.rs b/tests/ui/threads-sendsync/thread-local-extern-static.rs index ce2a221ec2e41..0da4e398f335c 100644 --- a/tests/ui/threads-sendsync/thread-local-extern-static.rs +++ b/tests/ui/threads-sendsync/thread-local-extern-static.rs @@ -2,7 +2,8 @@ //@ ignore-windows FIXME(134939): thread_local + no_mangle doesn't work on Windows //@ aux-build:thread-local-extern-static.rs -#![feature(cfg_target_thread_local, thread_local)] +#![feature(cfg_target_thread_local)] +#![cfg_attr(target_thread_local, feature(thread_local))] #[cfg(target_thread_local)] extern crate thread_local_extern_static; diff --git a/tests/ui/traits/alias/import-cross-crate.rs b/tests/ui/traits/alias/import-cross-crate.rs index 65e7c90965b85..f77aa3cd05a3b 100644 --- a/tests/ui/traits/alias/import-cross-crate.rs +++ b/tests/ui/traits/alias/import-cross-crate.rs @@ -1,7 +1,6 @@ //@ run-pass //@ aux-build:greeter.rs -#![feature(trait_alias)] extern crate greeter; diff --git a/tests/ui/traits/overlap-permitted-for-marker-traits.rs b/tests/ui/traits/overlap-permitted-for-marker-traits.rs index c05e5fddae635..310516f4e4ace 100644 --- a/tests/ui/traits/overlap-permitted-for-marker-traits.rs +++ b/tests/ui/traits/overlap-permitted-for-marker-traits.rs @@ -4,7 +4,6 @@ // `MyMarker` if it is either `Debug` or `Display`. #![feature(marker_trait_attr)] -#![feature(negative_impls)] use std::fmt::{Debug, Display}; diff --git a/tests/ui/type/typeid-consistency.rs b/tests/ui/type/typeid-consistency.rs index 67ee1b6d839ab..fb22ae3ac3050 100644 --- a/tests/ui/type/typeid-consistency.rs +++ b/tests/ui/type/typeid-consistency.rs @@ -3,7 +3,6 @@ //@ run-pass #![allow(deprecated)] -#![feature(core_intrinsics)] //@ aux-build:typeid-consistency-aux1.rs //@ aux-build:typeid-consistency-aux2.rs diff --git a/tests/ui/typeck/type-name-intrinsic-usage-61894.rs b/tests/ui/typeck/type-name-intrinsic-usage-61894.rs index 8131bb273909d..f587e5fe53f97 100644 --- a/tests/ui/typeck/type-name-intrinsic-usage-61894.rs +++ b/tests/ui/typeck/type-name-intrinsic-usage-61894.rs @@ -1,7 +1,6 @@ // https://github.com/rust-lang/rust/issues/61894 //@ run-pass -#![feature(core_intrinsics)] use std::any::type_name;