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: Unexpected type for constructor Variant(1) #125888

Open
Luv-Ray opened this issue Jun 2, 2024 · 3 comments · May be fixed by #127311
Open

ICE: Unexpected type for constructor Variant(1) #125888

Luv-Ray opened this issue Jun 2, 2024 · 3 comments · May be fixed by #127311
Labels
A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Luv-Ray
Copy link
Contributor

Luv-Ray commented Jun 2, 2024

I try to reduce the code of #125155 and find the ice changed.
Maybe duplicated with #120601 and #124004, but I think the code here is cleaner.

Code

enum NestedEnum {
    First,
    Second,
}

enum Enum {
    Variant(*const &'a ()),
}

fn foo(x: Enum) {
    match x {
        Enum::Variant(NestedEnum::Second) => {}
    }
}

fn main() {}

Meta

rustc --version --verbose:

rustc 1.80.0-nightly (6f3df08aa 2024-05-30)
binary: rustc
commit-hash: 6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4
commit-date: 2024-05-30
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.6
Error output

error[E0261]: use of undeclared lifetime name `'a`
 --> src/main.rs:7:21
  |
6 | enum Enum {
  |          - help: consider introducing lifetime `'a` here: `<'a>`
7 |     Variant(*const &'a ()),
  |                     ^^ undeclared lifetime

error: internal compiler error: compiler/rustc_pattern_analysis/src/rustc.rs:236:22: Unexpected type for constructor `Variant(1)`: *const &'{erased} ()

thread 'rustc' panicked at compiler/rustc_pattern_analysis/src/rustc.rs:236:22:
Box<dyn Any>
stack backtrace:
   0:     0x7b7b729f9dfb - std::backtrace_rs::backtrace::libunwind::trace::h7d54eacc88008817
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:     0x7b7b729f9dfb - std::backtrace_rs::backtrace::trace_unsynchronized::h1b384a49badbbbf0
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x7b7b729f9dfb - std::backtrace::Backtrace::create::ha4add90f9a9ffcbb
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/backtrace.rs:331:13
   3:     0x7b7b729f9d45 - std::backtrace::Backtrace::force_capture::he209e47860813be1
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/backtrace.rs:312:9
   4:     0x7b7b6f13432a - std[362b16250628d2ae]::panicking::update_hook::<alloc[36c56ba0e371072d]::boxed::Box<rustc_driver_impl[33236637d18b51d0]::install_ice_hook::{closure#0}>>::{closure#0}
   5:     0x7b7b72a14c2b - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h1df67ed3fceec998
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/alloc/src/boxed.rs:2077:9
   6:     0x7b7b72a14c2b - std::panicking::rust_panic_with_hook::h7947d7d7856ccdd3
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/panicking.rs:799:13
   7:     0x7b7b6f164644 - std[362b16250628d2ae]::panicking::begin_panic::<rustc_errors[59a72888fd61d3ce]::ExplicitBug>::{closure#0}
   8:     0x7b7b6f160f76 - std[362b16250628d2ae]::sys_common::backtrace::__rust_end_short_backtrace::<std[362b16250628d2ae]::panicking::begin_panic<rustc_errors[59a72888fd61d3ce]::ExplicitBug>::{closure#0}, !>
   9:     0x7b7b6f15c2c6 - std[362b16250628d2ae]::panicking::begin_panic::<rustc_errors[59a72888fd61d3ce]::ExplicitBug>
  10:     0x7b7b6f16dae1 - <rustc_errors[59a72888fd61d3ce]::diagnostic::BugAbort as rustc_errors[59a72888fd61d3ce]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
  11:     0x7b7b6f64d31c - rustc_middle[d10142e9169e5087]::util::bug::opt_span_bug_fmt::<rustc_span[6ca5b1b463c06ed1]::span_encoding::Span>::{closure#0}
  12:     0x7b7b6f63055a - rustc_middle[d10142e9169e5087]::ty::context::tls::with_opt::<rustc_middle[d10142e9169e5087]::util::bug::opt_span_bug_fmt<rustc_span[6ca5b1b463c06ed1]::span_encoding::Span>::{closure#0}, !>::{closure#0}
  13:     0x7b7b6f6303fb - rustc_middle[d10142e9169e5087]::ty::context::tls::with_context_opt::<rustc_middle[d10142e9169e5087]::ty::context::tls::with_opt<rustc_middle[d10142e9169e5087]::util::bug::opt_span_bug_fmt<rustc_span[6ca5b1b463c06ed1]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
  14:     0x7b7b6d9eb1a0 - rustc_middle[d10142e9169e5087]::util::bug::bug_fmt
  15:     0x7b7b70e1d8cb - rustc_pattern_analysis[8a3e0b8a86761bb1]::usefulness::compute_exhaustiveness_and_usefulness::<rustc_pattern_analysis[8a3e0b8a86761bb1]::rustc::RustcPatCtxt>::{closure#0}
  16:     0x7b7b70e178f3 - rustc_pattern_analysis[8a3e0b8a86761bb1]::usefulness::compute_exhaustiveness_and_usefulness::<rustc_pattern_analysis[8a3e0b8a86761bb1]::rustc::RustcPatCtxt>::{closure#0}
  17:     0x7b7b70e0e704 - rustc_pattern_analysis[8a3e0b8a86761bb1]::analyze_match
  18:     0x7b7b6daa9d42 - <rustc_mir_build[bacafdeaff7b19ff]::thir::pattern::check_match::MatchVisitor as rustc_middle[d10142e9169e5087]::thir::visit::Visitor>::visit_expr
  19:     0x7b7b6daa92bd - <rustc_mir_build[bacafdeaff7b19ff]::thir::pattern::check_match::MatchVisitor as rustc_middle[d10142e9169e5087]::thir::visit::Visitor>::visit_expr
  20:     0x7b7b6daaa134 - <rustc_mir_build[bacafdeaff7b19ff]::thir::pattern::check_match::MatchVisitor as rustc_middle[d10142e9169e5087]::thir::visit::Visitor>::visit_expr
  21:     0x7b7b6daa92bd - <rustc_mir_build[bacafdeaff7b19ff]::thir::pattern::check_match::MatchVisitor as rustc_middle[d10142e9169e5087]::thir::visit::Visitor>::visit_expr
  22:     0x7b7b70873686 - rustc_mir_build[bacafdeaff7b19ff]::thir::pattern::check_match::check_match
  23:     0x7b7b7087326d - rustc_query_impl[a4ad450ce75c81f3]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[a4ad450ce75c81f3]::query_impl::check_match::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 1usize]>>
  24:     0x7b7b70ad1b0e - rustc_query_system[466e502815dde757]::query::plumbing::try_execute_query::<rustc_query_impl[a4ad450ce75c81f3]::DynamicConfig<rustc_query_system[466e502815dde757]::query::caches::VecCache<rustc_span[6ca5b1b463c06ed1]::def_id::LocalDefId, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[a4ad450ce75c81f3]::plumbing::QueryCtxt, true>
  25:     0x7b7b706e5aad - rustc_query_impl[a4ad450ce75c81f3]::query_impl::check_match::get_query_incr::__rust_end_short_backtrace
  26:     0x7b7b7087afc9 - rustc_mir_build[bacafdeaff7b19ff]::build::mir_build
  27:     0x7b7b7087a68e - rustc_query_impl[a4ad450ce75c81f3]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[a4ad450ce75c81f3]::query_impl::mir_built::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 8usize]>>
  28:     0x7b7b70c69776 - rustc_query_system[466e502815dde757]::query::plumbing::try_execute_query::<rustc_query_impl[a4ad450ce75c81f3]::DynamicConfig<rustc_query_system[466e502815dde757]::query::caches::VecCache<rustc_span[6ca5b1b463c06ed1]::def_id::LocalDefId, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[a4ad450ce75c81f3]::plumbing::QueryCtxt, true>
  29:     0x7b7b70ad985c - rustc_query_impl[a4ad450ce75c81f3]::query_impl::mir_built::get_query_incr::__rust_end_short_backtrace
  30:     0x7b7b70c76aa6 - rustc_mir_build[bacafdeaff7b19ff]::check_unsafety::check_unsafety
  31:     0x7b7b70c76847 - rustc_query_impl[a4ad450ce75c81f3]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[a4ad450ce75c81f3]::query_impl::check_unsafety::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 0usize]>>
  32:     0x7b7b70ad7c61 - rustc_query_system[466e502815dde757]::query::plumbing::try_execute_query::<rustc_query_impl[a4ad450ce75c81f3]::DynamicConfig<rustc_query_system[466e502815dde757]::query::caches::VecCache<rustc_span[6ca5b1b463c06ed1]::def_id::LocalDefId, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[a4ad450ce75c81f3]::plumbing::QueryCtxt, true>
  33:     0x7b7b70ad777f - rustc_query_impl[a4ad450ce75c81f3]::query_impl::check_unsafety::get_query_incr::__rust_end_short_backtrace
  34:     0x7b7b70c7d05b - rustc_interface[749128fb2397a9e]::passes::analysis
  35:     0x7b7b70c7c15b - rustc_query_impl[a4ad450ce75c81f3]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[a4ad450ce75c81f3]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 1usize]>>
  36:     0x7b7b7156640a - rustc_query_system[466e502815dde757]::query::plumbing::try_execute_query::<rustc_query_impl[a4ad450ce75c81f3]::DynamicConfig<rustc_query_system[466e502815dde757]::query::caches::SingleCache<rustc_middle[d10142e9169e5087]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[a4ad450ce75c81f3]::plumbing::QueryCtxt, true>
  37:     0x7b7b7156603a - rustc_query_impl[a4ad450ce75c81f3]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
  38:     0x7b7b711ee71c - rustc_interface[749128fb2397a9e]::interface::run_compiler::<core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>, rustc_driver_impl[33236637d18b51d0]::run_compiler::{closure#0}>::{closure#1}
  39:     0x7b7b711d97e7 - std[362b16250628d2ae]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[749128fb2397a9e]::util::run_in_thread_with_globals<rustc_interface[749128fb2397a9e]::util::run_in_thread_pool_with_globals<rustc_interface[749128fb2397a9e]::interface::run_compiler<core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>, rustc_driver_impl[33236637d18b51d0]::run_compiler::{closure#0}>::{closure#1}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>::{closure#0}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>
  40:     0x7b7b711d95aa - <<std[362b16250628d2ae]::thread::Builder>::spawn_unchecked_<rustc_interface[749128fb2397a9e]::util::run_in_thread_with_globals<rustc_interface[749128fb2397a9e]::util::run_in_thread_pool_with_globals<rustc_interface[749128fb2397a9e]::interface::run_compiler<core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>, rustc_driver_impl[33236637d18b51d0]::run_compiler::{closure#0}>::{closure#1}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>::{closure#0}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[5f8c442e32640be5]::result::Result<(), rustc_span[6ca5b1b463c06ed1]::ErrorGuaranteed>>::{closure#2} as core[5f8c442e32640be5]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  41:     0x7b7b72a1ebfb - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hc666fad739fe414e
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/alloc/src/boxed.rs:2063:9
  42:     0x7b7b72a1ebfb - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hcd8201f663299c4b
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/alloc/src/boxed.rs:2063:9
  43:     0x7b7b72a1ebfb - std::sys::pal::unix::thread::Thread::new::thread_start::h4f248c4f539e2e55
                               at /rustc/6f3df08aadf71e8d4bf7e49f5dc10dfa6f254cb4/library/std/src/sys/pal/unix/thread.rs:108:17
  44:     0x7b7b727caded - <unknown>
  45:     0x7b7b7284e0dc - <unknown>
  46:                0x0 - <unknown>


rustc version: 1.80.0-nightly (6f3df08aa 2024-05-30)
platform: x86_64-unknown-linux-gnu

query stack during panic:
#0 [check_match] match-checking `foo`
#1 [mir_built] building MIR for `foo`
#2 [check_unsafety] unsafety-checking `foo`
#3 [analysis] running analysis passes on this crate
end of query stack

@Luv-Ray Luv-Ray added C-bug Category: This is a bug. 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. labels Jun 2, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 2, 2024
@lqd lqd added A-patterns Relating to patterns and pattern matching and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 2, 2024
@matthiaskrgr matthiaskrgr added the S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. label Jun 9, 2024
@Luv-Ray
Copy link
Contributor Author

Luv-Ray commented Jun 11, 2024

My thought after some debug:
There are some ways to trigger panic in compiler/rustc_pattern_analysis, because we trust that the type analysed here are all correct but they may not.

Consider two programs below:

// program A
enum NestedEnum {
    First,
    Second,
}

enum Enum {
    Variant(*const ()),
    // Variant(*const &'a ()),
}

fn foo(x: Enum) {
    match x {
        Enum::Variant(NestedEnum::Second) => {}
    }
}
// program B
enum NestedEnum {
    First,
    Second,
}

enum Enum {
    // Variant(*const ()),
    Variant(*const &'a ()),
}

fn foo(x: Enum) {
    match x {
        Enum::Variant(NestedEnum::Second) => {}
    }
}

program B will panic at compile while program A not. The difference occurs here:

pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let typeck_results = tcx.typeck(def_id);
let (thir, expr) = tcx.thir_body(def_id)?;
let thir = thir.borrow();

program A will early return at tcx.thir_body(def_id)?, but program B will not and cause the panic.
I have checked the typeck_results of two programs, and there is a key different between them: in program A typeck_results.tainted_by_errors is Some(ErrorGuaranteed(())), and in program B that is None.

A:

TypeckResults { hir_owner: DefId(0:12 ~ tmp[d0fa]::foo), type_dependent_defs: UnordMap { inner: {} }, field_indices: UnordMap { inner: {} }, nested_fields: UnordMap { inner: {} }, node_types: UnordMap { inner: {16: (), 13: (), 10: NestedEnum, 4: Enum, 1: Enum, 14: (), 11: Enum, 2: Enum, 15: (), 3: ()} }, node_args: UnordMap { inner: {} }, user_provided_types: UnordMap { inner: {} }, user_provided_sigs: UnordMap { inner: {} }, adjustments: UnordMap { inner: {} }, pat_binding_modes: UnordMap { inner: {2: BindingMode(No, Not)} }, rust_2024_migration_desugared_pats: UnordSet { inner: {} }, pat_adjustments: UnordMap { inner: {} }, skipped_ref_pats: UnordSet { inner: {} }, closure_kind_origins: UnordMap { inner: {} }, liberated_fn_sigs: UnordMap { inner: {0: fn(Enum)} }, fru_field_types: UnordMap { inner: {} }, coercion_casts: UnordSet { inner: {} }, used_trait_imports: UnordSet { inner: {} }, tainted_by_errors: Some(ErrorGuaranteed(())), concrete_opaque_types: {}, closure_min_captures: UnordMap { inner: {} }, closure_fake_reads: UnordMap { inner: {} }, rvalue_scopes: RvalueScopes { map: UnordMap { inner: {} } }, coroutine_stalled_predicates: {}, treat_byte_string_as_slice: UnordSet { inner: {} }, closure_size_eval: UnordMap { inner: {} }, offset_of_data: UnordMap { inner: {} }, inline_consts: {} }

B:

TypeckResults { hir_owner: DefId(0:12 ~ tmp2[62c9]::foo), type_dependent_defs: UnordMap { inner: {} }, field_indices: UnordMap { inner: {} }, nested_fields: UnordMap { inner: {} }, node_types: UnordMap { inner: {16: (), 13: (), 10: NestedEnum, 4: Enum, 1: Enum, 14: (), 11: Enum, 2: Enum, 15: (), 3: ()} }, node_args: UnordMap { inner: {} }, user_provided_types: UnordMap { inner: {} }, user_provided_sigs: UnordMap { inner: {} }, adjustments: UnordMap { inner: {} }, pat_binding_modes: UnordMap { inner: {2: BindingMode(No, Not)} }, rust_2024_migration_desugared_pats: UnordSet { inner: {} }, pat_adjustments: UnordMap { inner: {} }, skipped_ref_pats: UnordSet { inner: {} }, closure_kind_origins: UnordMap { inner: {} }, liberated_fn_sigs: UnordMap { inner: {0: fn(Enum)} }, fru_field_types: UnordMap { inner: {} }, coercion_casts: UnordSet { inner: {} }, used_trait_imports: UnordSet { inner: {} }, tainted_by_errors: None, concrete_opaque_types: {}, closure_min_captures: UnordMap { inner: {} }, closure_fake_reads: UnordMap { inner: {} }, rvalue_scopes: RvalueScopes { map: UnordMap { inner: {} } }, coroutine_stalled_predicates: {}, treat_byte_string_as_slice: UnordSet { inner: {} }, closure_size_eval: UnordMap { inner: {} }, offset_of_data: UnordMap { inner: {} }, inline_consts: {} }

In TyCtxt::thir_body's comment, it says: If typeck for that body failed, returns an empty Thir., but seems that it return ErrorGuaranteed rather than empty Thir if typeck failed. Is the description wrong here?

@Luv-Ray
Copy link
Contributor Author

Luv-Ray commented Jun 12, 2024

Because this hack, I think.

// HACK: We specifically don't want the (opaque) error from tainting our
// inference context. That'll prevent us from doing opaque type inference
// later on in borrowck, which affects diagnostic spans pretty negatively.
if let Some(e) = fcx.tainted_by_errors() {
wbcx.typeck_results.tainted_by_errors = Some(e);
}

@Luv-Ray
Copy link
Contributor Author

Luv-Ray commented Jun 13, 2024

program A set tainted_by_errors to Some(ErrorGuaranteed(())) here, but program B not.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 4, 2024
Avoid follow-up errors and ICEs after missing lifetime errors on data structures

Tuple struct constructors are functions, so when we call them typeck will use the signature tuple struct constructor function to provide type hints. Since typeck mostly ignores and erases lifetimes, we end up never seeing the error lifetime in writeback, thus not tainting the typeck result.

Now, we eagerly taint typeck results by tainting from `resolve_vars_if_possible`, which is called all over the place.

I did not carry over all the `crashes` test suite tests, as they are really all the same cause (missing or unknown lifetime names in tuple struct definitions or generic arg lists).

fixes rust-lang#124262
fixes rust-lang#124083
fixes rust-lang#125155
fixes rust-lang#125888
fixes rust-lang#125992
fixes rust-lang#126666
fixes rust-lang#126648
fixes rust-lang#127268
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants