Skip to content

Commit 3bcfa4c

Browse files
authored
Rollup merge of #105267 - compiler-errors:issue-104613, r=oli-obk
Don't ICE in ExprUseVisitor on FRU for non-existent struct Fixes #104613 Fixes #105202
2 parents 91b8f34 + 1c81540 commit 3bcfa4c

File tree

13 files changed

+85
-19
lines changed

13 files changed

+85
-19
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16471647
// the fields with the base_expr. This could cause us to hit errors later
16481648
// when certain fields are assumed to exist that in fact do not.
16491649
if error_happened {
1650+
if let Some(base_expr) = base_expr {
1651+
self.check_expr(base_expr);
1652+
}
16501653
return;
16511654
}
16521655

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
523523
// Consume the expressions supplying values for each field.
524524
for field in fields {
525525
self.consume_expr(field.expr);
526+
527+
// The struct path probably didn't resolve
528+
if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() {
529+
self.tcx().sess.delay_span_bug(field.span, "couldn't resolve index for field");
530+
}
526531
}
527532

528533
let with_expr = match *opt_with {
@@ -540,9 +545,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
540545
ty::Adt(adt, substs) if adt.is_struct() => {
541546
// Consume those fields of the with expression that are needed.
542547
for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() {
543-
let is_mentioned = fields.iter().any(|f| {
544-
self.tcx().field_index(f.hir_id, self.mc.typeck_results) == f_index
545-
});
548+
let is_mentioned = fields
549+
.iter()
550+
.any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
546551
if !is_mentioned {
547552
let field_place = self.mc.cat_projection(
548553
&*with_expr,

compiler/rustc_lint/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
259259
}
260260
if let PatKind::Binding(binding_annot, _, ident, None) = fieldpat.pat.kind {
261261
if cx.tcx.find_field_index(ident, &variant)
262-
== Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
262+
== Some(cx.typeck_results().field_index(fieldpat.hir_id))
263263
{
264264
cx.struct_span_lint(
265265
NON_SHORTHAND_FIELD_PATTERNS,

compiler/rustc_middle/src/ty/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,14 @@ impl<'tcx> TypeckResults<'tcx> {
667667
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices }
668668
}
669669

670+
pub fn field_index(&self, id: hir::HirId) -> usize {
671+
self.field_indices().get(id).cloned().expect("no index for a field")
672+
}
673+
674+
pub fn opt_field_index(&self, id: hir::HirId) -> Option<usize> {
675+
self.field_indices().get(id).cloned()
676+
}
677+
670678
pub fn user_provided_types(&self) -> LocalTableInContext<'_, CanonicalUserType<'tcx>> {
671679
LocalTableInContext { hir_owner: self.hir_owner, data: &self.user_provided_types }
672680
}

compiler/rustc_middle/src/ty/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -2142,10 +2142,6 @@ impl<'tcx> TyCtxt<'tcx> {
21422142
}
21432143
}
21442144

2145-
pub fn field_index(self, hir_id: hir::HirId, typeck_results: &TypeckResults<'_>) -> usize {
2146-
typeck_results.field_indices().get(hir_id).cloned().expect("no index for a field")
2147-
}
2148-
21492145
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
21502146
variant
21512147
.fields

compiler/rustc_mir_build/src/thir/cx/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ impl<'tcx> Cx<'tcx> {
704704
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
705705
lhs: self.mirror_expr(source),
706706
variant_index: VariantIdx::new(0),
707-
name: Field::new(tcx.field_index(expr.hir_id, self.typeck_results)),
707+
name: Field::new(self.typeck_results.field_index(expr.hir_id)),
708708
},
709709
hir::ExprKind::Cast(ref source, ref cast_ty) => {
710710
// Check for a user-given type annotation on this `cast`
@@ -1079,7 +1079,7 @@ impl<'tcx> Cx<'tcx> {
10791079
fields
10801080
.iter()
10811081
.map(|field| FieldExpr {
1082-
name: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)),
1082+
name: Field::new(self.typeck_results.field_index(field.hir_id)),
10831083
expr: self.mirror_expr(field.expr),
10841084
})
10851085
.collect()

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
321321
let subpatterns = fields
322322
.iter()
323323
.map(|field| FieldPat {
324-
field: Field::new(self.tcx.field_index(field.hir_id, self.typeck_results)),
324+
field: Field::new(self.typeck_results.field_index(field.hir_id)),
325325
pattern: self.lower_pattern(&field.pat),
326326
})
327327
.collect();

compiler/rustc_passes/src/dead.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
124124
fn handle_field_access(&mut self, lhs: &hir::Expr<'_>, hir_id: hir::HirId) {
125125
match self.typeck_results().expr_ty_adjusted(lhs).kind() {
126126
ty::Adt(def, _) => {
127-
let index = self.tcx.field_index(hir_id, self.typeck_results());
127+
let index = self.typeck_results().field_index(hir_id);
128128
self.insert_def_id(def.non_enum_variant().fields[index].did);
129129
}
130130
ty::Tuple(..) => {}
@@ -208,7 +208,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
208208
if let PatKind::Wild = pat.pat.kind {
209209
continue;
210210
}
211-
let index = self.tcx.field_index(pat.hir_id, self.typeck_results());
211+
let index = self.typeck_results().field_index(pat.hir_id);
212212
self.insert_def_id(variant.fields[index].did);
213213
}
214214
}
@@ -341,7 +341,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
341341
fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) {
342342
if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() {
343343
for field in fields {
344-
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
344+
let index = self.typeck_results().field_index(field.hir_id);
345345
self.insert_def_id(adt.non_enum_variant().fields[index].did);
346346
}
347347
}

compiler/rustc_privacy/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1065,9 +1065,9 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10651065
// are checked for privacy (RFC 736). Rather than computing the set of
10661066
// unmentioned fields, just check them all.
10671067
for (vf_index, variant_field) in variant.fields.iter().enumerate() {
1068-
let field = fields.iter().find(|f| {
1069-
self.tcx.field_index(f.hir_id, self.typeck_results()) == vf_index
1070-
});
1068+
let field = fields
1069+
.iter()
1070+
.find(|f| self.typeck_results().field_index(f.hir_id) == vf_index);
10711071
let (use_ctxt, span) = match field {
10721072
Some(field) => (field.ident.span, field.span),
10731073
None => (base.span, base.span),
@@ -1077,7 +1077,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10771077
} else {
10781078
for field in fields {
10791079
let use_ctxt = field.ident.span;
1080-
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
1080+
let index = self.typeck_results().field_index(field.hir_id);
10811081
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
10821082
}
10831083
}
@@ -1093,7 +1093,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10931093
let variant = adt.variant_of_res(res);
10941094
for field in fields {
10951095
let use_ctxt = field.ident.span;
1096-
let index = self.tcx.field_index(field.hir_id, self.typeck_results());
1096+
let index = self.typeck_results().field_index(field.hir_id);
10971097
self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
10981098
}
10991099
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// compile-flags: -Zdrop-tracking
2+
// edition: 2021
3+
4+
fn main() {}
5+
6+
async fn foo() {
7+
None { value: (), ..Default::default() }.await;
8+
//~^ ERROR `Option<_>` is not a future
9+
//~| ERROR variant `Option<_>::None` has no field named `value`
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0559]: variant `Option<_>::None` has no field named `value`
2+
--> $DIR/drop-track-bad-field-in-fru.rs:7:12
3+
|
4+
LL | None { value: (), ..Default::default() }.await;
5+
| ^^^^^ `Option<_>::None` does not have this field
6+
7+
error[E0277]: `Option<_>` is not a future
8+
--> $DIR/drop-track-bad-field-in-fru.rs:7:45
9+
|
10+
LL | None { value: (), ..Default::default() }.await;
11+
| ^^^^^^
12+
| |
13+
| `Option<_>` is not a future
14+
| help: remove the `.await`
15+
|
16+
= help: the trait `Future` is not implemented for `Option<_>`
17+
= note: Option<_> must be a future or must implement `IntoFuture` to be awaited
18+
= note: required for `Option<_>` to implement `IntoFuture`
19+
20+
error: aborting due to 2 previous errors
21+
22+
Some errors have detailed explanations: E0277, E0559.
23+
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
struct S {
2+
a: u32,
3+
}
4+
5+
fn main() {
6+
let s1 = S { a: 1 };
7+
8+
let _ = || {
9+
let s2 = Oops { a: 2, ..s1 };
10+
//~^ ERROR cannot find struct, variant or union type `Oops` in this scope
11+
};
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0422]: cannot find struct, variant or union type `Oops` in this scope
2+
--> $DIR/unresolved-struct-with-fru.rs:9:18
3+
|
4+
LL | let s2 = Oops { a: 2, ..s1 };
5+
| ^^^^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0422`.

0 commit comments

Comments
 (0)