Skip to content

Commit 4d3a91b

Browse files
committed
use non-ascribed type as field type in mir
1 parent ac31d52 commit 4d3a91b

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

compiler/rustc_mir_build/src/build/matches/simplify.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
294294

295295
PatKind::Leaf { ref subpatterns } => {
296296
// tuple struct, match subpats (if any)
297-
candidate.match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns));
297+
candidate
298+
.match_pairs
299+
.extend(self.field_match_pairs_tuple_struct(match_pair.place, subpatterns));
298300
Ok(())
299301
}
300302

compiler/rustc_mir_build/src/build/matches/util.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,51 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2525
.collect()
2626
}
2727

28+
#[instrument(skip(self), level = "debug")]
29+
pub(crate) fn field_match_pairs_tuple_struct<'pat>(
30+
&mut self,
31+
place_builder: PlaceBuilder<'tcx>,
32+
subpatterns: &'pat [FieldPat<'tcx>],
33+
) -> Vec<MatchPair<'pat, 'tcx>> {
34+
let place_ty = place_builder
35+
.try_ty(&self.local_decls, self)
36+
.map(|ty| self.tcx.normalize_erasing_regions(self.param_env, ty));
37+
debug!(?place_ty);
38+
39+
subpatterns
40+
.iter()
41+
.map(|fieldpat| {
42+
// NOTE: With type ascriptions it can happen that we get errors
43+
// during borrow-checking on higher-ranked types if we use the
44+
// ascribed type as the field type, so we try to get the actual field
45+
// type from the `Place`, if possible, see issue #96514
46+
let field_ty = if let Some(place_ty) = place_ty {
47+
let field_idx = fieldpat.field.as_usize();
48+
let field_ty = match place_ty.kind() {
49+
ty::Adt(adt_def, substs) => {
50+
adt_def.all_fields().collect::<Vec<_>>()[field_idx].ty(self.tcx, substs)
51+
}
52+
ty::Tuple(elems) => elems.to_vec()[field_idx],
53+
_ => bug!(
54+
"no field available, place_ty: {:#?}, kind: {:?}",
55+
place_ty,
56+
place_ty.kind()
57+
),
58+
};
59+
60+
self.tcx.normalize_erasing_regions(self.param_env, field_ty)
61+
} else {
62+
fieldpat.pattern.ty
63+
};
64+
65+
let place = place_builder.clone().field(fieldpat.field, field_ty);
66+
debug!(?place, ?field_ty);
67+
68+
MatchPair::new(place, &fieldpat.pattern, self)
69+
})
70+
.collect()
71+
}
72+
2873
pub(crate) fn prefix_slice_suffix<'pat>(
2974
&mut self,
3075
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,

0 commit comments

Comments
 (0)