diff --git a/compiler/rustc_codegen_gcc/src/callee.rs b/compiler/rustc_codegen_gcc/src/callee.rs index a96bd66ba79..9fc77627b1b 100644 --- a/compiler/rustc_codegen_gcc/src/callee.rs +++ b/compiler/rustc_codegen_gcc/src/callee.rs @@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) // whether we are sharing generics or not. The important thing here is // that the visibility we apply to the declaration is the same one that // has been applied to the definition (wherever that definition may be). - let is_generic = instance.args.non_erasable_generics().next().is_some(); + let is_generic = instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some(); if is_generic { // This is a monomorphization. Its expected visibility depends diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 36c098218cf..5254c3f9c9a 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -95,7 +95,8 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage); - let is_generic = instance.args.non_erasable_generics().next().is_some(); + let is_generic = + instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some(); if is_generic { // This is a monomorphization. Its expected visibility depends diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 52481a1090c..c862acdc7de 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -349,6 +349,7 @@ fn dbg_scope_fn( type_names::push_generic_params( tcx, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + enclosing_fn_def_id, &mut name, ); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8fb2ccb7e8a..5b869bed0a0 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -334,7 +334,7 @@ fn exported_symbols_provider_local( match *mono_item { MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => { - if args.non_erasable_generics().next().is_some() { + if args.non_erasable_generics(tcx, def).next().is_some() { let symbol = ExportedSymbol::Generic(def, args); symbols.push(( symbol, @@ -346,10 +346,10 @@ fn exported_symbols_provider_local( )); } } - MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), args }) => { + MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), args }) => { // A little sanity-check debug_assert_eq!( - args.non_erasable_generics().next(), + args.non_erasable_generics(tcx, def_id).next(), Some(GenericArgKind::Type(ty)) ); symbols.push(( diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 067c824aba0..d195e1fc02f 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -106,14 +106,14 @@ fn push_debuginfo_type_name<'tcx>( ty_and_layout, &|output, visited| { push_item_name(tcx, def.did(), true, output); - push_generic_params_internal(tcx, args, output, visited); + push_generic_params_internal(tcx, args, def.did(), output, visited); }, output, visited, ); } else { push_item_name(tcx, def.did(), qualified, output); - push_generic_params_internal(tcx, args, output, visited); + push_generic_params_internal(tcx, args, def.did(), output, visited); } } ty::Tuple(component_types) => { @@ -237,8 +237,13 @@ fn push_debuginfo_type_name<'tcx>( let principal = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal); push_item_name(tcx, principal.def_id, qualified, output); - let principal_has_generic_params = - push_generic_params_internal(tcx, principal.args, output, visited); + let principal_has_generic_params = push_generic_params_internal( + tcx, + principal.args, + principal.def_id, + output, + visited, + ); let projection_bounds: SmallVec<[_; 4]> = trait_data .projection_bounds() @@ -516,7 +521,13 @@ pub fn compute_debuginfo_vtable_name<'tcx>( tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); visited.clear(); - push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); + push_generic_params_internal( + tcx, + trait_ref.args, + trait_ref.def_id, + &mut vtable_name, + &mut visited, + ); } else { vtable_name.push('_'); } @@ -610,20 +621,20 @@ fn push_unqualified_item_name( fn push_generic_params_internal<'tcx>( tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, + def_id: DefId, output: &mut String, visited: &mut FxHashSet>, ) -> bool { - if args.non_erasable_generics().next().is_none() { + debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args)); + let mut args = args.non_erasable_generics(tcx, def_id).peekable(); + if args.peek().is_none() { return false; } - - debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args)); - let cpp_like_debuginfo = cpp_like_debuginfo(tcx); output.push('<'); - for type_parameter in args.non_erasable_generics() { + for type_parameter in args { match type_parameter { GenericArgKind::Type(type_parameter) => { push_debuginfo_type_name(tcx, type_parameter, true, output, visited); @@ -691,11 +702,12 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S pub fn push_generic_params<'tcx>( tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, + def_id: DefId, output: &mut String, ) { let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name"); let mut visited = FxHashSet::default(); - push_generic_params_internal(tcx, args, output, &mut visited); + push_generic_params_internal(tcx, args, def_id, output, &mut visited); } fn push_closure_or_generator_name<'tcx>( @@ -738,7 +750,7 @@ fn push_closure_or_generator_name<'tcx>( // Truncate the args to the length of the above generics. This will cut off // anything closure- or generator-specific. let args = args.truncate_to(tcx, generics); - push_generic_params_internal(tcx, args, output, visited); + push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited); } fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ac5468f3dfd..6dba5d2945d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1642,8 +1642,8 @@ enum Mismatch<'a> { ValuePairs::Terms(infer::ExpectedFound { expected, found }) => { match (expected.unpack(), found.unpack()) { (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => { - let is_simple_err = - expected.is_simple_text() && found.is_simple_text(); + let is_simple_err = expected.is_simple_text(self.tcx) + && found.is_simple_text(self.tcx); OpaqueTypesVisitor::visit_expected_found( self.tcx, expected, found, span, ) @@ -1885,7 +1885,7 @@ enum Similar<'tcx> { } s }; - if !(values.expected.is_simple_text() && values.found.is_simple_text()) + if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx)) || (exp_found.is_some_and(|ef| { // This happens when the type error is a subset of the expectation, // like when you have two references but one is `usize` and the other diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 8fd980d5a9e..403e80bd34c 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -78,9 +78,11 @@ pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize { } } - pub fn is_generic_fn(&self) -> bool { - match *self { - MonoItem::Fn(ref instance) => instance.args.non_erasable_generics().next().is_some(), + pub fn is_generic_fn(&self, tcx: TyCtxt<'tcx>) -> bool { + match self { + MonoItem::Fn(instance) => { + instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some() + } MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false, } } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 5db9b775a0f..e7ebb985ca4 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -70,10 +70,10 @@ pub fn is_simple_ty(self) -> bool { /// description in error messages. This is used in the primary span label. Beyond what /// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to /// ADTs with no type arguments. - pub fn is_simple_text(self) -> bool { + pub fn is_simple_text(self, tcx: TyCtxt<'tcx>) -> bool { match self.kind() { - Adt(_, args) => args.non_erasable_generics().next().is_none(), - Ref(_, ty, _) => ty.is_simple_text(), + Adt(def, args) => args.non_erasable_generics(tcx, def.did()).next().is_none(), + Ref(_, ty, _) => ty.is_simple_text(tcx), _ => self.is_simple_ty(), } } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 153b24acba1..e598ead791e 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -379,12 +379,17 @@ pub fn consts(&'tcx self) -> impl DoubleEndedIterator> + self.iter().filter_map(|k| k.as_const()) } + /// Returns generic arguments that are not lifetimes or host effect params. #[inline] pub fn non_erasable_generics( &'tcx self, + tcx: TyCtxt<'tcx>, + def_id: DefId, ) -> impl DoubleEndedIterator> + 'tcx { - self.iter().filter_map(|k| match k.unpack() { - GenericArgKind::Lifetime(_) => None, + let generics = tcx.generics_of(def_id); + self.iter().enumerate().filter_map(|(i, k)| match k.unpack() { + _ if Some(i) == generics.host_effect_index => None, + ty::GenericArgKind::Lifetime(_) => None, generic => Some(generic), }) } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index ceac21cf6ea..8e6c1cd4bbb 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -212,10 +212,12 @@ pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool { pub fn own_requires_monomorphization(&self) -> bool { for param in &self.params { match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + GenericParamDefKind::Type { .. } + | GenericParamDefKind::Const { is_host_effect: false, .. } => { return true; } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime + | GenericParamDefKind::Const { is_host_effect: true, .. } => {} } } false diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8913bf76d34..e5b9203d12a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -139,7 +139,7 @@ pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option { } // If this a non-generic instance, it cannot be a shared monomorphization. - self.args.non_erasable_generics().next()?; + self.args.non_erasable_generics(tcx, self.def_id()).next()?; match self.def { InstanceDef::Item(def) => tcx @@ -344,6 +344,7 @@ pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind { ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + ty::GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(), ty::GenericParamDefKind::Type { .. } => { bug!("Instance::mono: {:?} has type parameters", def_id) } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7d4c4a823a8..4dc7c3b6444 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -390,7 +390,12 @@ fn check_codegen_attributes( // Reachability pass defines which functions are eligible for inlining. Generally inlining // other functions is incorrect because they could reference symbols that aren't exported. - let is_generic = callsite.callee.args.non_erasable_generics().next().is_some(); + let is_generic = callsite + .callee + .args + .non_erasable_generics(self.tcx, callsite.callee.def_id()) + .next() + .is_some(); if !is_generic && !callee_attrs.requests_inline() { return Err("not exported"); } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8cbb68fc8c1..026204393ff 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -459,7 +459,7 @@ fn collect_items_rec<'tcx>( // Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the // mono item graph. if tcx.sess.diagnostic().err_count() > error_count - && starting_item.node.is_generic_fn() + && starting_item.node.is_generic_fn(tcx) && starting_item.node.is_user_defined() { let formatted_item = with_no_trimmed_paths!(starting_item.node.to_string()); @@ -1315,6 +1315,7 @@ fn create_mono_items_for_default_impls<'tcx>( // it, to validate whether or not the impl is legal to instantiate at all. let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(), GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { unreachable!( "`own_requires_monomorphization` check means that \ diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index de6db8ae6ae..c993e64477b 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -221,7 +221,7 @@ fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> Pl } let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item); - let is_volatile = is_incremental_build && mono_item.is_generic_fn(); + let is_volatile = is_incremental_build && mono_item.is_generic_fn(cx.tcx); let cgu_name = match characteristic_def_id { Some(def_id) => compute_codegen_unit_name( @@ -801,7 +801,7 @@ fn mono_item_visibility<'tcx>( return Visibility::Hidden; } - let is_generic = instance.args.non_erasable_generics().next().is_some(); + let is_generic = instance.args.non_erasable_generics(tcx, def_id).next().is_some(); // Upstream `DefId` instances get different handling than local ones. let Some(def_id) = def_id.as_local() else { diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 74538e9f5a3..535a3ea2d7e 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -108,7 +108,6 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::query::Providers; -use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_session::config::SymbolManglingVersion; @@ -144,7 +143,7 @@ fn symbol_name_provider<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty // This closure determines the instantiating crate for instances that // need an instantiating-crate-suffix for their symbol name, in order // to differentiate between local copies. - if is_generic(instance.args) { + if is_generic(instance, tcx) { // For generics we might find re-usable upstream instances. If there // is one, we rely on the symbol being instantiated locally. instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE) @@ -246,7 +245,7 @@ fn compute_symbol_name<'tcx>( // the ID of the instantiating crate. This avoids symbol conflicts // in case the same instances is emitted in two crates of the same // project. - let avoid_cross_crate_conflicts = is_generic(args) || is_globally_shared_function; + let avoid_cross_crate_conflicts = is_generic(instance, tcx) || is_globally_shared_function; let instantiating_crate = avoid_cross_crate_conflicts.then(compute_instantiating_crate); @@ -278,6 +277,6 @@ fn compute_symbol_name<'tcx>( symbol } -fn is_generic(args: GenericArgsRef<'_>) -> bool { - args.non_erasable_generics().next().is_some() +fn is_generic<'tcx>(instance: Instance<'tcx>, tcx: TyCtxt<'tcx>) -> bool { + instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some() } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index e1a15b5cf9f..da2958bf56e 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -55,6 +55,7 @@ fn resolve_instance<'tcx>( } } else { debug!(" => free item"); + // FIXME(effects): we may want to erase the effect param if that is present on this item. ty::InstanceDef::Item(def_id) }; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index d3311792cfa..2bdac1352dc 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -343,7 +343,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h // If the current self type doesn't implement Copy (due to generic constraints), search to see if // there's a Copy impl for any instance of the adt. if !is_copy(cx, ty) { - if ty_subs.non_erasable_generics().next().is_some() { + if ty_subs.non_erasable_generics(cx.tcx, ty_adt.did()).next().is_some() { let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { impls.iter().any(|&id| { matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)