1
Fork 0

Rollup merge of #89441 - Nadrieril:fix-89393, r=tmandry

Normalize after substituting via `field.ty()`

Back in https://github.com/rust-lang/rust/issues/72476 I hadn't understood where the problem was coming from, and only worked around the issue. What happens is that calling `field.ty()` on a field of a generic struct substitutes the appropriate generics but doesn't normalize the resulting type.
As a consumer of types I'm surprised that one would substitute without normalizing, feels like a footgun, so I added a comment.

Fixes https://github.com/rust-lang/rust/issues/89393.
This commit is contained in:
Manish Goregaokar 2021-10-01 14:46:52 -07:00 committed by GitHub
commit 5ab1245303
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 27 deletions

View file

@ -1154,6 +1154,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
let ty = field.ty(cx.tcx, substs);
// `field.ty()` doesn't normalize after substituting.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = cx.is_uninhabited(ty);
@ -1671,7 +1673,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
write!(f, "{}", hi)
}
IntRange(range) => write!(f, "{:?}", range), // Best-effort, will render e.g. `false` as `0..=0`
Wildcard | Missing { .. } | NonExhaustive => write!(f, "_"),
Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty),
Or => {
for pat in self.iter_fields() {
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;

View file

@ -781,8 +781,7 @@ fn is_useful<'p, 'tcx>(
assert!(rows.iter().all(|r| r.len() == v.len()));
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
let ty = matrix.heads().next().map_or(v.head().ty(), |r| r.ty());
let ty = v.head().ty();
let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty);
let pcx = PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive };