about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-04-17 12:17:29 +0200
committerRalf Jung <post@ralfj.de>2024-04-17 12:59:55 +0200
commitd101971ab10ebc95ad0664b704b730ce792d8fc5 (patch)
treeb2353ad98bf448c90939f956c4e99484e0ef6669 /compiler/rustc_passes/src
parentb7581490aaf964d4a34121d75be0fc49a2445911 (diff)
downloadrust-d101971ab10ebc95ad0664b704b730ce792d8fc5.tar.gz
rust-d101971ab10ebc95ad0664b704b730ce792d8fc5.zip
weak lang items are not allowed to be #[track_caller]
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_passes/src/errors.rs10
2 files changed, 31 insertions, 2 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1254ae8cfc8..ca41c5165b2 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -11,9 +11,9 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::StashKey;
 use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan};
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
-use rustc_hir as hir;
 use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::{self as hir};
 use rustc_hir::{
     self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
 };
@@ -519,7 +519,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
                 false
             }
-            Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true,
+            Target::Fn => {
+                // `#[track_caller]` is not valid on weak lang items because they are called via
+                // `extern` declarations and `#[track_caller]` would alter their ABI.
+                if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
+                    && let Some(item) = hir::LangItem::from_name(lang_item)
+                    && item.is_weak()
+                {
+                    let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
+
+                    self.dcx().emit_err(errors::LangItemWithTrackCaller {
+                        attr_span,
+                        name: lang_item,
+                        sig_span: sig.span,
+                    });
+                    false
+                } else {
+                    true
+                }
+            }
+            Target::Method(..) | Target::ForeignFn | Target::Closure => true,
             // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
             // `#[track_caller]` attribute with just a lint, because we previously
             // erroneously allowed it and some crates used it accidentally, to be compatible
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 3f26ea4507d..19b5e5495d6 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -820,6 +820,16 @@ pub struct MissingLangItem {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_lang_item_fn_with_track_caller)]
+pub struct LangItemWithTrackCaller {
+    #[primary_span]
+    pub attr_span: Span,
+    pub name: Symbol,
+    #[label]
+    pub sig_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_lang_item_fn_with_target_feature)]
 pub struct LangItemWithTargetFeature {
     #[primary_span]