mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Normalize after substituting via field.ty()
This commit is contained in:
parent
b7e358ee17
commit
68b76a4835
@ -1627,8 +1627,8 @@ impl ReprOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> FieldDef {
|
impl<'tcx> FieldDef {
|
||||||
/// Returns the type of this field. The `subst` is typically obtained
|
/// Returns the type of this field. The resulting type is not normalized. The `subst` is
|
||||||
/// via the second field of `TyKind::AdtDef`.
|
/// typically obtained via the second field of `TyKind::AdtDef`.
|
||||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
|
pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
|
||||||
tcx.type_of(self.did).subst(tcx, subst)
|
tcx.type_of(self.did).subst(tcx, subst)
|
||||||
}
|
}
|
||||||
|
@ -1154,6 +1154,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
|||||||
|
|
||||||
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
|
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
|
||||||
let ty = field.ty(cx.tcx, substs);
|
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_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
|
||||||
let is_uninhabited = cx.is_uninhabited(ty);
|
let is_uninhabited = cx.is_uninhabited(ty);
|
||||||
|
|
||||||
@ -1671,7 +1673,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
|
|||||||
write!(f, "{}", hi)
|
write!(f, "{}", hi)
|
||||||
}
|
}
|
||||||
IntRange(range) => write!(f, "{:?}", range), // Best-effort, will render e.g. `false` as `0..=0`
|
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 => {
|
Or => {
|
||||||
for pat in self.iter_fields() {
|
for pat in self.iter_fields() {
|
||||||
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;
|
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;
|
||||||
|
@ -781,8 +781,7 @@ fn is_useful<'p, 'tcx>(
|
|||||||
|
|
||||||
assert!(rows.iter().all(|r| r.len() == v.len()));
|
assert!(rows.iter().all(|r| r.len() == v.len()));
|
||||||
|
|
||||||
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
|
let ty = v.head().ty();
|
||||||
let ty = matrix.heads().next().map_or(v.head().ty(), |r| r.ty());
|
|
||||||
let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(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 };
|
let pcx = PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive };
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
// From https://github.com/rust-lang/rust/issues/72476
|
||||||
|
// and https://github.com/rust-lang/rust/issues/89393
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
impl Trait for A {
|
||||||
|
type Projection = bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B;
|
||||||
|
impl Trait for B {
|
||||||
|
type Projection = (u32, u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Next<T: Trait>(T::Projection);
|
||||||
|
|
||||||
|
fn foo1(item: Next<A>) {
|
||||||
|
match item {
|
||||||
|
Next(true) => {}
|
||||||
|
Next(false) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo2(x: <A as Trait>::Projection) {
|
||||||
|
match x {
|
||||||
|
true => {}
|
||||||
|
false => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo3(x: Next<B>) {
|
||||||
|
let Next((_, _)) = x;
|
||||||
|
match x {
|
||||||
|
Next((_, _)) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo4(x: <B as Trait>::Projection) {
|
||||||
|
let (_, _) = x;
|
||||||
|
match x {
|
||||||
|
(_, _) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo5<T: Trait>(x: <T as Trait>::Projection) {
|
||||||
|
match x {
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -1,22 +0,0 @@
|
|||||||
// check-pass
|
|
||||||
|
|
||||||
// From https://github.com/rust-lang/rust/issues/72476
|
|
||||||
|
|
||||||
trait A {
|
|
||||||
type Projection;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl A for () {
|
|
||||||
type Projection = bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Next<T: A>(T::Projection);
|
|
||||||
|
|
||||||
fn f(item: Next<()>) {
|
|
||||||
match item {
|
|
||||||
Next(true) => {}
|
|
||||||
Next(false) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
Loading…
Reference in New Issue
Block a user