Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE: builtin attribute "should_panic" not handled by CheckAttrVisitor #128622

Closed
matthiaskrgr opened this issue Aug 4, 2024 · 7 comments · Fixed by #128623
Closed

ICE: builtin attribute "should_panic" not handled by CheckAttrVisitor #128622

matthiaskrgr opened this issue Aug 4, 2024 · 7 comments · Fixed by #128623
Assignees
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@matthiaskrgr
Copy link
Member

auto-reduced (treereduce-rust):

struct S {
    #[should_panic::skip]
    field: u8,
}

original:

// Non-builtin attributes do not mess with field visibility resolution (issue #67006).

mod internal {
    struct S {
        #[rustfmt::skip]
        pub(in crate::internal) field: u32 // OK
    }

    struct Z(
        #[rustfmt::skip]
        pub(in crate::internal) u8 // OK
    );
}

struct S {
    #[should_panic::skip]
    pub(in nonexistent) field: u8 //~ ERROR failed to resolve
}

struct TokenStream(
    #[rustfmt::skip]
    pub(in nonexistent) u8 //~ ERROR failed to resolve
);

fn main() {}

Version information

rustc 1.82.0-nightly (64ebd39da 2024-08-03)
binary: rustc
commit-hash: 64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b
commit-date: 2024-08-03
host: x86_64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0

Command:
/home/matthias/.rustup/toolchains/master/bin/rustc

Program output

error[E0433]: failed to resolve: use of undeclared crate or module `should_panic`
 --> /tmp/icemaker_global_tempdir.YjHCgx05egvK/rustc_testrunner_tmpdir_reporting.sPNqKpdsgpau/mvce.rs:2:7
  |
2 |     #[should_panic::skip]
  |       ^^^^^^^^^^^^ use of undeclared crate or module `should_panic`

error[E0601]: `main` function not found in crate `mvce`
 --> /tmp/icemaker_global_tempdir.YjHCgx05egvK/rustc_testrunner_tmpdir_reporting.sPNqKpdsgpau/mvce.rs:4:2
  |
