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