Skip to content

Commit 6a9456f

Browse files
committed
Supress unhelpful diagnostics for unresolved top level attributes
1 parent df0295f commit 6a9456f

29 files changed

+139
-233
lines changed

compiler/rustc_passes/src/check_attr.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -2495,12 +2495,8 @@ fn is_c_like_enum(item: &Item<'_>) -> bool {
24952495
}
24962496
}
24972497

2498-
// FIXME: Fix "Cannot determine resolution" error and remove built-in macros
2499-
// from this check.
2498+
// builtin macros will be checked in resolve
25002499
fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
2501-
// Check for builtin attributes at the crate level
2502-
// which were unsuccessfully resolved due to cannot determine
2503-
// resolution for the attribute macro error.
25042500
const ATTRS_TO_CHECK: &[Symbol] = &[
25052501
sym::macro_export,
25062502
sym::repr,
@@ -2509,11 +2505,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
25092505
sym::start,
25102506
sym::rustc_main,
25112507
sym::unix_sigpipe,
2512-
sym::derive,
2513-
sym::test,
2514-
sym::test_case,
2515-
sym::global_allocator,
2516-
sym::bench,
25172508
];
25182509

25192510
for attr in attrs {

compiler/rustc_resolve/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ resolve_invalid_asm_sym =
151151
.label = is a local variable
152152
.help = `sym` operands must refer to either a function or a static
153153
154+
resolve_invalid_attr_at_crate_level =
155+
`{$name}` attribute cannot be used at crate level
156+
.suggestion = perhaps you meant to use an outer attribute
157+
154158
resolve_is_not_directly_importable =
155159
`{$target}` is not directly importable
156160
.label = cannot be imported directly

compiler/rustc_resolve/src/errors.rs

+23
Original file line numberDiff line numberDiff line change
@@ -771,3 +771,26 @@ pub(crate) struct IsNotDirectlyImportable {
771771
pub(crate) span: Span,
772772
pub(crate) target: Ident,
773773
}
774+
775+
#[derive(Diagnostic)]
776+
#[diag(resolve_invalid_attr_at_crate_level)]
777+
pub struct InvalidAttrAtCrateLevel {
778+
#[primary_span]
779+
pub(crate) span: Span,
780+
pub(crate) name: Symbol,
781+
#[subdiagnostic]
782+
pub(crate) sugg: InvalidAttrSugg,
783+
}
784+
785+
#[derive(Subdiagnostic)]
786+
#[suggestion(
787+
resolve_suggestion,
788+
code = "",
789+
applicability = "machine-applicable",
790+
style = "verbose"
791+
)]
792+
pub(crate) struct InvalidAttrSugg {
793+
#[primary_span]
794+
pub(crate) span: Span,
795+
pub(crate) name: Symbol,
796+
}

compiler/rustc_resolve/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15841584
self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
15851585
}
15861586

1587+
fn is_builtin(&mut self, res: Res) -> bool {
1588+
if self.is_builtin_macro(res) {
1589+
return true;
1590+
}
1591+
self.builtin_attrs_bindings.values().any(|b| b.res() == res)
1592+
}
1593+
15871594
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
15881595
loop {
15891596
match ctxt.outer_expn_data().macro_def_id {

compiler/rustc_resolve/src/macros.rs

+51-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! A bunch of methods and structures more or less related to resolving macros and
22
//! interface provided by `Resolver` to macro expander.
33
4+
use crate::ast::AttrStyle;
5+
use crate::ast::Attribute;
46
use crate::errors::{
57
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
68
MacroExpectedFound, RemoveSurroundingDerive,
@@ -35,6 +37,7 @@ use rustc_span::edition::Edition;
3537
use rustc_span::hygiene::{self, ExpnData, ExpnKind, LocalExpnId};
3638
use rustc_span::hygiene::{AstPass, MacroKind};
3739
use rustc_span::symbol::{kw, sym, Ident, Symbol};
40+
use rustc_span::BytePos;
3841
use rustc_span::{Span, DUMMY_SP};
3942
use std::cell::Cell;
4043
use std::mem;
@@ -698,6 +701,35 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
698701
res.map(|res| (self.get_macro(res).map(|macro_data| macro_data.ext.clone()), res))
699702
}
700703

704+
fn report_invalid_crate_level_attr(&mut self, attrs: &[Attribute], name: Symbol) -> bool {
705+
for attr in attrs.iter().filter(|attr| attr.style == AttrStyle::Inner) {
706+
if attr.has_name(name) {
707+
let tcx = self.tcx;
708+
tcx.sess.emit_err(errors::InvalidAttrAtCrateLevel {
709+
name,
710+
span: attr.span,
711+
sugg: errors::InvalidAttrSugg {
712+
span: tcx
713+
.sess
714+
.source_map()
715+
.span_to_snippet(attr.span)
716+
.ok()
717+
.filter(|src| src.starts_with("#!["))
718+
.map(|_| {
719+
attr.span
720+
.with_lo(attr.span.lo() + BytePos(1))
721+
.with_hi(attr.span.lo() + BytePos(2))
722+
})
723+
.unwrap(),
724+
name,
725+
},
726+
});
727+
return true;
728+
}
729+
}
730+
false
731+
}
732+
701733
pub(crate) fn finalize_macro_resolutions(&mut self, krate: &Crate) {
702734
let check_consistency = |this: &mut Self,
703735
path: &[Segment],
@@ -717,15 +749,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
717749
// expanded into a dummy fragment for recovery during expansion.
718750
// Now, post-expansion, the resolution may succeed, but we can't change the
719751
// past and need to report an error.
720-
// However, non-speculative `resolve_path` can successfully return private items
752+
// Special cases:
753+
// 1. non-speculative `resolve_path` can successfully return private items
721754
// even if speculative `resolve_path` returned nothing previously, so we skip this
722755
// less informative error if the privacy error is reported elsewhere.
756+
// 2. issue #118455, unresolved top level attribute error didn't imported prelude and
757+
// already have emitted an error, report builtin macro and attributes error by the way,
758+
// so `check_invalid_crate_level_attr` in can ignore them.
759+
760+
let is_builtin = res.opt_def_id().map_or(false, |_| this.is_builtin(res));
723761
if this.privacy_errors.is_empty() {
724-
this.tcx.sess.emit_err(CannotDetermineMacroResolution {
725-
span,
726-
kind: kind.descr(),
727-
path: Segment::names_to_string(path),
728-
});
762+
let mut fallback = !is_builtin;
763+
if is_builtin && krate.id == ast::CRATE_NODE_ID {
764+
fallback =
765+
!this.report_invalid_crate_level_attr(&krate.attrs, path[0].ident.name);
766+
}
767+
if fallback && this.tcx.sess.has_errors().is_none() {
768+
this.tcx.sess.emit_err(CannotDetermineMacroResolution {
769+
span,
770+
kind: kind.descr(),
771+
path: Segment::names_to_string(path),
772+
});
773+
}
729774
}
730775
}
731776
};

tests/ui/derives/issue-36617.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
#![derive(Copy)] //~ ERROR cannot determine resolution for the attribute macro `derive`
1+
#![derive(Copy)]
22
//~^ ERROR `derive` attribute cannot be used at crate level
33

4-
#![test]//~ ERROR cannot determine resolution for the attribute macro `test`
4+
#![test]
55
//~^ ERROR `test` attribute cannot be used at crate level
66

7-
#![test_case]//~ ERROR cannot determine resolution for the attribute macro `test_case`
7+
#![test_case]
88
//~^ ERROR `test_case` attribute cannot be used at crate level
99

10-
#![bench]//~ ERROR cannot determine resolution for the attribute macro `bench`
10+
#![bench]
1111
//~^ ERROR `bench` attribute cannot be used at crate level
1212

13-
#![global_allocator]//~ ERROR cannot determine resolution for the attribute macro `global_allocator`
13+
#![global_allocator]
1414
//~^ ERROR `global_allocator` attribute cannot be used at crate level
1515

1616
fn main() {}

tests/ui/derives/issue-36617.stderr

+1-56
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,8 @@
1-
error: cannot determine resolution for the attribute macro `derive`
2-
--> $DIR/issue-36617.rs:1:4
3-
|
4-
LL | #![derive(Copy)]
5-
| ^^^^^^
6-
|
7-
= note: import resolution is stuck, try simplifying macro imports
8-
9-
error: cannot determine resolution for the attribute macro `test`
10-
--> $DIR/issue-36617.rs:4:4
11-
|
12-
LL | #![test]
13-
| ^^^^
14-
|
15-
= note: import resolution is stuck, try simplifying macro imports
16-
17-
error: cannot determine resolution for the attribute macro `test_case`
18-
--> $DIR/issue-36617.rs:7:4
19-
|
20-
LL | #![test_case]
21-
| ^^^^^^^^^
22-
|
23-
= note: import resolution is stuck, try simplifying macro imports
24-
25-
error: cannot determine resolution for the attribute macro `bench`
26-
--> $DIR/issue-36617.rs:10:4
27-
|
28-
LL | #![bench]
29-
| ^^^^^
30-
|
31-
= note: import resolution is stuck, try simplifying macro imports
32-
33-
error: cannot determine resolution for the attribute macro `global_allocator`
34-
--> $DIR/issue-36617.rs:13:4
35-
|
36-
LL | #![global_allocator]
37-
| ^^^^^^^^^^^^^^^^
38-
|
39-
= note: import resolution is stuck, try simplifying macro imports
40-
411
error: `derive` attribute cannot be used at crate level
422
--> $DIR/issue-36617.rs:1:1
433
|
444
LL | #![derive(Copy)]
455
| ^^^^^^^^^^^^^^^^
46-
...
47-
LL | fn main() {}
48-
| ---- the inner attribute doesn't annotate this function
496
|
507
help: perhaps you meant to use an outer attribute
518
|
@@ -58,9 +15,6 @@ error: `test` attribute cannot be used at crate level
5815
|
5916
LL | #![test]
6017
| ^^^^^^^^
61-
...
62-
LL | fn main() {}
63-
| ---- the inner attribute doesn't annotate this function
6418
|
6519
help: perhaps you meant to use an outer attribute
6620
|
@@ -73,9 +27,6 @@ error: `test_case` attribute cannot be used at crate level
7327
|
7428
LL | #![test_case]
7529
| ^^^^^^^^^^^^^
76-
...
77-
LL | fn main() {}
78-
| ---- the inner attribute doesn't annotate this function
7930
|
8031
help: perhaps you meant to use an outer attribute
8132
|
@@ -88,9 +39,6 @@ error: `bench` attribute cannot be used at crate level
8839
|
8940
LL | #![bench]
9041
| ^^^^^^^^^
91-
...
92-
LL | fn main() {}
93-
| ---- the inner attribute doesn't annotate this function
9442
|
9543
help: perhaps you meant to use an outer attribute
9644
|
@@ -103,15 +51,12 @@ error: `global_allocator` attribute cannot be used at crate level
10351
|
10452
LL | #![global_allocator]
10553
| ^^^^^^^^^^^^^^^^^^^^
106-
...
107-
LL | fn main() {}
108-
| ---- the inner attribute doesn't annotate this function
10954
|
11055
help: perhaps you meant to use an outer attribute
11156
|
11257
LL - #![global_allocator]
11358
LL + #[global_allocator]
11459
|
11560

116-
error: aborting due to 10 previous errors
61+
error: aborting due to 5 previous errors
11762

tests/ui/extenv/issue-55897.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ mod unresolved_env {
44
use env; //~ ERROR unresolved import `env`
55

66
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
7-
//~^ ERROR cannot determine resolution for the macro `env`
87
}
98

109
mod nonexistent_env {

tests/ui/extenv/issue-55897.stderr

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: environment variable `NON_EXISTENT` not defined at compile time
2-
--> $DIR/issue-55897.rs:11:22
2+
--> $DIR/issue-55897.rs:10:22
33
|
44
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
55
| ^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
88
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
99

1010
error: suffixes on string literals are invalid
11-
--> $DIR/issue-55897.rs:16:22
11+
--> $DIR/issue-55897.rs:15:22
1212
|
1313
LL | include!(concat!("NON_EXISTENT"suffix, "/data.rs"));
1414
| ^^^^^^^^^^^^^^^^^^^^ invalid suffix `suffix`
@@ -33,14 +33,6 @@ help: consider importing this module instead
3333
LL | use std::env;
3434
| ~~~~~~~~
3535

36-
error: cannot determine resolution for the macro `env`
37-
--> $DIR/issue-55897.rs:6:22
38-
|
39-
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
40-
| ^^^
41-
|
42-
= note: import resolution is stuck, try simplifying macro imports
43-
44-
error: aborting due to 5 previous errors
36+
error: aborting due to 4 previous errors
4537

4638
For more information about this error, try `rustc --explain E0432`.

tests/ui/feature-gates/issue-43106-gating-of-bench.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// handled in "weird places" when `--test` is passed.
44

55
#![feature(custom_inner_attributes)]
6-
7-
#![bench = "4100"]
8-
//~^ ERROR cannot determine resolution for the attribute macro `bench`
9-
//~^^ ERROR `bench` attribute cannot be used at crate level
6+
#![bench = "4100"]
7+
//~^ ERROR `bench` attribute cannot be used at crate level
108
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
1-
error: cannot determine resolution for the attribute macro `bench`
2-
--> $DIR/issue-43106-gating-of-bench.rs:7:4
3-
|
4-
LL | #![bench = "4100"]
5-
| ^^^^^
6-
|
7-
= note: import resolution is stuck, try simplifying macro imports
8-
91
error: `bench` attribute cannot be used at crate level
10-
--> $DIR/issue-43106-gating-of-bench.rs:7:1
2+
--> $DIR/issue-43106-gating-of-bench.rs:6:1
113
|
12-
LL | #![bench = "4100"]
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14-
...
15-
LL | fn main() {}
16-
| ---- the inner attribute doesn't annotate this function
4+
LL | #![bench = "4100"]
5+
| ^^^^^^^^^^^^^^^^^^
176
|
187
help: perhaps you meant to use an outer attribute
198
|
20-
LL - #![bench = "4100"]
21-
LL + #[bench = "4100"]
9+
LL - #![bench = "4100"]
10+
LL + #[bench = "4100"]
2211
|
2312

24-
error: aborting due to 2 previous errors
13+
error: aborting due to 1 previous error
2514

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs.
22

33
#![allow(soft_unstable)]
4-
#![test = "4200"]
5-
//~^ ERROR cannot determine resolution for the attribute macro `test`
6-
//~^^ ERROR `test` attribute cannot be used at crate level
4+
#![test = "4200"]
5+
//~^ ERROR `test` attribute cannot be used at crate level
76
fn main() {}

0 commit comments

Comments
 (0)