about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/naked_asm.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs2
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs6
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs18
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/test.rs2
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--tests/ui/asm/global-asm-mono-sym-fn.rs27
-rw-r--r--tests/ui/asm/naked-asm-mono-sym-fn.rs35
21 files changed, 109 insertions, 31 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index d3f47ad7263..e866b896255 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 d22f4229e23..2ed5ec4381e 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 68f60f169b5..fe3a7a1580b 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 ffeab59b05c..bfaad8f2f1e 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 1bfdbc0b620..5f0a0cf922a 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -612,7 +612,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,
             )
         }
@@ -660,7 +660,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_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 89439e40937..775ab9071e7 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -457,7 +457,13 @@ where
                 rustc_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/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
index 0301ef437c0..d2a687359e0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
@@ -95,7 +95,9 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
             );
 
             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_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 309b8f2c761..91dde13be55 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 0494c78a7a9..d0668794198 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<hir::OwnerId> {
         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 3c62017072e..1d67d0fe3bb 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 e5d1dda3aa0..4a5c42c721c 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));
@@ -209,7 +209,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 6b413a7383a..7243f87ee63 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 6af9d4aae30..4981233cebe 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2481,7 +2481,7 @@ rustc_queries! {
     query resolve_instance_raw(
         key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
     ) -> Result<Option<ty::Instance<'tcx>>, 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 d660e7d0d60..0d99a1b5149 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 1e3744e19f5..c6a81e60b2b 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -931,7 +931,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));
             }
@@ -1520,7 +1520,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 64763b71d30..40e6d21c063 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 ddeeadff13d..0c6d1495e39 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 da83566dad0..166e8f19342 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 63859c0396e..6d3e77b6b6e 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/global-asm-mono-sym-fn.rs b/tests/ui/asm/global-asm-mono-sym-fn.rs
new file mode 100644
index 00000000000..e584a98badb
--- /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 <i32 as Foo>::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 00000000000..948c290c0b4
--- /dev/null
+++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs
@@ -0,0 +1,35 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/140373>.
+// 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 Tr {
+    extern "C" fn t();
+}
+
+enum E<const C: usize> {}
+
+impl<const C: usize> Tr for E<C> {
+    extern "C" fn t() {
+        println!("Const generic: {}", C);
+    }
+}
+
+#[unsafe(naked)]
+extern "C" fn foo<U: Tr>() {
+    core::arch::naked_asm!(
+        "push rax",
+        "call {fn}",
+        "pop rax",
+        "ret",
+        fn = sym <U as Tr>::t,
+    );
+}
+
+fn main() {
+    foo::<E<42>>();
+}