1
Fork 0

Add term to ExistentialProjection

Also prevent ICE when adding a const in associated const equality.
This commit is contained in:
kadmin 2022-01-13 07:39:58 +00:00
parent f396888c4d
commit 1c1ce2fbda
35 changed files with 213 additions and 71 deletions

View file

@ -4,7 +4,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::TyKind::*;
use crate::ty::{
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
ProjectionTy, TyCtxt, TyS, TypeAndMut,
ProjectionTy, Term, TyCtxt, TyS, TypeAndMut,
};
use rustc_errors::{Applicability, DiagnosticBuilder};
@ -105,8 +105,14 @@ impl<'tcx> TyS<'tcx> {
ExistentialPredicate::Trait(ExistentialTraitRef { substs, .. }) => {
substs.iter().all(generic_arg_is_suggestible)
}
ExistentialPredicate::Projection(ExistentialProjection { substs, ty, .. }) => {
ty.is_suggestable() && substs.iter().all(generic_arg_is_suggestible)
ExistentialPredicate::Projection(ExistentialProjection {
substs, term, ..
}) => {
let term_is_suggestable = match term {
Term::Ty(ty) => ty.is_suggestable(),
Term::Const(c) => const_is_suggestable(c.val),
};
term_is_suggestable && substs.iter().all(generic_arg_is_suggestible)
}
_ => true,
}),

View file

@ -320,7 +320,10 @@ impl FlagComputation {
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
self.add_ty(projection.ty);
match projection.term {
ty::Term::Ty(ty) => self.add_ty(ty),
ty::Term::Const(ct) => self.add_const(ct),
}
}
fn add_projection_ty(&mut self, projection_ty: ty::ProjectionTy<'_>) {

View file

@ -795,7 +795,7 @@ pub struct CoercePredicate<'tcx> {
}
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable)]
pub enum Term<'tcx> {
Ty(Ty<'tcx>),

View file

@ -905,29 +905,27 @@ pub trait PrettyPrinter<'tcx>:
}
for (assoc_item_def_id, term) in assoc_items {
let ty = match term.skip_binder() {
Term::Ty(ty) => ty,
Term::Const(c) => {
p!(print(c));
continue;
}
};
if !first {
p!(", ");
}
p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident));
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
match ty.kind() {
ty::Projection(ty::ProjectionTy { item_def_id, .. })
if Some(*item_def_id) == self.tcx().lang_items().generator_return() =>
{
p!("[async output]")
match term.skip_binder() {
Term::Ty(ty) => {
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
if matches!(
ty.kind(), ty::Projection(ty::ProjectionTy { item_def_id, .. })
if Some(*item_def_id) == self.tcx().lang_items().generator_return()
) {
p!("[async output]")
} else {
p!(print(ty))
}
}
_ => {
p!(print(ty))
Term::Const(c) => {
p!(print(c));
}
}
};
first = false;
}
@ -1031,7 +1029,11 @@ pub trait PrettyPrinter<'tcx>:
let mut projections = predicates.projection_bounds();
if let (Some(proj), None) = (projections.next(), projections.next()) {
let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
p!(pretty_fn_sig(&tys, false, proj.skip_binder().ty));
p!(pretty_fn_sig(
&tys,
false,
proj.skip_binder().term.ty().expect("Return type was a const")
));
resugared = true;
}
}
@ -2454,7 +2456,7 @@ define_print_and_forward_display! {
ty::ExistentialProjection<'tcx> {
let name = cx.tcx().associated_item(self.item_def_id).ident;
p!(write("{} = ", name), print(self.ty))
p!(write("{} = ", name), print(self.term))
}
ty::ExistentialPredicate<'tcx> {

View file

@ -291,11 +291,11 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
b.item_def_id,
)))
} else {
let ty = relation.relate_with_variance(
let term = relation.relate_with_variance(
ty::Invariant,
ty::VarianceDiagInfo::default(),
a.ty,
b.ty,
a.term,
b.term,
)?;
let substs = relation.relate_with_variance(
ty::Invariant,
@ -303,7 +303,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
a.substs,
b.substs,
)?;
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty })
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, term })
}
}
}

View file

@ -423,7 +423,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(self.substs).map(|substs| ty::ExistentialProjection {
substs,
ty: tcx.lift(self.ty).expect("type must lift when substs do"),
term: tcx.lift(self.term).expect("type must lift when substs do"),
item_def_id: self.item_def_id,
})
}

View file

@ -1540,7 +1540,7 @@ impl From<BoundVar> for BoundTy {
pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId,
pub substs: SubstsRef<'tcx>,
pub ty: Ty<'tcx>,
pub term: Term<'tcx>,
}
pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>;
@ -1570,7 +1570,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
item_def_id: self.item_def_id,
substs: tcx.mk_substs_trait(self_ty, self.substs),
},
term: self.ty.into(),
term: self.term,
}
}
@ -1580,15 +1580,11 @@ impl<'tcx> ExistentialProjection<'tcx> {
) -> Self {
// Assert there is a Self.
projection_predicate.projection_ty.substs.type_at(0);
let ty = match projection_predicate.term {
Term::Ty(ty) => ty,
Term::Const(_c) => unimplemented!(),
};
Self {
item_def_id: projection_predicate.projection_ty.item_def_id,
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
ty,
term: projection_predicate.term,
}
}
}

View file

@ -157,7 +157,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
stack.extend(obj.iter().rev().flat_map(|predicate| {
let (substs, opt_ty) = match predicate.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.ty)),
ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.term)),
ty::ExistentialPredicate::AutoTrait(_) =>
// Empty iterator
{
@ -165,7 +165,10 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
}
};
substs.iter().rev().chain(opt_ty.map(|ty| ty.into()))
substs.iter().rev().chain(opt_ty.map(|term| match term {
ty::Term::Ty(ty) => ty.into(),
ty::Term::Const(ct) => ct.into(),
}))
}));
}
ty::Adt(_, substs)