about summary refs log tree commit diff
path: root/compiler/rustc_metadata
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-06-11 17:05:01 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-08-15 15:56:45 +0000
commit8baab4cdf77979aed3ed7a5617df651c3e933405 (patch)
tree2e9cebd3698e22b3a93a37ca2a2f2e648c33b5fb /compiler/rustc_metadata
parentc018ae5389c49cc4bcb8343d80dd8e7323325410 (diff)
downloadrust-8baab4cdf77979aed3ed7a5617df651c3e933405.tar.gz
rust-8baab4cdf77979aed3ed7a5617df651c3e933405.zip
Detect missing `derive` on unresolved attribute even when not imported
```
error: cannot find attribute `sede` in this scope
  --> $DIR/missing-derive-3.rs:20:7
   |
LL |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Deserialize` and `Serialize` accept the similarly named `serde` attribute
   |
LL |     #[serde(untagged)]
   |         +

error: cannot find attribute `serde` in this scope
  --> $DIR/missing-derive-3.rs:14:7
   |
LL |     #[serde(untagged)]
   |       ^^^^^
   |
note: `serde` is imported here, but it is a crate, not an attribute
  --> $DIR/missing-derive-3.rs:4:1
   |
LL | extern crate serde;
   | ^^^^^^^^^^^^^^^^^^^
help: `serde` is an attribute that can be used by the derive macros `Deserialize` and `Serialize`, you might be missing a `derive` attribute
   |
LL + #[derive(Deserialize, Serialize)]
LL | enum B {
   |
```
Diffstat (limited to 'compiler/rustc_metadata')
-rw-r--r--compiler/rustc_metadata/src/creader.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs16
2 files changed, 21 insertions, 0 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 6bfb3769f24..5d776ea581d 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -32,6 +32,7 @@ use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateS
 use rustc_session::lint::{self, BuiltinLintDiag};
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
+use rustc_span::def_id::DefId;
 use rustc_span::edition::Edition;
 use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
 use rustc_target::spec::{PanicStrategy, Target};
@@ -275,6 +276,10 @@ impl CStore {
             .filter_map(|(cnum, data)| data.as_deref().map(|data| (cnum, data)))
     }
 
+    pub fn all_proc_macro_def_ids(&self) -> impl Iterator<Item = DefId> {
+        self.iter_crate_data().flat_map(|(krate, data)| data.proc_macros_for_crate(krate, self))
+    }
+
     fn push_dependencies_in_postorder(&self, deps: &mut IndexSet<CrateNum>, cnum: CrateNum) {
         if !deps.contains(&cnum) {
             let data = self.get_crate_data(cnum);
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 548c56a97bc..110b26c62ef 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -2014,6 +2014,22 @@ impl CrateMetadata {
         self.root.is_proc_macro_crate()
     }
 
+    pub(crate) fn proc_macros_for_crate(
+        &self,
+        krate: CrateNum,
+        cstore: &CStore,
+    ) -> impl Iterator<Item = DefId> {
+        gen move {
+            for def_id in self.root.proc_macro_data.as_ref().into_iter().flat_map(move |data| {
+                data.macros
+                    .decode(CrateMetadataRef { cdata: self, cstore })
+                    .map(move |index| DefId { index, krate })
+            }) {
+                yield def_id;
+            }
+        }
+    }
+
     pub(crate) fn name(&self) -> Symbol {
         self.root.header.name
     }