internal compiler error: no type for node HirId ...
dwrensha opened this issue · 10 comments
I'm seeing an internal compiler error on the following input (found by fuzz-rustc):
struct Foo { 0: u8 }
fn test(f: Foo) {
Foo{foo: 4, ..f};
}
fn main() {}
$ rustc main.rs
error: expected identifier, found `0`
--> main.rs:1:14
|
1 | struct Foo { 0: u8 }
| ^ expected identifier
error: internal compiler error: src/librustc_typeck/check/mod.rs:3328: no type for node HirId { owner: DefIndex(4), local_id: 4 }: expr f (hir_id=HirId { owner: DefIndex(4), local_id: 4 }) in fcx 0x7fdb535efe40
thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:881:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.43.0-nightly (8aa9d2014 2020-02-21) running on x86_64-unknown-linux-gnu
error: aborting due to 2 previous errors
The error happens on stable
, beta
, and nightly
.
I'm looking into this! But mostly as a learning exercise. Spent ~4 hours exploring typeck & error handling today to see why this exact combination of things triggers an error. My friend and I will probably have a solution at some point, but it might be a few weeks from now.
If anyone has a good & quick solution, or if it is deemed high-priority, then feel free to ignore me.
According to cargo-bisect-rustc
, this regressed between 2019-07-30 and 2019-07-31. Unfortunately, cargo-bisect-rustc
seems to be incapable of narrowing it down to a commit because that was more than 167 days ago.
EDIT: cargo-bisect-rustc
gave me a misleading result. This error is at least as old as nightly-2019-07-19
.
The ICE goes away if I apply this patch:
$ git diff
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 38d73256469..a3bb0c2fb81 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1311,9 +1311,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind_name: &str,
ty_span: Span,
) {
- if variant.recovered {
- return;
- }
let mut err = self.type_error_struct_with_diag(
field.ident.span,
|actual| match ty.kind {
(Though I'd guess that making this change would cause us to regress on the problems that #59266 fixed.)
This change fixes the ICE and avoids regressing on ui/parser/recovered-struct-variant.rs
:
$ git diff
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 38d73256469..bd80cc31e3c 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1218,8 +1218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.field_ty(field.span, v_field, substs)
} else {
- error_happened = true;
if let Some(prev_span) = seen_fields.get(&ident) {
+ error_happened = true;
let mut err = struct_span_err!(
self.tcx.sess,
field.ident.span,
@@ -1232,7 +1232,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_label(*prev_span, format!("first use of `{}`", ident));
err.emit();
- } else {
+ } else if !variant.recovered {
+ error_happened = true;
self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span);
}
@@ -1311,9 +1312,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind_name: &str,
ty_span: Span,
) {
- if variant.recovered {
- return;
- }
let mut err = self.type_error_struct_with_diag(
field.ident.span,
|actual| match ty.kind {
I'm unsure whether this respects the intended meaning of error_happened
, though.
Unfortunately, the patch that I proposed above fails on this modification of ui/issues/issue-50618.rs
:
struct Point {
pub x: u64,
pub y: u64,
0: u64,
}
fn main() {
let _ = |t: Point| {
Point {
nonexistent: 0,
..t
}
};
}
triage: P-high. Removing nomination. Added regression stable-to-stable tag.
I think I found a way to resolve this without regressing on #59266. The point of this PR is to not emit an error if it might be invalid to the user. But there are errors in context still. The patch I propose is this:
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 38d73256469..14615521749 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1312,6 +1312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty_span: Span,
) {
if variant.recovered {
+ self.set_tainted_by_errors();
return;
}
let mut err = self.type_error_struct_with_diag(
This does pass every UI test. I'll open a PR so this can be discussed more easely.