4 | }
  |  ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.YjHCgx05egvK/rustc_testrunner_tmpdir_reporting.sPNqKpdsgpau/mvce.rs`

error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute "should_panic" not handled by `CheckAttrVisitor`
 --> /tmp/icemaker_global_tempdir.YjHCgx05egvK/rustc_testrunner_tmpdir_reporting.sPNqKpdsgpau/mvce.rs:2:5
  |
2 |     #[should_panic::skip]
  |     ^^^^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at compiler/rustc_passes/src/check_attr.rs:285:33:
Box<dyn Any>
stack backtrace:
   0:     0x73cd3257515d - std::backtrace_rs::backtrace::libunwind::trace::h470c7ae87ba4025c
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:     0x73cd3257515d - std::backtrace_rs::backtrace::trace_unsynchronized::h59a012957645db86
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x73cd3257515d - std::sys::backtrace::_print_fmt::he6eec48dee0520cd
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/sys/backtrace.rs:66:9
   3:     0x73cd3257515d - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::hfdd25df09ce1fcfa
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/sys/backtrace.rs:39:26
   4:     0x73cd325c569b - core::fmt::rt::Argument::fmt::hb463cdd1073c5435
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/core/src/fmt/rt.rs:173:76
   5:     0x73cd325c569b - core::fmt::write::hd7c3b9720108f6ed
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/core/src/fmt/mod.rs:1178:21
   6:     0x73cd32568ec3 - std::io::Write::write_fmt::ha2df104fcce421c5
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/io/mod.rs:1823:15
   7:     0x73cd32577952 - std::sys::backtrace::BacktraceLock::print::hf06cfc93c67871f0
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/sys/backtrace.rs:42:9
   8:     0x73cd32577952 - std::panicking::default_hook::{{closure}}::hbb4ed713e2c9c643
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/panicking.rs:266:22
   9:     0x73cd325775be - std::panicking::default_hook::h7690590dddb77129
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/panicking.rs:293:9
  10:     0x73cd2eaa6d47 - std[5d818de65be8229c]::panicking::update_hook::<alloc[9a5ee3285ce50e9f]::boxed::Box<rustc_driver_impl[a2f6f36da10355a2]::install_ice_hook::{closure#0}>>::{closure#0}
  11:     0x73cd32578342 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h79d7cc46a296b25c
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/alloc/src/boxed.rs:2164:9
  12:     0x73cd32578342 - std::panicking::rust_panic_with_hook::hbd0f660a3f2612ad
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/panicking.rs:805:13
  13:     0x73cd2eae2211 - std[5d818de65be8229c]::panicking::begin_panic::<rustc_errors[30d9fa35dd7a2581]::ExplicitBug>::{closure#0}
  14:     0x73cd2ead4f26 - std[5d818de65be8229c]::sys::backtrace::__rust_end_short_backtrace::<std[5d818de65be8229c]::panicking::begin_panic<rustc_errors[30d9fa35dd7a2581]::ExplicitBug>::{closure#0}, !>
  15:     0x73cd2ead0006 - std[5d818de65be8229c]::panicking::begin_panic::<rustc_errors[30d9fa35dd7a2581]::ExplicitBug>
  16:     0x73cd2eaeb481 - <rustc_errors[30d9fa35dd7a2581]::diagnostic::BugAbort as rustc_errors[30d9fa35dd7a2581]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
  17:     0x73cd2f335e7d - <rustc_errors[30d9fa35dd7a2581]::DiagCtxtHandle>::span_bug::<rustc_span[e78ddc703a44fb87]::span_encoding::Span, alloc[9a5ee3285ce50e9f]::string::String>
  18:     0x73cd2f352818 - rustc_middle[60b1eb66b763f760]::util::bug::opt_span_bug_fmt::<rustc_span[e78ddc703a44fb87]::span_encoding::Span>::{closure#0}
  19:     0x73cd2f35284a - rustc_middle[60b1eb66b763f760]::ty::context::tls::with_opt::<rustc_middle[60b1eb66b763f760]::util::bug::opt_span_bug_fmt<rustc_span[e78ddc703a44fb87]::span_encoding::Span>::{closure#0}, !>::{closure#0}
  20:     0x73cd2f34598b - rustc_middle[60b1eb66b763f760]::ty::context::tls::with_context_opt::<rustc_middle[60b1eb66b763f760]::ty::context::tls::with_opt<rustc_middle[60b1eb66b763f760]::util::bug::opt_span_bug_fmt<rustc_span[e78ddc703a44fb87]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
  21:     0x73cd2f343b37 - rustc_middle[60b1eb66b763f760]::util::bug::span_bug_fmt::<rustc_span[e78ddc703a44fb87]::span_encoding::Span>
  22:     0x73cd302219d7 - <rustc_passes[82698ad2f6a923fe]::check_attr::CheckAttrVisitor>::check_attributes
  23:     0x73cd3021d944 - <rustc_passes[82698ad2f6a923fe]::check_attr::CheckAttrVisitor as rustc_hir[ea3fcf664761130]::intravisit::Visitor>::visit_item
  24:     0x73cd3021cdc0 - rustc_passes[82698ad2f6a923fe]::check_attr::check_mod_attrs
  25:     0x73cd3021cd3b - rustc_query_impl[952a2029dfc6d38d]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[952a2029dfc6d38d]::query_impl::check_mod_attrs::dynamic_query::{closure#2}::{closure#0}, rustc_middle[60b1eb66b763f760]::query::erase::Erased<[u8; 0usize]>>
  26:     0x73cd30c13176 - rustc_query_system[def1941f6afd59f1]::query::plumbing::try_execute_query::<rustc_query_impl[952a2029dfc6d38d]::DynamicConfig<rustc_query_system[def1941f6afd59f1]::query::caches::DefaultCache<rustc_span[e78ddc703a44fb87]::def_id::LocalModDefId, rustc_middle[60b1eb66b763f760]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[952a2029dfc6d38d]::plumbing::QueryCtxt, false>
  27:     0x73cd30c12e99 - rustc_query_impl[952a2029dfc6d38d]::query_impl::check_mod_attrs::get_query_non_incr::__rust_end_short_backtrace
  28:     0x73cd30c12931 - <rustc_middle[60b1eb66b763f760]::hir::map::Map>::par_for_each_module::<rustc_interface[a7671a33eb98c4b3]::passes::run_required_analyses::{closure#0}::{closure#0}::{closure#1}::{closure#0}>::{closure#0}
  29:     0x73cd3059aefc - rustc_interface[a7671a33eb98c4b3]::passes::analysis
  30:     0x73cd3059abdb - rustc_query_impl[952a2029dfc6d38d]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[952a2029dfc6d38d]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[60b1eb66b763f760]::query::erase::Erased<[u8; 1usize]>>
  31:     0x73cd30f7ac6e - rustc_query_system[def1941f6afd59f1]::query::plumbing::try_execute_query::<rustc_query_impl[952a2029dfc6d38d]::DynamicConfig<rustc_query_system[def1941f6afd59f1]::query::caches::SingleCache<rustc_middle[60b1eb66b763f760]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[952a2029dfc6d38d]::plumbing::QueryCtxt, false>
  32:     0x73cd30f7a9cf - rustc_query_impl[952a2029dfc6d38d]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace
  33:     0x73cd30e89be3 - rustc_interface[a7671a33eb98c4b3]::interface::run_compiler::<core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>, rustc_driver_impl[a2f6f36da10355a2]::run_compiler::{closure#0}>::{closure#1}
  34:     0x73cd30e27889 - std[5d818de65be8229c]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[a7671a33eb98c4b3]::util::run_in_thread_with_globals<rustc_interface[a7671a33eb98c4b3]::util::run_in_thread_pool_with_globals<rustc_interface[a7671a33eb98c4b3]::interface::run_compiler<core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>, rustc_driver_impl[a2f6f36da10355a2]::run_compiler::{closure#0}>::{closure#1}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>::{closure#0}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>
  35:     0x73cd30e27632 - <<std[5d818de65be8229c]::thread::Builder>::spawn_unchecked_<rustc_interface[a7671a33eb98c4b3]::util::run_in_thread_with_globals<rustc_interface[a7671a33eb98c4b3]::util::run_in_thread_pool_with_globals<rustc_interface[a7671a33eb98c4b3]::interface::run_compiler<core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>, rustc_driver_impl[a2f6f36da10355a2]::run_compiler::{closure#0}>::{closure#1}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>::{closure#0}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dc2153a232c405cb]::result::Result<(), rustc_span[e78ddc703a44fb87]::ErrorGuaranteed>>::{closure#1} as core[dc2153a232c405cb]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  36:     0x73cd3258205b - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h4329d9c9b4cecba8
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/alloc/src/boxed.rs:2150:9
  37:     0x73cd3258205b - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h2a2d295295b3a578
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/alloc/src/boxed.rs:2150:9
  38:     0x73cd3258205b - std::sys::pal::unix::thread::Thread::new::thread_start::hc3031069669580a0
                               at /rustc/64ebd39da5ec28caa3bd7cbb3f22f5949432fe2b/library/std/src/sys/pal/unix/thread.rs:105:17
  39:     0x73cd2b4a6ded - <unknown>
  40:     0x73cd2b52a0dc - <unknown>
  41:                0x0 - <unknown>

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: rustc 1.82.0-nightly (64ebd39da 2024-08-03) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [check_mod_attrs] checking attributes in top-level module
#1 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0433, E0601.
For more information about an error, try `rustc --explain E0433`.

@matthiaskrgr matthiaskrgr added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Aug 4, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 4, 2024
@matthiaskrgr
Copy link
Member Author

fn main() {
    #[deny::skip]
    foo();
}

@matthiaskrgr
Copy link
Member Author

there are a bunch more which probably all follow the #[$attr::skip] pattern...

  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"allow\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"cfg_attr\" not handled by `CheckAttrVisitor`",
  4   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"cfg\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"cmse_nonsecure_entry\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"collapse_debuginfo\" not handled by `CheckAttrVisitor`",
  6   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"deny\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"doc\" not handled by `CheckAttrVisitor`",
  4   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"inline\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"macro_export\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"optimize\" not handled by `CheckAttrVisitor`",
  4   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"proc_macro_derive\" not handled by `CheckAttrVisitor`",
 14   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"proc_macro\" not handled by `CheckAttrVisitor`",
  2   "error_reason": "error: internal compiler error: compiler/rustc_passes/src/check_attr.rs:285:33: builtin attribute \"should_panic\" not handled by `CheckAttrVisitor`",

@matthiaskrgr
Copy link
Member Author

#128581 cc @jieyouxu

@jieyouxu
Copy link
Member

jieyouxu commented Aug 4, 2024

Taking a look

@jieyouxu jieyouxu self-assigned this Aug 4, 2024
@jieyouxu
Copy link
Member

jieyouxu commented Aug 4, 2024

there are a bunch more which probably all follow the #[$attr::skip] pattern...

Problem is the previous match

[sym::ignore] | [sym::should_panic] => {
    self.check_generic_attr(hir_id, attr, target, Target::Fn)
}

falls through to the [name, ..] fallback case for [sym::should_panic] etc. because it has >1 segments

match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        // 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.
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}

... and then since should_panic et al. is a AttributeType::Normal attribute, it triggers the ICE.

@jieyouxu
Copy link
Member

jieyouxu commented Aug 4, 2024

I have a candidate fix locally, doing some more testing

@jieyouxu jieyouxu added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 4, 2024
rust-cloud-vms bot pushed a commit to jieyouxu/rust that referenced this issue Aug 4, 2024
rust-cloud-vms bot pushed a commit to jieyouxu/rust that referenced this issue Aug 4, 2024
PR rust-lang#128581 introduced an assertion that all builtin attributes are
actually checked via `CheckAttrVisitor` and aren't accidentally usable
on completely unrelated HIR nodes. Unfortunately, the check had
correctness problems.

The match on attribute path segments looked like

```rust,ignore
[sym::should_panic] => /* check is implemented */
match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}
```

However, it failed to account for edge cases such as an attribute whose:

1. path segments *starts* with a builtin attribute such as
   `should_panic`
2. which does not start with `rustc_`, and
3. is also an `AttributeType::Normal` attribute upon registration with
   the builtin attribute map

These conditions when all satisfied cause the span bug to be issued for e.g.
`#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's
`[sym::should_panic, sym::skip]`).

