From 0e46be3359830c8eb3c46bdb2b8d0a21b3cfebc8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 27 Apr 2025 21:55:50 +0000 Subject: [PATCH 1/3] Resolve instance for SymFn in global/naked asm --- .../rustc_codegen_cranelift/src/global_asm.rs | 8 ++++- .../rustc_codegen_ssa/src/mir/naked_asm.rs | 4 ++- compiler/rustc_codegen_ssa/src/mono_item.rs | 8 ++++- tests/ui/asm/global-asm-mono-sym-fn.rs | 27 ++++++++++++++ tests/ui/asm/naked-asm-mono-sym-fn.rs | 35 +++++++++++++++++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 tests/ui/asm/global-asm-mono-sym-fn.rs create mode 100644 tests/ui/asm/naked-asm-mono-sym-fn.rs diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 79cefb05de322..5561a01f35a19 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -65,7 +65,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, let ty = tcx.typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => Instance::expect_resolve( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + expr.span, + ), _ => span_bug!(op_sp, "asm sym is not a function"), }; let symbol = tcx.symbol_name(instance); diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 3a6b1f8d4efc9..c061795c913aa 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -86,7 +86,9 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ); let instance = match mono_type.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => { + Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span) + } _ => bug!("asm sym is not a function"), }; diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index f6af889fd6ecb..11e7b202a47c9 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -74,7 +74,13 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { hir::InlineAsmOperand::SymFn { expr } => { let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => Instance::expect_resolve( + cx.tcx(), + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + expr.span, + ), _ => span_bug!(*op_sp, "asm sym is not a function"), }; diff --git a/tests/ui/asm/global-asm-mono-sym-fn.rs b/tests/ui/asm/global-asm-mono-sym-fn.rs new file mode 100644 index 0000000000000..e584a98badb0d --- /dev/null +++ b/tests/ui/asm/global-asm-mono-sym-fn.rs @@ -0,0 +1,27 @@ +// Test that we're properly monomorphizing sym args in global asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64-unknown-linux-gnu +//@ build-pass + +#![no_main] + +use std::arch::global_asm; + +fn foo() { + loop {} +} + +trait Foo { + fn bar(); +} + +impl Foo for i32 { + fn bar() { + loop {} + } +} + +global_asm!(".global main", "main:", "call {}", sym ::bar); diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs new file mode 100644 index 0000000000000..2bd554beacf8c --- /dev/null +++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs @@ -0,0 +1,35 @@ +// Regression test for . +// Test that we're properly monomorphizing sym args in naked asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64 +//@ build-pass + +trait T { + extern "C" fn t(); +} + +enum E {} + +impl T for E { + extern "C" fn t() { + println!("Const generic: {}", C); + } +} + +#[unsafe(naked)] +extern "C" fn foo() { + core::arch::naked_asm!( + "push rax", + "call {fn}", + "pop rax", + "ret", + fn = sym ::t, + ); +} + +fn main() { + foo::>(); +} From 30d1fcb37418ed04623db6174afe7b420232fbef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 28 Apr 2025 14:40:16 +0000 Subject: [PATCH 2/3] Rename Instance::new to Instance::new_raw and add a note that it is raw --- .../src/intrinsics/mod.rs | 2 +- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- .../src/coverageinfo/mapgen/unused.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- .../src/back/symbol_export.rs | 4 ++-- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_lint/src/foreign_modules.rs | 2 +- .../src/middle/exported_symbols.rs | 2 +- .../rustc_middle/src/mir/interpret/queries.rs | 6 +++--- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 18 +++++++++++++----- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- compiler/rustc_smir/src/rustc_smir/builder.rs | 2 +- compiler/rustc_symbol_mangling/src/test.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 10 +++++----- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- tests/ui/asm/naked-asm-mono-sym-fn.rs | 8 ++++---- 18 files changed, 41 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index d3f47ad726334..e866b8962551a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1282,7 +1282,7 @@ fn codegen_regular_intrinsic_call<'tcx>( intrinsic.name, ); } - return Err(Instance::new(instance.def_id(), instance.args)); + return Err(Instance::new_raw(instance.def_id(), instance.args)); } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index d22f4229e2374..2ed5ec4381edf 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -399,7 +399,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } // Fall back to default body - _ => return Err(Instance::new(instance.def_id(), instance.args)), + _ => return Err(Instance::new_raw(instance.def_id(), instance.args)), }; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs index 68f60f169b5b5..fe3a7a1580b53 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs @@ -157,7 +157,7 @@ fn make_dummy_instance<'tcx>(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> ty: let def_id = local_def_id.to_def_id(); // Make a dummy instance that fills in all generics with placeholders. - ty::Instance::new( + ty::Instance::new_raw( def_id, ty::GenericArgs::for_item(tcx, def_id, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ffeab59b05c32..bfaad8f2f1ef0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -613,7 +613,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => { debug!("unknown intrinsic '{}' -- falling back to default body", name); // Call the fallback body instead of generating the intrinsic code - return Err(ty::Instance::new(instance.def_id(), instance.args)); + return Err(ty::Instance::new_raw(instance.def_id(), instance.args)); } }; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 2bfab1f43bce3..175474186ea1b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -565,7 +565,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( ExportedSymbol::Generic(def_id, args) => { rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, - Instance::new(def_id, args), + Instance::new_raw(def_id, args), instantiating_crate, ) } @@ -613,7 +613,7 @@ fn calling_convention_for_symbol<'tcx>( None } ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)), - ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)), + ExportedSymbol::Generic(def_id, args) => Some(Instance::new_raw(def_id, args)), // DropGlue always use the Rust calling convention and thus follow the target's default // symbol decoration scheme. ExportedSymbol::DropGlue(..) => None, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 309b8f2c76138..91dde13be550e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -216,7 +216,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { check::maybe_check_static_with_link_section(tcx, item_def_id); } DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { - let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); + let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 0494c78a7a97c..d0668794198ac 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -104,7 +104,7 @@ impl ClashingExternDeclarations { /// for the item, return its HirId without updating the set. fn insert(&mut self, tcx: TyCtxt<'_>, fi: hir::ForeignItemId) -> Option { let did = fi.owner_id.to_def_id(); - let instance = Instance::new(did, ty::List::identity_for_item(tcx, did)); + let instance = Instance::new_raw(did, ty::List::identity_for_item(tcx, did)); let name = Symbol::intern(tcx.symbol_name(instance).name); if let Some(&existing_id) = self.seen_decls.get(&name) { // Avoid updating the map with the new entry when we do find a collision. We want to diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 3c62017072e41..1d67d0fe3bbf4 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -56,7 +56,7 @@ impl<'tcx> ExportedSymbol<'tcx> { match *self { ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, args) => { - tcx.symbol_name(ty::Instance::new(def_id, args)) + tcx.symbol_name(ty::Instance::new_raw(def_id, args)) } ExportedSymbol::DropGlue(ty) => { tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty)) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4222a68e5447d..c7159ed8167ae 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -23,7 +23,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); self.const_eval_global_id(typing_env, cid, DUMMY_SP) @@ -39,7 +39,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); let inputs = self.erase_regions(typing_env.as_query_input(cid)); @@ -208,7 +208,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self.tcx, def_id); - let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args)); + let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args)); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 6b413a7383a5e..7243f87ee6380 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -318,7 +318,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> { match *self { MonoItem::Fn(instance) => write!(f, "fn {instance}"), MonoItem::Static(def_id) => { - write!(f, "static {}", Instance::new(def_id, GenericArgs::empty())) + write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty())) } MonoItem::GlobalAsm(..) => write!(f, "global_asm"), } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b55e4d7d83176..1e026fd751bf6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2471,7 +2471,7 @@ rustc_queries! { query resolve_instance_raw( key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { - desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } + desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } } query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index d660e7d0d6022..0d99a1b51499a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -491,7 +491,15 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { } impl<'tcx> Instance<'tcx> { - pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { + /// Creates a new [`InstanceKind::Item`] from the `def_id` and `args`. + /// + /// Note that this item corresponds to the body of `def_id` directly, which + /// likely does not make sense for trait items which need to be resolved to an + /// implementation, and which may not even have a body themselves. Usages of + /// this function should probably use [`Instance::expect_resolve`], or if run + /// in a polymorphic environment or within a lint (that may encounter ambiguity) + /// [`Instance::try_resolve`] instead. + pub fn new_raw(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { assert!( !args.has_escaping_bound_vars(), "args of instance {def_id:?} has escaping bound vars: {args:?}" @@ -510,7 +518,7 @@ impl<'tcx> Instance<'tcx> { } }); - Instance::new(def_id, args) + Instance::new_raw(def_id, args) } #[inline] @@ -603,7 +611,7 @@ impl<'tcx> Instance<'tcx> { let type_length = type_length(args); if !tcx.type_length_limit().value_within_limit(type_length) { let (shrunk, written_to_path) = - shrunk_instance_name(tcx, Instance::new(def_id, args)); + shrunk_instance_name(tcx, Instance::new_raw(def_id, args)); let mut path = PathBuf::new(); let was_written = if let Some(path2) = written_to_path { path = path2; @@ -773,7 +781,7 @@ impl<'tcx> Instance<'tcx> { match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args), - _ => Instance::new(def_id, args), + _ => Instance::new_raw(def_id, args), } } @@ -899,7 +907,7 @@ impl<'tcx> Instance<'tcx> { // This is important for `Iterator`'s combinators, but also useful for // adding future default methods to `Future`, for instance. debug_assert!(tcx.defaultness(trait_item_id).has_value()); - Some(Instance::new(trait_item_id, rcvr_args)) + Some(Instance::new_raw(trait_item_id, rcvr_args)) } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 76dad6b35714a..549f54d3c5496 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -913,7 +913,7 @@ fn visit_instance_use<'tcx>( // We explicitly skip this otherwise to ensure we get a linker error // if anyone tries to call this intrinsic and the codegen backend did not // override the implementation. - let instance = ty::Instance::new(instance.def_id(), instance.args); + let instance = ty::Instance::new_raw(instance.def_id(), instance.args); if tcx.should_codegen_locally(instance) { output.push(create_fn_mono_item(tcx, instance, source)); } @@ -1502,7 +1502,7 @@ impl<'v> RootCollector<'_, 'v> { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { - Instance::new(def_id, self.tcx.erase_regions(args)) + Instance::new_raw(def_id, self.tcx.erase_regions(args)) } _ => unreachable!(), }; diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index 64763b71d303d..40e6d21c06378 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -22,7 +22,7 @@ impl<'tcx> BodyBuilder<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self { let instance = match instance.def { // To get the fallback body of an intrinsic, we need to convert it to an item. - ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args), + ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args), _ => instance, }; BodyBuilder { tcx, instance } diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index ddeeadff13d17..0c6d1495e39cf 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -56,7 +56,7 @@ impl SymbolNamesTest<'_> { // some subset. for attr in tcx.get_attrs(def_id, SYMBOL_NAME) { let def_id = def_id.to_def_id(); - let instance = Instance::new( + let instance = Instance::new_raw( def_id, tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)), ); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index da83566dad024..166e8f1934299 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -235,7 +235,7 @@ fn resolve_associated_item<'tcx>( tcx.ensure_ok().compare_impl_item(leaf_def_item)?; } - Some(ty::Instance::new(leaf_def.item.def_id, args)) + Some(ty::Instance::new_raw(leaf_def.item.def_id, args)) } traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => { let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args); @@ -280,7 +280,7 @@ fn resolve_associated_item<'tcx>( // Use the default `fn clone_from` from `trait Clone`. let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) { if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) { @@ -329,7 +329,7 @@ fn resolve_associated_item<'tcx>( // sync with the built-in trait implementations (since all of the // implementations return `FnOnce::Output`). if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } else { Some(Instance { def: ty::InstanceKind::ConstructCoroutineInClosureShim { @@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>( args, }) } else { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } } ty::Closure(closure_def_id, args) => { @@ -381,7 +381,7 @@ fn resolve_associated_item<'tcx>( let name = tcx.item_name(trait_item_id); assert_eq!(name, sym::transmute); let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 63859c0396e48..6d3e77b6b6e97 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -263,7 +263,7 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None, diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs index 2bd554beacf8c..948c290c0b4fb 100644 --- a/tests/ui/asm/naked-asm-mono-sym-fn.rs +++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs @@ -7,26 +7,26 @@ //@ only-x86_64 //@ build-pass -trait T { +trait Tr { extern "C" fn t(); } enum E {} -impl T for E { +impl Tr for E { extern "C" fn t() { println!("Const generic: {}", C); } } #[unsafe(naked)] -extern "C" fn foo() { +extern "C" fn foo() { core::arch::naked_asm!( "push rax", "call {fn}", "pop rax", "ret", - fn = sym ::t, + fn = sym ::t, ); } From 1c55d70eedf8113b599f8cef2c894dd236c13309 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 30 Apr 2025 14:55:23 +0000 Subject: [PATCH 3/3] Use Instance::new_raw less --- compiler/rustc_hir_analysis/src/lib.rs | 12 +++++-- .../rustc_middle/src/mir/interpret/queries.rs | 32 +++++++++++++++---- compiler/rustc_middle/src/query/mod.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 4 +-- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 91dde13be550e..417943a90fc63 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -101,7 +101,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::{ErrorGuaranteed, Span}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; use rustc_trait_selection::traits; pub use crate::collect::suggest_impl_trait; @@ -216,9 +216,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) { check::maybe_check_static_with_link_section(tcx, item_def_id); } DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { - let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty()); - let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); + let instance = ty::Instance::expect_resolve( + tcx, + typing_env, + item_def_id.into(), + ty::GenericArgs::empty(), + DUMMY_SP, + ); + let cid = GlobalId { instance, promoted: None }; tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); } _ => (), diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index c7159ed8167ae..bfc5ddc7bc79c 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,3 +1,5 @@ +use std::assert_matches::debug_assert_matches; + use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_session::lint; @@ -18,14 +20,18 @@ impl<'tcx> TyCtxt<'tcx> { /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> { + debug_assert_matches!( + self.def_kind(def_id), + DefKind::Const | DefKind::AnonConst | DefKind::InlineConst + ); // In some situations def_id will have generic parameters within scope, but they aren't allowed // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new_raw(def_id, args); - let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); + let instance = ty::Instance::expect_resolve(self, typing_env, def_id, args, DUMMY_SP); + let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id(typing_env, cid, DUMMY_SP) } @@ -34,14 +40,18 @@ impl<'tcx> TyCtxt<'tcx> { /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly_to_alloc(self, def_id: DefId) -> EvalToAllocationRawResult<'tcx> { + debug_assert_matches!( + self.def_kind(def_id), + DefKind::Const | DefKind::AnonConst | DefKind::InlineConst + ); // In some situations def_id will have generic parameters within scope, but they aren't allowed // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new_raw(def_id, args); - let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); + let instance = ty::Instance::expect_resolve(self, typing_env, def_id, args, DUMMY_SP); + let cid = GlobalId { instance, promoted: None }; let inputs = self.erase_regions(typing_env.as_query_input(cid)); self.eval_to_allocation_raw(inputs) } @@ -203,14 +213,24 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> { /// generic parameter is used within the constant `ErrorHandled::TooGeneric` will be returned. #[instrument(skip(self), level = "debug")] pub fn const_eval_poly(self, def_id: DefId) { + debug_assert_matches!( + self.tcx.def_kind(def_id), + DefKind::Const | DefKind::AnonConst | DefKind::InlineConst + ); // In some situations def_id will have generic parameters within scope, but they aren't allowed // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self.tcx, def_id); - let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args)); - let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id); + let instance = ty::Instance::expect_resolve( + self.tcx, + typing_env, + def_id, + self.tcx.erase_regions(args), + DUMMY_SP, + ); + let cid = GlobalId { instance, promoted: None }; // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.tcx.erase_regions(typing_env.as_query_input(cid)); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1e026fd751bf6..9c3653ec7f85f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2471,7 +2471,7 @@ rustc_queries! { query resolve_instance_raw( key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { - desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } + desc { |tcx| "resolving instance `{}`", tcx.def_path_str_with_args(key.value.0, key.value.1) } } query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 6d3e77b6b6e97..02c505b8f4677 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -263,12 +263,12 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::new_raw(def_id, args); + let typing_env = ty::TypingEnv::post_analysis(cx.tcx, def_id); + let instance = ty::Instance::expect_resolve(self.tcx,typing_env,def_id, args, DUMMY_SP); let cid = GlobalId { instance, promoted: None, }; - let typing_env = ty::TypingEnv::post_analysis(cx.tcx, def_id); let result = cx.tcx.const_eval_global_id_for_typeck(typing_env, cid, DUMMY_SP); Self::is_value_unfrozen_raw(cx, result, ty) }