about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Brouwer <jonathantbrouwer@gmail.com>2025-07-11 17:02:24 +0200
committerJonathan Brouwer <jonathantbrouwer@gmail.com>2025-07-11 17:02:57 +0200
commit2f05fa6fffb857c08edd0af2dc69f05fa1f02703 (patch)
treef93c4fc162c14431c34c4963611bf1595a25b991
parent855e0fe46e68d94e9f6147531b75ac2d488c548e (diff)
downloadrust-2f05fa6fffb857c08edd0af2dc69f05fa1f02703.tar.gz
rust-2f05fa6fffb857c08edd0af2dc69f05fa1f02703.zip
Fix ICE for parsed attributes with longer path not handled by CheckAttrVisitor
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs5
-rw-r--r--compiler/rustc_passes/Cargo.toml1
-rw-r--r--compiler/rustc_passes/src/check_attr.rs11
-rw-r--r--tests/ui/attributes/builtin-attribute-prefix.rs8
-rw-r--r--tests/ui/attributes/builtin-attribute-prefix.stderr15
6 files changed, 40 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 271a2f7962c..98a78b8495b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4349,6 +4349,7 @@ dependencies = [
  "rustc_ast_lowering",
  "rustc_ast_pretty",
  "rustc_attr_data_structures",
+ "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_expand",
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index dbe1a5b2ad0..737fe6ba081 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -718,6 +718,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
         attributes
     }
 
+    /// Returns whether there is a parser for an attribute with this name
+    pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
+        Late::parsers().0.contains_key(path)
+    }
+
     fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {
         match args {
             ast::AttrArgs::Empty => AttrArgs::Empty,
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
index b9167489076..503fc98da76 100644
--- a/compiler/rustc_passes/Cargo.toml
+++ b/compiler/rustc_passes/Cargo.toml
@@ -10,6 +10,7 @@ rustc_ast = { path = "../rustc_ast" }
 rustc_ast_lowering = { path = "../rustc_ast_lowering" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
+rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_expand = { path = "../rustc_expand" }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 0aa6a2b41cf..3a22b19683c 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -7,10 +7,12 @@
 
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
+use std::slice;
 
 use rustc_abi::{Align, ExternAbi, Size};
 use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, ast};
 use rustc_attr_data_structures::{AttributeKind, InlineAttr, ReprAttr, find_attr};
+use rustc_attr_parsing::{AttributeParser, Late};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
 use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
@@ -373,11 +375,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::custom_mir,
                             ..
                         ] => {}
-                        [name, ..] => {
+                        [name, rest@..] => {
                             match BUILTIN_ATTRIBUTE_MAP.get(name) {
                                 // checked below
                                 Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
                                 Some(_) => {
+                                    if rest.len() > 0 && AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(name)) {
+                                        // Check if we tried to use a builtin attribute as an attribute namespace, like `#[must_use::skip]`.
+                                        // This check is here to solve https://github.com/rust-lang/rust/issues/137590
+                                        // An error is already produced for this case elsewhere
+                                        continue
+                                    }
+
                                     // FIXME: differentiate between unstable and internal attributes just
                                     // like we do with features instead of just accepting `rustc_`
                                     // attributes by name. That should allow trimming the above list, too.
diff --git a/tests/ui/attributes/builtin-attribute-prefix.rs b/tests/ui/attributes/builtin-attribute-prefix.rs
new file mode 100644
index 00000000000..d184c6d008d
--- /dev/null
+++ b/tests/ui/attributes/builtin-attribute-prefix.rs
@@ -0,0 +1,8 @@
+// Regression test for https://github.com/rust-lang/rust/issues/143789
+#[must_use::skip]
+//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `must_use`
+fn main() { }
+
+// Regression test for https://github.com/rust-lang/rust/issues/137590
+struct S(#[stable::skip] u8, u16, u32);
+//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `stable`
diff --git a/tests/ui/attributes/builtin-attribute-prefix.stderr b/tests/ui/attributes/builtin-attribute-prefix.stderr
new file mode 100644
index 00000000000..a16080c003f
--- /dev/null
+++ b/tests/ui/attributes/builtin-attribute-prefix.stderr
@@ -0,0 +1,15 @@
+error[E0433]: failed to resolve: use of unresolved module or unlinked crate `stable`
+  --> $DIR/builtin-attribute-prefix.rs:7:12
+   |
+LL | struct S(#[stable::skip] u8, u16, u32);
+   |            ^^^^^^ use of unresolved module or unlinked crate `stable`
+
+error[E0433]: failed to resolve: use of unresolved module or unlinked crate `must_use`
+  --> $DIR/builtin-attribute-prefix.rs:2:3
+   |
+LL | #[must_use::skip]
+   |   ^^^^^^^^ use of unresolved module or unlinked crate `must_use`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.