See <rust-lang#128622>.
@jieyouxu
Copy link
Member

jieyouxu commented Aug 4, 2024

Opened #128623 as a candidate fix.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Aug 5, 2024
…cote

Do not fire unhandled attribute assertion on multi-segment `AttributeType::Normal` attributes with builtin attribute as first segment

### The Problem

In rust-lang#128581 I introduced an assertion to check that all builtin attributes are actually checked via
`CheckAttrVisitor` and aren't accidentally usable on completely unrelated HIR nodes.
Unfortunately, the assertion had correctness problems as revealed in rust-lang#128622.

The match on attribute path segments looked like

```rs,ignore
// Normal handler
[sym::should_panic] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}
```

However, it failed to account for edge cases such as an attribute whose:

1. path segments *starts* with a segment matching the name of a builtin attribute such as `should_panic`, and
2. the first segment's symbol does not start with `rustc_`, and
3. the matched builtin attribute is also of `AttributeType::Normal` attribute type upon registration with the builtin attribute map.

These conditions when all satisfied cause the span bug to be issued for e.g.
`#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's
`[sym::should_panic, sym::skip]`).

### Proposed Solution

This PR tries to remedy that by adjusting all normal/specific handlers to not match exactly on a single segment, but instead match a prefix segment.

i.e.

```rs,ignore
// Normal handler, notice the `, ..` rest pattern
[sym::should_panic, ..] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}
```

### Review Remarks

This PR contains 2 commits:

1. The first commit adds a regression test. This will ICE without the `CheckAttrVisitor` changes.
2. The second commit adjusts `CheckAttrVisitor` assertion logic. Once this commit is applied, the test should no longer ICE and produce the expected bless stderr.

Fixes rust-lang#128622.

r? `@nnethercote` (since you reviewed rust-lang#128581)
@bors bors closed this as completed in 2048007 Aug 5, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Aug 5, 2024
Rollup merge of rust-lang#128623 - jieyouxu:check-attr-ice, r=nnethercote

Do not fire unhandled attribute assertion on multi-segment `AttributeType::Normal` attributes with builtin attribute as first segment

### The Problem

In rust-lang#128581 I introduced an assertion to check that all builtin attributes are actually checked via
`CheckAttrVisitor` and aren't accidentally usable on completely unrelated HIR nodes.
Unfortunately, the assertion had correctness problems as revealed in rust-lang#128622.

The match on attribute path segments looked like

```rs,ignore
// Normal handler
[sym::should_panic] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}
```

However, it failed to account for edge cases such as an attribute whose:

1. path segments *starts* with a segment matching the name of a builtin attribute such as `should_panic`, and
2. the first segment's symbol does not start with `rustc_`, and
3. the matched builtin attribute is also of `AttributeType::Normal` attribute type upon registration with the builtin attribute map.

These conditions when all satisfied cause the span bug to be issued for e.g.
`#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's
`[sym::should_panic, sym::skip]`).

### Proposed Solution

This PR tries to remedy that by adjusting all normal/specific handlers to not match exactly on a single segment, but instead match a prefix segment.

i.e.

```rs,ignore
// Normal handler, notice the `, ..` rest pattern
[sym::should_panic, ..] => /* check is implemented */
// Fallback handler
[name, ..] => match BUILTIN_ATTRIBUTE_MAP.get(name) {
    // checked below
    Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
    Some(_) => {
        if !name.as_str().starts_with("rustc_") {
            span_bug!(
                attr.span,
                "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
            )
        }
    }
    None => (),
}
```

### Review Remarks

This PR contains 2 commits:

1. The first commit adds a regression test. This will ICE without the `CheckAttrVisitor` changes.
2. The second commit adjusts `CheckAttrVisitor` assertion logic. Once this commit is applied, the test should no longer ICE and produce the expected bless stderr.

Fixes rust-lang#128622.

r? ``@nnethercote`` (since you reviewed rust-lang#128581)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
3 participants