Skip to content

Commit 6975afd

Browse files
committed
Add polarity to TraitPredicate
1 parent 72d6606 commit 6975afd

File tree

15 files changed

+105
-12
lines changed

15 files changed

+105
-12
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
9494
Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
9595
trait_ref,
9696
constness: ty::BoundConstness::NotConst,
97+
polarity: ty::ImplPolarity::Positive,
9798
}))),
9899
locations,
99100
category,

compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
825825
Binder::dummy(TraitPredicate {
826826
trait_ref,
827827
constness: ty::BoundConstness::ConstIfConst,
828+
polarity: ty::ImplPolarity::Positive,
828829
}),
829830
);
830831

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ impl Qualif for NeedsNonConstDrop {
137137
ty::Binder::dummy(ty::TraitPredicate {
138138
trait_ref,
139139
constness: ty::BoundConstness::ConstIfConst,
140+
polarity: ty::ImplPolarity::Positive,
140141
}),
141142
);
142143

compiler/rustc_middle/src/ty/error.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl<T> ExpectedFound<T> {
3434
pub enum TypeError<'tcx> {
3535
Mismatch,
3636
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
37+
PolarityMismatch(ExpectedFound<ty::ImplPolarity>),
3738
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
3839
AbiMismatch(ExpectedFound<abi::Abi>),
3940
Mutability,
@@ -104,6 +105,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
104105
ConstnessMismatch(values) => {
105106
write!(f, "expected {} bound, found {} bound", values.expected, values.found)
106107
}
108+
PolarityMismatch(values) => {
109+
write!(f, "expected {} polarity, found {} polarity", values.expected, values.found)
110+
}
107111
UnsafetyMismatch(values) => {
108112
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
109113
}
@@ -212,10 +216,9 @@ impl<'tcx> TypeError<'tcx> {
212216
use self::TypeError::*;
213217
match self {
214218
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
215-
| Mismatch | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
216-
| IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) | TargetFeatureCast(_) => {
217-
false
218-
}
219+
| PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
220+
| ArgumentSorts(..) | Sorts(_) | IntMismatch(_) | FloatMismatch(_)
221+
| VariadicMismatch(_) | TargetFeatureCast(_) => false,
219222

220223
Mutability
221224
| ArgumentMutability(_)

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,18 @@ pub struct ImplHeader<'tcx> {
165165
pub predicates: Vec<Predicate<'tcx>>,
166166
}
167167

168-
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
168+
#[derive(
169+
Copy,
170+
Clone,
171+
PartialEq,
172+
Eq,
173+
Hash,
174+
TyEncodable,
175+
TyDecodable,
176+
HashStable,
177+
Debug,
178+
TypeFoldable
179+
)]
169180
pub enum ImplPolarity {
170181
/// `impl Trait for Type`
171182
Positive,
@@ -178,6 +189,26 @@ pub enum ImplPolarity {
178189
Reservation,
179190
}
180191

192+
impl ImplPolarity {
193+
pub fn flip(&self) -> Option<ImplPolarity> {
194+
match self {
195+
ImplPolarity::Positive => Some(ImplPolarity::Negative),
196+
ImplPolarity::Negative => Some(ImplPolarity::Positive),
197+
ImplPolarity::Reservation => None,
198+
}
199+
}
200+
}
201+
202+
impl fmt::Display for ImplPolarity {
203+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204+
match self {
205+
Self::Positive => f.write_str("positive"),
206+
Self::Negative => f.write_str("negative"),
207+
Self::Reservation => f.write_str("reservation"),
208+
}
209+
}
210+
}
211+
181212
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
182213
pub enum Visibility {
183214
/// Visible everywhere (including in other crates).
@@ -460,6 +491,26 @@ impl<'tcx> Predicate<'tcx> {
460491
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
461492
self.inner.kind
462493
}
494+
495+
pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
496+
let kind = self
497+
.inner
498+
.kind
499+
.map_bound(|kind| match kind {
500+
PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
501+
Some(PredicateKind::Trait(TraitPredicate {
502+
trait_ref,
503+
constness,
504+
polarity: polarity.flip()?,
505+
}))
506+
}
507+
508+
_ => None,
509+
})
510+
.transpose()?;
511+
512+
Some(tcx.mk_predicate(kind))
513+
}
463514
}
464515

465516
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
@@ -655,6 +706,8 @@ pub struct TraitPredicate<'tcx> {
655706
pub trait_ref: TraitRef<'tcx>,
656707

657708
pub constness: BoundConstness,
709+
710+
pub polarity: ImplPolarity,
658711
}
659712

660713
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
@@ -789,7 +842,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
789842
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
790843
self.value
791844
.map_bound(|trait_ref| {
792-
PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: self.constness })
845+
PredicateKind::Trait(ty::TraitPredicate {
846+
trait_ref,
847+
constness: self.constness,
848+
polarity: ty::ImplPolarity::Positive,
849+
})
793850
})
794851
.to_predicate(tcx)
795852
}

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,20 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
797797
}
798798
}
799799

