Skip to content

Commit 68b76a4

Browse files
committed
Normalize after substituting via field.ty()
1 parent b7e358e commit 68b76a4

File tree

5 files changed

+62
-27
lines changed

5 files changed

+62
-27
lines changed

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1627,8 +1627,8 @@ impl ReprOptions {
16271627
}
16281628

16291629
impl<'tcx> FieldDef {
1630-
/// Returns the type of this field. The `subst` is typically obtained
1631-
/// via the second field of `TyKind::AdtDef`.
1630+
/// Returns the type of this field. The resulting type is not normalized. The `subst` is
1631+
/// typically obtained via the second field of `TyKind::AdtDef`.
16321632
pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
16331633
tcx.type_of(self.did).subst(tcx, subst)
16341634
}

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
11541154

11551155
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
11561156
let ty = field.ty(cx.tcx, substs);
1157+
// `field.ty()` doesn't normalize after substituting.
1158+
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
11571159
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
11581160
let is_uninhabited = cx.is_uninhabited(ty);
11591161

@@ -1671,7 +1673,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
16711673
write!(f, "{}", hi)
16721674
}
16731675
IntRange(range) => write!(f, "{:?}", range), // Best-effort, will render e.g. `false` as `0..=0`
1674-
Wildcard | Missing { .. } | NonExhaustive => write!(f, "_"),
1676+
Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty),
16751677
Or => {
16761678
for pat in self.iter_fields() {
16771679
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,7 @@ fn is_useful<'p, 'tcx>(
781781

782782
assert!(rows.iter().all(|r| r.len() == v.len()));
783783

784-
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
785-
let ty = matrix.heads().next().map_or(v.head().ty(), |r| r.ty());
784+
let ty = v.head().ty();
786785
let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty);
787786
let pcx = PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive };
788787

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// check-pass
2+
3+
// From https://github.com/rust-lang/rust/issues/72476
4+
// and https://github.com/rust-lang/rust/issues/89393
5+
6+
trait Trait {
7+
type Projection;
8+
}
9+
10+
struct A;
11+
impl Trait for A {
12+
type Projection = bool;
13+
}
14+
15+
struct B;
16+
impl Trait for B {
17+
type Projection = (u32, u32);
18+
}
19+
20+
struct Next<T: Trait>(T::Projection);
21+
22+
fn foo1(item: Next<A>) {
23+
match item {
24+
Next(true) => {}
25+
Next(false) => {}
26+
}
27+
}
28+
29+
fn foo2(x: <A as Trait>::Projection) {
30+
match x {
31+
true => {}
32+
false => {}
33+
}
34+
}
35+
36+
fn foo3(x: Next<B>) {
37+
let Next((_, _)) = x;
38+
match x {
39+
Next((_, _)) => {}
40+
}
41+
}
42+
43+
fn foo4(x: <B as Trait>::Projection) {
44+
let (_, _) = x;
45+
match x {
46+
(_, _) => {}
47+
}
48+
}
49+
50+
fn foo5<T: Trait>(x: <T as Trait>::Projection) {
51+
match x {
52+
_ => {}
53+
}
54+
}
55+
56+
fn main() {}

src/test/ui/pattern/usefulness/issue-72476-associated-type.rs

-22
This file was deleted.

0 commit comments

Comments
 (0)