|
| 1 | +//! Regression test for #128622. |
| 2 | +//! |
| 3 | +//! PR #128581 introduced an assertion that all builtin attributes are actually checked via |
| 4 | +//! `CheckAttrVisitor` and aren't accidentally usable on completely unrelated HIR nodes. |
| 5 | +//! Unfortunately, the check had correctness problems. |
| 6 | +//! |
| 7 | +//! The match on attribute path segments looked like |
| 8 | +//! |
| 9 | +//! ```rs,ignore |
| 10 | +//! [sym::should_panic] => /* check is implemented */ |
| 11 | +//! match BUILTIN_ATTRIBUTE_MAP.get(name) { |
| 12 | +//! // checked below |
| 13 | +//! Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {} |
| 14 | +//! Some(_) => { |
| 15 | +//! if !name.as_str().starts_with("rustc_") { |
| 16 | +//! span_bug!( |
| 17 | +//! attr.span, |
| 18 | +//! "builtin attribute {name:?} not handled by `CheckAttrVisitor`" |
| 19 | +//! ) |
| 20 | +//! } |
| 21 | +//! } |
| 22 | +//! None => (), |
| 23 | +//! } |
| 24 | +//! ``` |
| 25 | +//! |
| 26 | +//! However, it failed to account for edge cases such as an attribute whose: |
| 27 | +//! |
| 28 | +//! 1. path segments *starts* with a builtin attribute such as `should_panic` |
| 29 | +//! 2. which does not start with `rustc_`, and |
| 30 | +//! 3. is also an `AttributeType::Normal` attribute upon registration with the builtin attribute map |
| 31 | +//! |
| 32 | +//! These conditions when all satisfied cause the span bug to be issued for e.g. |
| 33 | +//! `#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's |
| 34 | +//! `[sym::should_panic, sym::skip]`). |
| 35 | +//! |
| 36 | +//! This test checks that the span bug is not fired for such cases. |
| 37 | +//! |
| 38 | +//! issue: rust-lang/rust#128622 |
| 39 | +
|
| 40 | +// Notably, `should_panic` is a `AttributeType::Normal` attribute that is checked separately. |
| 41 | + |
| 42 | +struct Foo { |
| 43 | + #[should_panic::skip] |
| 44 | + //~^ ERROR failed to resolve |
| 45 | + pub field: u8, |
| 46 | + |
| 47 | + #[should_panic::a::b::c] |
| 48 | + //~^ ERROR failed to resolve |
| 49 | + pub field2: u8, |
| 50 | +} |
| 51 | + |
| 52 | +fn foo() {} |
| 53 | + |
| 54 | +fn main() { |
| 55 | + #[deny::skip] |
| 56 | + //~^ ERROR failed to resolve |
| 57 | + foo(); |
| 58 | +} |
0 commit comments