Skip to content

Commit 11c4bea

Browse files
Rollup merge of #153453 - kpreid:fix-153388, r=fmease,estebank
Fix ICEs due to incomplete typechecking on struct literals with syntax errors. Fixes #153388. Followup to #153227. Today I have learned that when we don’t emit a diagnostic *specifically from typeck*, we need to call `self.infcx.set_tainted_by_errors()` to signal that the type checking is incomplete despite the lack of error. r? fmease
2 parents 4a5a216 + 072bd69 commit 11c4bea

3 files changed

Lines changed: 45 additions & 2 deletions

File tree

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2203,14 +2203,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22032203
};
22042204
self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys);
22052205
}
2206-
rustc_hir::StructTailExpr::NoneWithError(ErrorGuaranteed { .. }) => {
2206+
rustc_hir::StructTailExpr::NoneWithError(guaranteed) => {
22072207
// If parsing the struct recovered from a syntax error, do not report missing
22082208
// fields. This prevents spurious errors when a field is intended to be present
22092209
// but a preceding syntax error caused it not to be parsed. For example, if a
22102210
// struct type `StructName` has fields `foo` and `bar`, then
22112211
// StructName { foo(), bar: 2 }
22122212
// will not successfully parse a field `foo`, but we will not mention that,
22132213
// since the syntax error has already been reported.
2214+
2215+
// Signal that type checking has failed, even though we haven’t emitted a diagnostic
2216+
// about it ourselves.
2217+
self.infcx.set_tainted_by_errors(guaranteed);
22142218
}
22152219
rustc_hir::StructTailExpr::None => {
22162220
if adt_kind != AdtKind::Union

tests/ui/structs/syntax-error-not-missing-field.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,21 @@ fn enum_expr_missing_separator() {
4747
let e = Bar::Baz { a: make_a() b: 2 }; //~ ERROR found `b`
4848
}
4949

50+
// Should error but not then ICE due to lack of type checking
51+
fn regression_test_for_issue_153388_a() {
52+
struct TheStruct;
53+
struct MyStruct {
54+
value: i32,
55+
s: TheStruct,
56+
}
57+
static A: MyStruct = MyStruct { ,s: TheStruct }; //~ ERROR expected identifier, found `,`
58+
}
59+
60+
fn regression_test_for_issue_153388_b() {
61+
struct MyStruct {
62+
value: i32,
63+
}
64+
static A: MyStruct = MyStruct {,}; //~ ERROR expected identifier, found `,`
65+
}
66+
5067
fn main() {}

tests/ui/structs/syntax-error-not-missing-field.stderr

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,27 @@ LL | let e = Bar::Baz { a: make_a() b: 2 };
8989
| | help: try adding a comma: `,`
9090
| while parsing this struct
9191

92-
error: aborting due to 9 previous errors
92+
error: expected identifier, found `,`
93+
--> $DIR/syntax-error-not-missing-field.rs:57:37
94+
|
95+
LL | static A: MyStruct = MyStruct { ,s: TheStruct };
96+
| -------- ^ expected identifier
97+
| |
98+
| while parsing this struct
99+
|
100+
help: remove this comma
101+
|
102+
LL - static A: MyStruct = MyStruct { ,s: TheStruct };
103+
LL + static A: MyStruct = MyStruct { s: TheStruct };
104+
|
105+
106+
error: expected identifier, found `,`
107+
--> $DIR/syntax-error-not-missing-field.rs:64:36
108+
|
109+
LL | static A: MyStruct = MyStruct {,};
110+
| -------- ^ expected identifier
111+
| |
112+
| while parsing this struct
113+
114+
error: aborting due to 11 previous errors
93115

0 commit comments

Comments
 (0)