Add polarity to TraitPredicate
This commit is contained in:
parent
72d66064e7
commit
6975afd141
@ -94,6 +94,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}))),
|
||||
locations,
|
||||
category,
|
||||
|
@ -825,6 +825,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
|
||||
Binder::dummy(TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -137,6 +137,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -34,6 +34,7 @@ impl<T> ExpectedFound<T> {
|
||||
pub enum TypeError<'tcx> {
|
||||
Mismatch,
|
||||
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
|
||||
PolarityMismatch(ExpectedFound<ty::ImplPolarity>),
|
||||
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
|
||||
AbiMismatch(ExpectedFound<abi::Abi>),
|
||||
Mutability,
|
||||
@ -104,6 +105,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||
ConstnessMismatch(values) => {
|
||||
write!(f, "expected {} bound, found {} bound", values.expected, values.found)
|
||||
}
|
||||
PolarityMismatch(values) => {
|
||||
write!(f, "expected {} polarity, found {} polarity", values.expected, values.found)
|
||||
}
|
||||
UnsafetyMismatch(values) => {
|
||||
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
|
||||
}
|
||||
@ -212,10 +216,9 @@ impl<'tcx> TypeError<'tcx> {
|
||||
use self::TypeError::*;
|
||||
match self {
|
||||
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
|
||||
| Mismatch | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
|
||||
| IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) | TargetFeatureCast(_) => {
|
||||
false
|
||||
}
|
||||
| PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
|
||||
| ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_)
|
||||
| VariadicMismatch(_) | TargetFeatureCast(_) => false,
|
||||
|
||||
Mutability
|
||||
| ArgumentMutability(_)
|
||||
|
@ -165,7 +165,18 @@ pub struct ImplHeader<'tcx> {
|
||||
pub predicates: Vec<Predicate<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
TyEncodable,
|
||||
TyDecodable,
|
||||
HashStable,
|
||||
Debug,
|
||||
TypeFoldable
|
||||
)]
|
||||
pub enum ImplPolarity {
|
||||
/// `impl Trait for Type`
|
||||
Positive,
|
||||
@ -178,6 +189,26 @@ pub enum ImplPolarity {
|
||||
Reservation,
|
||||
}
|
||||
|
||||
impl ImplPolarity {
|
||||
pub fn flip(&self) -> Option<ImplPolarity> {
|
||||
match self {
|
||||
ImplPolarity::Positive => Some(ImplPolarity::Negative),
|
||||
ImplPolarity::Negative => Some(ImplPolarity::Positive),
|
||||
ImplPolarity::Reservation => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ImplPolarity {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Positive => f.write_str("positive"),
|
||||
Self::Negative => f.write_str("negative"),
|
||||
Self::Reservation => f.write_str("reservation"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
|
||||
pub enum Visibility {
|
||||
/// Visible everywhere (including in other crates).
|
||||
@ -460,6 +491,26 @@ impl<'tcx> Predicate<'tcx> {
|
||||
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
|
||||
self.inner.kind
|
||||
}
|
||||
|
||||
pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
|
||||
let kind = self
|
||||
.inner
|
||||
.kind
|
||||
.map_bound(|kind| match kind {
|
||||
PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
|
||||
Some(PredicateKind::Trait(TraitPredicate {
|
||||
trait_ref,
|
||||
constness,
|
||||
polarity: polarity.flip()?,
|
||||
}))
|
||||
}
|
||||
|
||||
_ => None,
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
Some(tcx.mk_predicate(kind))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
||||
@ -655,6 +706,8 @@ pub struct TraitPredicate<'tcx> {
|
||||
pub trait_ref: TraitRef<'tcx>,
|
||||
|
||||
pub constness: BoundConstness,
|
||||
|
||||
pub polarity: ImplPolarity,
|
||||
}
|
||||
|
||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||
@ -789,7 +842,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.value
|
||||
.map_bound(|trait_ref| {
|
||||
PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: self.constness })
|
||||
PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: self.constness,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
})
|
||||
.to_predicate(tcx)
|
||||
}
|
||||
|
@ -797,6 +797,20 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::ImplPolarity {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
a: ty::ImplPolarity,
|
||||
b: ty::ImplPolarity,
|
||||
) -> RelateResult<'tcx, ty::ImplPolarity> {
|
||||
if a != b {
|
||||
Err(TypeError::PolarityMismatch(expected_found(relation, a, b)))
|
||||
} else {
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
@ -806,6 +820,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
|
||||
Ok(ty::TraitPredicate {
|
||||
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
|
||||
constness: relation.relate(a.constness, b.constness)?,
|
||||
polarity: relation.relate(a.polarity, b.polarity)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ impl fmt::Debug for ty::TraitPredicate<'tcx> {
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness {
|
||||
write!(f, "~const ")?;
|
||||
}
|
||||
write!(f, "TraitPredicate({:?})", self.trait_ref)
|
||||
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,8 +365,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
|
||||
type Lifted = ty::TraitPredicate<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
|
||||
tcx.lift(self.trait_ref)
|
||||
.map(|trait_ref| ty::TraitPredicate { trait_ref, constness: self.constness })
|
||||
tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: self.constness,
|
||||
polarity: self.polarity,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,6 +594,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
|
||||
Some(match self {
|
||||
Mismatch => Mismatch,
|
||||
ConstnessMismatch(x) => ConstnessMismatch(x),
|
||||
PolarityMismatch(x) => PolarityMismatch(x),
|
||||
UnsafetyMismatch(x) => UnsafetyMismatch(x),
|
||||
AbiMismatch(x) => AbiMismatch(x),
|
||||
Mutability => Mutability,
|
||||
|
@ -882,6 +882,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
||||
self.map_bound(|trait_ref| ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -124,9 +124,11 @@ where
|
||||
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
match predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _ }) => {
|
||||
self.visit_trait(trait_ref)
|
||||
}
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: _,
|
||||
polarity: _,
|
||||
}) => self.visit_trait(trait_ref),
|
||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
||||
ty.visit_with(self)?;
|
||||
self.visit_projection_ty(projection_ty)
|
||||
|
@ -286,6 +286,8 @@ impl AutoTraitFinder<'tcx> {
|
||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
// Auto traits are positive
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}));
|
||||
|
||||
let computed_preds = param_env.caller_bounds().iter();
|
||||
|
@ -804,6 +804,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot(
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -44,6 +44,7 @@ pub(crate) fn update<'tcx, T>(
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: predicate.constness,
|
||||
polarity: predicate.polarity,
|
||||
})
|
||||
})
|
||||
.to_predicate(infcx.tcx),
|
||||
|
@ -915,6 +915,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
substs: self.tcx().mk_substs_trait(ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}));
|
||||
copy_obligation.recursion_depth = depth + 1;
|
||||
self.assemble_candidates_from_impls(©_obligation, &mut copy_candidates);
|
||||
|
@ -531,6 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
|
||||
},
|
||||
constness: t.constness,
|
||||
polarity: t.polarity,
|
||||
}));
|
||||
let obl = Obligation::new(
|
||||
o.cause.clone(),
|
||||
|
@ -382,6 +382,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: _,
|
||||
}) => {
|
||||
if !matches!(
|
||||
trait_predicate_kind(tcx, predicate),
|
||||
@ -413,6 +414,7 @@ fn trait_predicate_kind<'tcx>(
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: _,
|
||||
}) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
|
||||
ty::PredicateKind::Trait(_)
|
||||
| ty::PredicateKind::RegionOutlives(_)
|
||||
|
Loading…
x
Reference in New Issue
Block a user