rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
94.89k stars 12.23k forks source link

ICE: typeck: `no index for a field` #126744

Open matthiaskrgr opened 2 weeks ago

matthiaskrgr commented 2 weeks ago

snippet:

struct TestStruct {,}

fn edge_case_if() {
    let ts = TestStruct {};
    let _b = || { match ts {
        TestStruct{ x: 1, .. } | _ => (),
    }};
}

Version information

rustc 1.81.0-nightly (1ca578e68 2024-06-20)
binary: rustc
commit-hash: 1ca578e68eb715e772fc0c1b9e6ca7c5b122765a
commit-date: 2024-06-20
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7

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

Program output

``` error: expected identifier, found `,` --> /tmp/icemaker_global_tempdir.hJLG4Uu9QCDq/rustc_testrunner_tmpdir_reporting.cVa4rm3LGIDH/mvce.rs:1:20 | 1 | struct TestStruct {,} | ---------- ^ expected identifier | | | while parsing this struct error[E0601]: `main` function not found in crate `mvce` --> /tmp/icemaker_global_tempdir.hJLG4Uu9QCDq/rustc_testrunner_tmpdir_reporting.cVa4rm3LGIDH/mvce.rs:8:2 | 8 | } | ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.hJLG4Uu9QCDq/rustc_testrunner_tmpdir_reporting.cVa4rm3LGIDH/mvce.rs` thread 'rustc' panicked at compiler/rustc_hir_typeck/src/expr_use_visitor.rs:1697:26: no index for a field stack backtrace: 0: 0x71e31da31915 - std::backtrace_rs::backtrace::libunwind::trace::h796e75e96c439f3e at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5 1: 0x71e31da31915 - std::backtrace_rs::backtrace::trace_unsynchronized::h57b5b13bb46e11ba at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 2: 0x71e31da31915 - std::sys::backtrace::_print_fmt::h11ce45f986076e87 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/backtrace.rs:68:5 3: 0x71e31da31915 - ::fmt::hcd09ba6a4fc236f1 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/backtrace.rs:44:22 4: 0x71e31da824bb - core::fmt::rt::Argument::fmt::h914f09f4a1c58d59 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/core/src/fmt/rt.rs:165:63 5: 0x71e31da824bb - core::fmt::write::hc590b91d463e6a2c at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/core/src/fmt/mod.rs:1168:21 6: 0x71e31da265af - std::io::Write::write_fmt::hc69b1d0ded026622 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/io/mod.rs:1835:15 7: 0x71e31da316ee - std::sys::backtrace::_print::hc852e4497da27a95 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/backtrace.rs:47:5 8: 0x71e31da316ee - std::sys::backtrace::print::hc624de700d5fe576 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/backtrace.rs:34:9 9: 0x71e31da34129 - std::panicking::default_hook::{{closure}}::hf8d8481f1d9702fb 10: 0x71e31da33ecc - std::panicking::default_hook::he469b58de751f8ee at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/panicking.rs:292:9 11: 0x71e31a147870 - std[eca1b30e63fdea7a]::panicking::update_hook::>::{closure#0} 12: 0x71e31da34a4f - as core::ops::function::Fn>::call::h7fb9108d23a6d563 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/alloc/src/boxed.rs:2076:9 13: 0x71e31da34a4f - std::panicking::rust_panic_with_hook::h738066c73a52890f at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/panicking.rs:804:13 14: 0x71e31da34677 - std::panicking::begin_panic_handler::{{closure}}::h8534a2aac695431b at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/panicking.rs:670:13 15: 0x71e31da31dd9 - std::sys::backtrace::__rust_end_short_backtrace::h3420ee35d28bf807 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/backtrace.rs:171:18 16: 0x71e31da34304 - rust_begin_unwind at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/panicking.rs:661:5 17: 0x71e31da7ea73 - core::panicking::panic_fmt::h51cb44e3a97167f8 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/core/src/panicking.rs:74:14 18: 0x71e31da7e8cb - core::panicking::panic_display::h01c80b100e2db3b0 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/core/src/panicking.rs:264:5 19: 0x71e31da7e8cb - core::option::expect_failed::h227980ecada19c49 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/core/src/option.rs:2023:5 20: 0x71e31c05cd08 - >::cat_pattern::<>::maybe_read_scrutinee, >::walk_expr::{closure#1}>>::{closure#0}> 21: 0x71e31c05c919 - >::cat_pattern::<>::maybe_read_scrutinee, >::walk_expr::{closure#1}>>::{closure#0}> 22: 0x71e31c0669c0 - >::walk_expr 23: 0x71e31c0656b0 - >::consume_expr 24: 0x71e31c06404e - >::walk_block 25: 0x71e31c0656b0 - >::consume_expr 26: 0x71e31c05e887 - ::analyze_closure 27: 0x71e31900c688 - ::visit_expr 28: 0x71e31b8a58ef - ::visit_block 29: 0x71e31b8a780b - rustc_hir_typeck[3a3cc19eb2dfac16]::typeck 30: 0x71e31b8a6ffb - rustc_query_impl[da2d3b64247f93f0]::plumbing::__rust_begin_short_backtrace::> 31: 0x71e31ba031ee - rustc_query_system[5e65d9b3abdd3162]::query::plumbing::try_execute_query::>, false, false, false>, rustc_query_impl[da2d3b64247f93f0]::plumbing::QueryCtxt, false> 32: 0x71e31ba01cdf - rustc_query_impl[da2d3b64247f93f0]::query_impl::typeck::get_query_non_incr::__rust_end_short_backtrace 33: 0x71e31ba01915 - ::par_body_owners::::{closure#0} 34: 0x71e31ba003bc - rustc_hir_analysis[74e881c9b9f2b37]::check_crate 35: 0x71e31bdf4f87 - rustc_interface[7fb7dc76513cf959]::passes::analysis 36: 0x71e31bdf4ac7 - rustc_query_impl[da2d3b64247f93f0]::plumbing::__rust_begin_short_backtrace::> 37: 0x71e31c433ea5 - rustc_query_system[5e65d9b3abdd3162]::query::plumbing::try_execute_query::>, false, false, false>, rustc_query_impl[da2d3b64247f93f0]::plumbing::QueryCtxt, false> 38: 0x71e31c433c0f - rustc_query_impl[da2d3b64247f93f0]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace 39: 0x71e31c2dd252 - rustc_interface[7fb7dc76513cf959]::interface::run_compiler::, rustc_driver_impl[93e75e0175b92285]::run_compiler::{closure#0}>::{closure#1} 40: 0x71e31c29dac9 - std[eca1b30e63fdea7a]::sys::backtrace::__rust_begin_short_backtrace::, rustc_driver_impl[93e75e0175b92285]::run_compiler::{closure#0}>::{closure#1}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>>::{closure#0}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>> 41: 0x71e31c29d880 - <::spawn_unchecked_, rustc_driver_impl[93e75e0175b92285]::run_compiler::{closure#0}>::{closure#1}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>>::{closure#0}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[daaba097f859fa28]::result::Result<(), rustc_span[1efc0ab8e6bb0790]::ErrorGuaranteed>>::{closure#2} as core[daaba097f859fa28]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} 42: 0x71e31da3e8cb - as core::ops::function::FnOnce>::call_once::ha1ad2417ff4e2c89 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/alloc/src/boxed.rs:2062:9 43: 0x71e31da3e8cb - as core::ops::function::FnOnce>::call_once::ha5ab2243447620ef at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/alloc/src/boxed.rs:2062:9 44: 0x71e31da3e8cb - std::sys::pal::unix::thread::Thread::new::thread_start::he00df2d38aeed7a5 at /rustc/1ca578e68eb715e772fc0c1b9e6ca7c5b122765a/library/std/src/sys/pal/unix/thread.rs:108:17 45: 0x71e316ca6ded - 46: 0x71e316d2a0dc - 47: 0x0 - error: the compiler unexpectedly panicked. this is a bug. 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.81.0-nightly (1ca578e68 2024-06-20) running on x86_64-unknown-linux-gnu query stack during panic: #0 [typeck] type-checking `edge_case_if` #1 [analysis] running analysis passes on this crate end of query stack error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0601`. ```

matthiaskrgr commented 2 weeks ago

126320 cc @oli-obk :D

oli-obk commented 2 weeks ago

wtf. why does that wrong comma cause the struct to be different from a struct with no fields

matthiaskrgr commented 2 weeks ago

minimized

struct X {,}

fn main() {
    || {
        if let X { x: 1,} = (X {}) {}
    };
}
chenyukang commented 1 day ago

wtf. why does that wrong comma cause the struct to be different from a struct with no fields

An extra , is a recovered struct variant, and it is skipped here: https://github.com/rust-lang/rust/blob/382148d9a21ae0b506adf44fc1e55a410acde828/compiler/rustc_hir_typeck/src/pat.rs#L1533

so we didn't emit the error like an empty struct: https://github.com/rust-lang/rust/blob/382148d9a21ae0b506adf44fc1e55a410acde828/compiler/rustc_hir_typeck/src/pat.rs#L1610

error[E0026]: struct `X` does not have a field named `x`
 --> src/main.rs:5:20
  |
5 |         if let X { x: 1,} = (X {}) {}
  |                    ^ struct `X` does not have this field

So the compiler continues until the ICE point.

I think a trivial fix will be ok here?

oli-obk commented 1 day ago

Hmm... I'd look into reporting that error even for recovered structs and figuring out how to avoid it just for the cases that this skip was intended to avoid

chenyukang commented 16 hours ago

seems there is nothing else we are trying to avoid:

https://github.com/rust-lang/rust/commit/2ea2bb430665277ccb01e514011782b329f78840

I'd prefer not to report the no-field error, since the first error in parsing will point out the root cause, and there is a case like https://github.com/rust-lang/rust/issues/126344, which may introduce noise when there are too many type errors, it's also applied to this issue.

oli-obk commented 11 hours ago

Oh... we can probably just replace the is_recovered method with a new tainted_by_errors method and return an Result<(), ErrorGuaranteed>. This way we act as if we reported an error, and thus not continue to the ICE

oli-obk commented 11 hours ago

Since we cannot encode an ErrorGuaranteed in the flags list, either take a TyCtxt argument on the tainted_by_errors method, or check if replacing the field field with Result<IndexVec<FieldIdx, FieldDef>, ErrorGuaranteed> works out nicely