800+
impl<'tcx> Relate<'tcx> for ty::ImplPolarity {
801+
fn relate<R: TypeRelation<'tcx>>(
802+
relation: &mut R,
803+
a: ty::ImplPolarity,
804+
b: ty::ImplPolarity,
805+
) -> RelateResult<'tcx, ty::ImplPolarity> {
806+
if a != b {
807+
Err(TypeError::PolarityMismatch(expected_found(relation, a, b)))
808+
} else {
809+
Ok(a)
810+
}
811+
}
812+
}
813+
800814
impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
801815
fn relate<R: TypeRelation<'tcx>>(
802816
relation: &mut R,
@@ -806,6 +820,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
806820
Ok(ty::TraitPredicate {
807821
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
808822
constness: relation.relate(a.constness, b.constness)?,
823+
polarity: relation.relate(a.polarity, b.polarity)?,
809824
})
810825
}
811826
}

compiler/rustc_middle/src/ty/structural_impls.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ impl fmt::Debug for ty::TraitPredicate<'tcx> {
157157
if let ty::BoundConstness::ConstIfConst = self.constness {
158158
write!(f, "~const ")?;
159159
}
160-
write!(f, "TraitPredicate({:?})", self.trait_ref)
160+
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
161161
}
162162
}
163163

@@ -365,8 +365,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
365365
impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
366366
type Lifted = ty::TraitPredicate<'tcx>;
367367
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
368-
tcx.lift(self.trait_ref)
369-
.map(|trait_ref| ty::TraitPredicate { trait_ref, constness: self.constness })
368+
tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate {
369+
trait_ref,
370+
constness: self.constness,
371+
polarity: self.polarity,
372+
})
370373
}
371374
}
372375

@@ -591,6 +594,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
591594
Some(match self {
592595
Mismatch => Mismatch,
593596
ConstnessMismatch(x) => ConstnessMismatch(x),
597+
PolarityMismatch(x) => PolarityMismatch(x),
594598
UnsafetyMismatch(x) => UnsafetyMismatch(x),
595599
AbiMismatch(x) => AbiMismatch(x),
596600
Mutability => Mutability,

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
882882
self.map_bound(|trait_ref| ty::TraitPredicate {
883883
trait_ref,
884884
constness: ty::BoundConstness::NotConst,
885+
polarity: ty::ImplPolarity::Positive,
885886
})
886887
}
887888
}

compiler/rustc_privacy/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ where
124124

125125
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
126126
match predicate.kind().skip_binder() {
127-
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _ }) => {
128-
self.visit_trait(trait_ref)
129-
}
127+
ty::PredicateKind::Trait(ty::TraitPredicate {
128+
trait_ref,
129+
constness: _,
130+
polarity: _,
131+
}) => self.visit_trait(trait_ref),
130132
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
131133
ty.visit_with(self)?;
132134
self.visit_projection_ty(projection_ty)

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ impl AutoTraitFinder<'tcx> {
286286
substs: infcx.tcx.mk_substs_trait(ty, &[]),
287287
},
288288
constness: ty::BoundConstness::NotConst,
289+
// Auto traits are positive
290+
polarity: ty::ImplPolarity::Positive,
289291
}));
290292

291293
let computed_preds = param_env.caller_bounds().iter();

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot(
804804
ty::Binder::dummy(ty::TraitPredicate {
805805
trait_ref,
806806
constness: ty::BoundConstness::NotConst,
807+
polarity: ty::ImplPolarity::Positive,
807808
}),
808809
);
809810

compiler/rustc_trait_selection/src/traits/relationships.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub(crate) fn update<'tcx, T>(
4444
ty::PredicateKind::Trait(ty::TraitPredicate {
4545
trait_ref,
4646
constness: predicate.constness,
47+
polarity: predicate.polarity,
4748
})
4849
})
4950
.to_predicate(infcx.tcx),

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
915915
substs: self.tcx().mk_substs_trait(ty, &[]),
916916
},
917917
constness: ty::BoundConstness::NotConst,
918+
polarity: ty::ImplPolarity::Positive,
918919
}));
919920
copy_obligation.recursion_depth = depth + 1;
920921
self.assemble_candidates_from_impls(&copy_obligation, &mut copy_candidates);

compiler/rustc_typeck/src/check/_match.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
531531
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
532532
},
533533
constness: t.constness,
534+
polarity: t.polarity,
534535
}));
535536
let obl = Obligation::new(
536537
o.cause.clone(),

compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
382382
ty::PredicateKind::Trait(ty::TraitPredicate {
383383
trait_ref,
384384
constness: ty::BoundConstness::NotConst,
385+
polarity: _,
385386
}) => {
386387
if !matches!(
387388
trait_predicate_kind(tcx, predicate),
@@ -413,6 +414,7 @@ fn trait_predicate_kind<'tcx>(
413414
ty::PredicateKind::Trait(ty::TraitPredicate {
414415
trait_ref,
415416
constness: ty::BoundConstness::NotConst,
417+
polarity: _,
416418
}) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
417419
ty::PredicateKind::Trait(_)
418420
| ty::PredicateKind::RegionOutlives(_)

0 commit comments

Comments
 (0)