diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 1cde4802a40b0..fe6db395a8e87 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -124,7 +124,7 @@ impl Elaborator<'tcx> { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(data, _) => { + ty::PredicateKind::Trait(data, _, _) => { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index e632f29e672c0..392e1b5d09399 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { let predicates = cx.tcx.explicit_predicates_of(item.def_id); for &(predicate, span) in predicates.predicates { let trait_predicate = match predicate.kind().skip_binder() { - Trait(trait_predicate, _constness) => trait_predicate, + Trait(trait_predicate, _constness, _polarity) => trait_predicate, _ => continue, }; let def_id = trait_predicate.trait_ref.def_id; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 67946dfb292a6..26cf8781e367a 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { let mut has_emitted = false; for &(predicate, _) in cx.tcx.explicit_item_bounds(def) { // We only look at the `DefId`, so it is safe to skip the binder here. - if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) = + if let ty::PredicateKind::Trait(ref poly_trait_predicate, _, _) = predicate.kind().skip_binder() { let def_id = poly_trait_predicate.trait_ref.def_id; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a2b17e97c29d9..1f97a761a66d2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2127,7 +2127,7 @@ impl<'tcx> TyCtxt<'tcx> { let generic_predicates = self.super_predicates_of(trait_did); for (predicate, _) in generic_predicates.predicates { - if let ty::PredicateKind::Trait(data, _) = predicate.kind().skip_binder() { + if let ty::PredicateKind::Trait(data, _, _) = predicate.kind().skip_binder() { if set.insert(data.def_id()) { stack.push(data.def_id()); } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 9faa172a4973f..9efa8d216c0fa 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -216,7 +216,7 @@ impl FlagComputation { fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) { match atom { - ty::PredicateKind::Trait(trait_pred, _constness) => { + ty::PredicateKind::Trait(trait_pred, _constness, _polarity) => { self.add_substs(trait_pred.trait_ref.substs); } ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 94e325e9e8784..3da76095131d8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -151,7 +151,18 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec>, } -#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + TyEncodable, + TyDecodable, + HashStable, + TypeFoldable, + Debug +)] pub enum ImplPolarity { /// `impl Trait for Type` Positive, @@ -371,7 +382,7 @@ impl ty::EarlyBoundRegion { } } -#[derive(Debug)] +#[derive(Debug, Clone)] crate struct PredicateInner<'tcx> { kind: Binder<'tcx, PredicateKind<'tcx>>, flags: TypeFlags, @@ -408,6 +419,26 @@ impl<'tcx> Predicate<'tcx> { pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> { self.inner.kind } + + /// hi oli + pub fn negate_trait(mut self, tcx: TyCtxt<'tcx>) -> Option { + let mut inner = self.inner.clone(); + + if !matches!(inner.kind.skip_binder(), PredicateKind::Trait(..)) { + return None; + } + + inner.kind = inner.kind.map_bound(|kind| match kind { + PredicateKind::Trait(trait_pred, constness, ImplPolarity::Positive) => { + PredicateKind::Trait(trait_pred, constness, ImplPolarity::Negative) + } + _ => bug!(), + }); + + self.inner = tcx.arena.alloc(inner); + + Some(self) + } } impl<'a, 'tcx> HashStable> for Predicate<'tcx> { @@ -435,7 +466,7 @@ pub enum PredicateKind<'tcx> { /// A trait predicate will have `Constness::Const` if it originates /// from a bound on a `const fn` without the `?const` opt-out (e.g., /// `const fn foobar() {}`). - Trait(TraitPredicate<'tcx>, Constness), + Trait(TraitPredicate<'tcx>, Constness, ImplPolarity), /// `where 'a: 'b` RegionOutlives(RegionOutlivesPredicate<'tcx>), @@ -591,6 +622,7 @@ impl<'tcx> Predicate<'tcx> { #[derive(HashStable, TypeFoldable)] pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx>, + pub polarity: ImplPolarity, } pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; @@ -724,8 +756,12 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::Trait(ty::TraitPredicate { trait_ref: self.value }, self.constness) - .to_predicate(tcx) + PredicateKind::Trait( + ty::TraitPredicate { trait_ref: self.value, polarity: self.polarity }, + self.constness, + self.polarity, + ) + .to_predicate(tcx) } } @@ -733,7 +769,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.value .map_bound(|trait_ref| { - PredicateKind::Trait(ty::TraitPredicate { trait_ref }, self.constness) + PredicateKind::Trait( + ty::TraitPredicate { trait_ref, polarity: self.polarity }, + self.constness, + self.polarity, + ) }) .to_predicate(tcx) } @@ -741,7 +781,9 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.value.map_bound(|value| PredicateKind::Trait(value, self.constness)).to_predicate(tcx) + self.value + .map_bound(|value| PredicateKind::Trait(value, self.constness, self.polarity)) + .to_predicate(tcx) } } @@ -767,8 +809,8 @@ impl<'tcx> Predicate<'tcx> { pub fn to_opt_poly_trait_ref(self) -> Option>> { let predicate = self.kind(); match predicate.skip_binder() { - PredicateKind::Trait(t, constness) => { - Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) }) + PredicateKind::Trait(t, constness, polarity) => { + Some(ConstnessAnd { constness, polarity, value: predicate.rebind(t.trait_ref) }) } PredicateKind::Projection(..) | PredicateKind::Subtype(..) @@ -1234,6 +1276,7 @@ impl<'tcx> ParamEnv<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)] pub struct ConstnessAnd { pub constness: Constness, + pub polarity: ImplPolarity, pub value: T, } @@ -1242,7 +1285,7 @@ pub struct ConstnessAnd { pub trait WithConstness: Sized { #[inline] fn with_constness(self, constness: Constness) -> ConstnessAnd { - ConstnessAnd { constness, value: self } + ConstnessAnd { constness, polarity: ImplPolarity::Positive, value: self } } #[inline] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f514278a11c93..5ecdfc44bed4f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -630,7 +630,8 @@ pub trait PrettyPrinter<'tcx>: for (predicate, _) in bounds { let predicate = predicate.subst(self.tcx(), substs); let bound_predicate = predicate.kind(); - if let ty::PredicateKind::Trait(pred, _) = bound_predicate.skip_binder() { + if let ty::PredicateKind::Trait(pred, _, _) = bound_predicate.skip_binder() + { let trait_ref = bound_predicate.rebind(pred.trait_ref); // Don't print +Sized, but rather +?Sized if absent. if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { @@ -2191,7 +2192,7 @@ define_print_and_forward_display! { ty::PredicateKind<'tcx> { match *self { - ty::PredicateKind::Trait(ref data, constness) => { + ty::PredicateKind::Trait(ref data, constness, _polarity) => { if let hir::Constness::Const = constness { p!("const "); } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index b6f93c9bd59e7..2408aa88fe471 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -735,7 +735,8 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { a: ty::TraitPredicate<'tcx>, b: ty::TraitPredicate<'tcx>, ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> { - Ok(ty::TraitPredicate { trait_ref: relation.relate(a.trait_ref, b.trait_ref)? }) + // TODO(yaahc): double check this is fine + Ok(ty::TraitPredicate { trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, polarity: ty::ImplPolarity::Positive }) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7290c41d615df..51668d429bb9b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -174,7 +174,7 @@ impl fmt::Debug for ty::Predicate<'tcx> { impl fmt::Debug for ty::PredicateKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - ty::PredicateKind::Trait(ref a, constness) => { + ty::PredicateKind::Trait(ref a, constness, _polarity) => { if let hir::Constness::Const = constness { write!(f, "const ")?; } @@ -366,7 +366,8 @@ 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> { - tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate { trait_ref }) + // TODO(yaahc): double check this is fine + tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive }) } } @@ -419,8 +420,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { type Lifted = ty::PredicateKind<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { match self { - ty::PredicateKind::Trait(data, constness) => { - tcx.lift(data).map(|data| ty::PredicateKind::Trait(data, constness)) + ty::PredicateKind::Trait(data, constness, polarity) => { + tcx.lift(data).map(|data| ty::PredicateKind::Trait(data, constness, polarity)) } ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype), ty::PredicateKind::RegionOutlives(data) => { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f35ecb4d3cd58..49e81fe2c8469 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -877,7 +877,8 @@ impl<'tcx> PolyTraitRef<'tcx> { } pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { - self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref }) + // TODO(yaahc): double check this is fine + self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive }) } } diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index d27fcb2f26f19..72840f314e66f 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts}; use rustc_middle::ty::{ - self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPredicate, Ty, - TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, + self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ImplPolarity, RegionVid, + ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, }; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; @@ -2718,8 +2718,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) { self.prove_predicates( Some(ty::PredicateKind::Trait( - ty::TraitPredicate { trait_ref }, + ty::TraitPredicate { trait_ref, polarity: ImplPolarity::Positive }, hir::Constness::NotConst, + ImplPolarity::Positive, )), locations, category, diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 41d9d0d04b50c..3765ea53e4e05 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -424,7 +424,7 @@ impl Validator<'mir, 'tcx> { ty::PredicateKind::Subtype(_) => { bug!("subtype predicate on function: {:#?}", predicate) } - ty::PredicateKind::Trait(pred, _constness) => { + ty::PredicateKind::Trait(pred, _constness, _polarity) => { if Some(pred.def_id()) == tcx.lang_items().sized_trait() { continue; } @@ -826,12 +826,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { } let trait_ref = TraitRef::from_method(tcx, trait_id, substs); + // TODO(yaahc): double check let obligation = Obligation::new( ObligationCause::dummy(), param_env, Binder::bind( TraitPredicate { trait_ref: TraitRef::from_method(tcx, trait_id, substs), + polarity: ty::ImplPolarity::Positive, }, tcx, ), diff --git a/compiler/rustc_mir/src/transform/function_item_references.rs b/compiler/rustc_mir/src/transform/function_item_references.rs index 8d02ac6d9b774..c1f5603cd3fc3 100644 --- a/compiler/rustc_mir/src/transform/function_item_references.rs +++ b/compiler/rustc_mir/src/transform/function_item_references.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { /// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type. fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option> { - if let ty::PredicateKind::Trait(predicate, _) = bound { + if let ty::PredicateKind::Trait(predicate, _, _) = bound { if self.tcx.is_diagnostic_item(sym::pointer_trait, predicate.def_id()) { Some(predicate.trait_ref.self_ty()) } else { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e64f12ef48f22..12b647226cb29 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -122,7 +122,7 @@ where fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow { match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => { + ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, .. }, _, _) => { self.visit_trait(trait_ref) } ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => { diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index efa5d7e7b1139..8428ebe3bc2b8 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2666,7 +2666,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(data, _) => { + ty::PredicateKind::Trait(data, _, _) => { // The order here needs to match what we would get from `subst_supertrait` let pred_bound_vars = bound_predicate.bound_vars(); let mut all_bound_vars = bound_vars.clone(); diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index f54eb0914a5a7..87306425f97b3 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -280,11 +280,13 @@ impl AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); + // TODO(yaahc): double check this is fine predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: trait_did, substs: infcx.tcx.mk_substs_trait(ty, &[]), }, + polarity: ty::ImplPolarity::Positive, })); let computed_preds = param_env.caller_bounds().iter(); @@ -415,8 +417,8 @@ impl AutoTraitFinder<'tcx> { let mut should_add_new = true; user_computed_preds.retain(|&old_pred| { if let ( - ty::PredicateKind::Trait(new_trait, _), - ty::PredicateKind::Trait(old_trait, _), + ty::PredicateKind::Trait(new_trait, _, _), + ty::PredicateKind::Trait(old_trait, _, _), ) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder()) { if new_trait.def_id() == old_trait.def_id() { @@ -638,7 +640,7 @@ impl AutoTraitFinder<'tcx> { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(p, _) => { + ty::PredicateKind::Trait(p, _, _) => { // Add this to `predicates` so that we end up calling `select` // with it. If this predicate ends up being unimplemented, // then `evaluate_predicates` will handle adding it the `ParamEnv` diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9bb4af16a8f53..5c4f6291a6566 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -5,10 +5,12 @@ //! [trait-specialization]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html use crate::infer::{CombinedSnapshot, InferOk, TyCtxtInferExt}; +use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::SkipLeakCheck; use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionContext}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_infer::traits::PredicateObligation; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, fast_reject, Ty, TyCtxt}; @@ -184,6 +186,15 @@ fn overlap_within_probe( debug!("overlap: unification check succeeded"); + let negate_obligation = |obligation: &PredicateObligation<'tcx>, tcx: TyCtxt<'tcx>| { + let predicate = obligation.predicate.negate_trait(tcx); + let mut obligation = obligation.clone(); + predicate.map(|predicate| { + obligation.predicate = predicate; + obligation + }) + }; + // Are any of the obligations unsatisfiable? If so, no overlap. let infcx = selcx.infcx(); let opt_failing_obligation = a_impl_header @@ -199,7 +210,17 @@ fn overlap_within_probe( predicate: p, }) .chain(obligations) - .find(|o| !selcx.predicate_may_hold_fatal(o)); + .find(|o| { + if let Some(o_neg) = negate_obligation(o, infcx.tcx) { + // given o = `T: Trait` this produces `T: !Trait` + if infcx.predicate_must_hold_considering_regions(&o_neg) { + // we can prove `T: !Trait` is true based on the impls we see + return true; + } + } + + !selcx.predicate_may_hold_fatal(o) + }); // FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported // to the canonical trait query form, `infcx.predicate_may_hold`, once // the new system supports intercrate mode (which coherence needs). diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index db396356d6711..f6d65022906dc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -259,7 +259,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(trait_predicate, _) => { + ty::PredicateKind::Trait(trait_predicate, _, _) => { let trait_predicate = bound_predicate.rebind(trait_predicate); let trait_predicate = self.resolve_vars_if_possible(trait_predicate); @@ -1106,7 +1106,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // FIXME: It should be possible to deal with `ForAll` in a cleaner way. let bound_error = error.kind(); let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) { - (ty::PredicateKind::Trait(..), ty::PredicateKind::Trait(error, _)) => { + (ty::PredicateKind::Trait(..), ty::PredicateKind::Trait(error, _, _)) => { (cond, bound_error.rebind(error)) } _ => { @@ -1117,7 +1117,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) { let bound_predicate = obligation.predicate.kind(); - if let ty::PredicateKind::Trait(implication, _) = bound_predicate.skip_binder() { + if let ty::PredicateKind::Trait(implication, _, _) = bound_predicate.skip_binder() { let error = error.to_poly_trait_ref(); let implication = bound_predicate.rebind(implication.trait_ref); // FIXME: I'm just not taking associated types at all here. @@ -1493,7 +1493,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { let bound_predicate = predicate.kind(); let mut err = match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(data, _) => { + ty::PredicateKind::Trait(data, _, _) => { let trait_ref = bound_predicate.rebind(data.trait_ref); debug!("trait_ref {:?}", trait_ref); @@ -1758,7 +1758,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { match (obligation.predicate.kind().skip_binder(), obligation.cause.code.peel_derives()) { ( - ty::PredicateKind::Trait(pred, _), + ty::PredicateKind::Trait(pred, _, _), &ObligationCauseCode::BindingObligation(item_def_id, span), ) => (pred, item_def_id, span), _ => return, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 8bbd2da537513..d58b7f2d00d9e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1383,7 +1383,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // bound was introduced. At least one generator should be present for this diagnostic to be // modified. let (mut trait_ref, mut target_ty) = match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(p, _) => (Some(p.trait_ref), Some(p.self_ty())), + ty::PredicateKind::Trait(p, _, _) => (Some(p.trait_ref), Some(p.self_ty())), _ => (None, None), }; let mut generator = None; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 120680092baaa..62ff8fd718344 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -353,7 +353,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { // Evaluation will discard candidates using the leak check. // This means we need to pass it the bound version of our // predicate. - ty::PredicateKind::Trait(trait_ref, _constness) => { + ty::PredicateKind::Trait(trait_ref, _constness, _polarity) => { let trait_obligation = obligation.with(binder.rebind(trait_ref)); self.process_trait_obligation( @@ -388,7 +388,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } }, Some(pred) => match pred { - ty::PredicateKind::Trait(data, _) => { + ty::PredicateKind::Trait(data, _, _) => { let trait_obligation = obligation.with(Binder::dummy(data)); self.process_trait_obligation( diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index d5e1bd3f9ea2e..081c2e446ceda 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -280,7 +280,7 @@ fn predicate_references_self( let self_ty = tcx.types.self_param; let has_self_ty = |arg: &GenericArg<'_>| arg.walk().any(|arg| arg == self_ty.into()); match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ref data, _) => { + ty::PredicateKind::Trait(ref data, _, _) => { // In the case of a trait predicate, we can skip the "self" type. if data.trait_ref.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None } } @@ -331,7 +331,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let predicates = predicates.instantiate_identity(tcx).predicates; elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| { match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ref trait_pred, _) => { + ty::PredicateKind::Trait(ref trait_pred, _, _) => { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } ty::PredicateKind::Projection(..) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index de538c62c5e39..481c2241950a9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -15,7 +15,8 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { // `&T`, accounts for about 60% percentage of the predicates // we have to prove. No need to canonicalize and all that for // such cases. - if let ty::PredicateKind::Trait(trait_ref, _) = key.value.predicate.kind().skip_binder() { + if let ty::PredicateKind::Trait(trait_ref, _, _) = key.value.predicate.kind().skip_binder() + { if let Some(sized_def_id) = tcx.lang_items().sized_trait() { if trait_ref.def_id() == sized_def_id { if trait_ref.self_ty().is_trivially_sized(tcx) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ea5eb2b68667f..b47724fdc84ec 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -40,6 +40,7 @@ use rustc_middle::ty::fast_reject; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef}; +use rustc_middle::ty::ImplPolarity; use rustc_middle::ty::{self, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_span::symbol::sym; @@ -454,13 +455,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let result = ensure_sufficient_stack(|| { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(t, _) => { + ty::PredicateKind::Trait(t, _, ImplPolarity::Positive) => { let t = bound_predicate.rebind(t); debug_assert!(!t.has_escaping_bound_vars()); let obligation = obligation.with(t); self.evaluate_trait_predicate_recursively(previous_stack, obligation) } + ty::PredicateKind::Trait(_t, _, ImplPolarity::Negative) => Ok(EvaluatedToErr), + ty::PredicateKind::Trait(_t, _, ImplPolarity::Reservation) => todo!("yaahc"), + ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); // Does this code ever run? @@ -865,7 +869,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool { let result = match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()), + ty::PredicateKind::Trait(ref data, _, _) => self.tcx().trait_is_auto(data.def_id()), _ => false, }; debug!(?predicate, ?result, "coinductive_predicate"); @@ -1047,6 +1051,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(Some(candidate)) } + // fn filter_positive_and_reservation_impls( + // &mut self, + // _candidate: SelectionCandidate<'tcx>, + // ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + // todo!("yaahc") + // } + fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option { debug!("is_knowable(intercrate={:?})", self.intercrate); @@ -1205,7 +1216,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .enumerate() .filter_map(|(idx, bound)| { let bound_predicate = bound.kind(); - if let ty::PredicateKind::Trait(pred, _) = bound_predicate.skip_binder() { + if let ty::PredicateKind::Trait(pred, _, _) = bound_predicate.skip_binder() { let bound = bound_predicate.rebind(pred.trait_ref); if self.infcx.probe(|_| { match self.match_normalize_trait_ref( diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f592cf1cd249d..145468c42efda 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -107,7 +107,7 @@ pub fn predicate_obligations<'a, 'tcx>( // It's ok to skip the binder here because wf code is prepared for it match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(t, _) => { + ty::PredicateKind::Trait(t, _, _) => { wf.compute_trait_ref(&t.trait_ref, Elaborate::None); } ty::PredicateKind::RegionOutlives(..) => {} @@ -225,7 +225,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( } } } - ty::PredicateKind::Trait(pred, _) => { + ty::PredicateKind::Trait(pred, _, _) => { // An associated item obligation born out of the `trait` failed to be met. An example // can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`. debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 39890fd5b0574..6d4855c3ecd36 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -87,7 +87,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment { chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner))) } - ty::PredicateKind::Trait(predicate, _) => chalk_ir::DomainGoal::FromEnv( + ty::PredicateKind::Trait(predicate, _, _) => chalk_ir::DomainGoal::FromEnv( chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)), ), ty::PredicateKind::RegionOutlives(predicate) => chalk_ir::DomainGoal::Holds( @@ -137,7 +137,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi collect_bound_vars(interner, interner.tcx, self.kind()); let value = match predicate { - ty::PredicateKind::Trait(predicate, _) => { + ty::PredicateKind::Trait(predicate, _, _) => { chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)), )) @@ -569,7 +569,7 @@ impl<'tcx> LowerInto<'tcx, Option { + ty::PredicateKind::Trait(predicate, _, _) => { Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner))) } ty::PredicateKind::RegionOutlives(predicate) => { @@ -702,7 +702,7 @@ impl<'tcx> LowerInto<'tcx, Option Some(chalk_ir::Binders::new( + ty::PredicateKind::Trait(predicate, _, _) => Some(chalk_ir::Binders::new( binders, chalk_solve::rust_ir::InlineBound::TraitBound( predicate.trait_ref.lower_into(interner), diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index ef1956210448d..1a6d2c09c5ab7 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1293,7 +1293,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(pred, _) => { + ty::PredicateKind::Trait(pred, _, _) => { let pred = bound_predicate.rebind(pred); associated_types.entry(span).or_default().extend( tcx.associated_items(pred.def_id()) diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index d056f2c90f988..92001ced2d6be 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -603,15 +603,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut suggest_box = !impl_trait_ret_ty.obligations.is_empty(); for o in impl_trait_ret_ty.obligations { match o.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(t, constness) => { + ty::PredicateKind::Trait(t, constness, polarity) => { let pred = ty::PredicateKind::Trait( ty::TraitPredicate { trait_ref: ty::TraitRef { def_id: t.def_id(), substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), }, + polarity, }, constness, + polarity, ); let obl = Obligation::new( o.cause.clone(), diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 236fec94bdba7..3b29fb48f38be 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -586,7 +586,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug!("coerce_unsized resolve step: {:?}", obligation); let bound_predicate = obligation.predicate.kind(); let trait_pred = match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(trait_pred, _) + ty::PredicateKind::Trait(trait_pred, _, _) if traits.contains(&trait_pred.def_id()) => { if unsize_did == trait_pred.def_id() { diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index de6336b254b3f..6d0b58f4fdb74 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -229,7 +229,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( let predicate = predicate.kind(); let p = p.kind(); match (predicate.skip_binder(), p.skip_binder()) { - (ty::PredicateKind::Trait(a, _), ty::PredicateKind::Trait(b, _)) => { + (ty::PredicateKind::Trait(a, _, _), ty::PredicateKind::Trait(b, _, _)) => { relator.relate(predicate.rebind(a), p.rebind(b)).is_ok() } (ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 96569ae0e7720..c38fd79740c58 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_predicate.rebind(data).required_poly_trait_ref(self.tcx), obligation, )), - ty::PredicateKind::Trait(data, _) => { + ty::PredicateKind::Trait(data, _, _) => { Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation)) } ty::PredicateKind::Subtype(..) => None, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 49aea19c8d099..be3fa7661df4d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -903,7 +903,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - if let ty::PredicateKind::Trait(predicate, _) = + if let ty::PredicateKind::Trait(predicate, _, _) = error.obligation.predicate.kind().skip_binder() { // Collect the argument position for all arguments that could have caused this @@ -954,7 +954,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::Path(qpath) = &path.kind { if let hir::QPath::Resolved(_, path) = &qpath { for error in errors { - if let ty::PredicateKind::Trait(predicate, _) = + if let ty::PredicateKind::Trait(predicate, _, _) = error.obligation.predicate.kind().skip_binder() { // If any of the type arguments in this path segment caused the diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 4da4835f7cfbb..3b888f2ddb5d3 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -201,7 +201,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { predicates: tcx.arena.alloc_from_iter( self.param_env.caller_bounds().iter().filter_map(|predicate| { match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(data, _) if data.self_ty().is_param(index) => { + ty::PredicateKind::Trait(data, _, _) if data.self_ty().is_param(index) => { // HACK(eddyb) should get the original `Span`. let span = tcx.def_span(def_id); Some((predicate, span)) diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index f546a0d896354..44f7124b43808 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -496,7 +496,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied()) // We don't care about regions here. .filter_map(|obligation| match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => { + ty::PredicateKind::Trait(trait_pred, _, _) + if trait_pred.def_id() == sized_def_id => + { let span = iter::zip(&predicates.predicates, &predicates.spans) .find_map( |(p, span)| { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 440e0f4e1a2ac..02b5296a25444 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -832,7 +832,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(trait_predicate, _) => { + ty::PredicateKind::Trait(trait_predicate, _, _) => { match *trait_predicate.trait_ref.self_ty().kind() { ty::Param(p) if p == param_ty => { Some(bound_predicate.rebind(trait_predicate.trait_ref)) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 16382c7e7a4bd..9d43e940c50a1 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -683,7 +683,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut collect_type_param_suggestions = |self_ty: Ty<'tcx>, parent_pred: &ty::Predicate<'tcx>, obligation: &str| { // We don't care about regions here, so it's fine to skip the binder here. - if let (ty::Param(_), ty::PredicateKind::Trait(p, _)) = + if let (ty::Param(_), ty::PredicateKind::Trait(p, _, _)) = (self_ty.kind(), parent_pred.kind().skip_binder()) { if let ty::Adt(def, _) = p.trait_ref.self_ty().kind() { @@ -763,7 +763,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_span_label(projection_ty.self_ty(), &obligation, &quiet); Some((obligation, projection_ty.self_ty())) } - ty::PredicateKind::Trait(poly_trait_ref, _) => { + ty::PredicateKind::Trait(poly_trait_ref, _, _) => { let p = poly_trait_ref.trait_ref; let self_ty = p.self_ty(); let path = p.print_only_trait_path(); @@ -1194,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match p.kind().skip_binder() { // Hide traits if they are present in predicates as they can be fixed without // having to implement them. - ty::PredicateKind::Trait(t, _) => t.def_id() == info.def_id, + ty::PredicateKind::Trait(t, _, _) => t.def_id() == info.def_id, ty::PredicateKind::Projection(p) => { p.projection_ty.item_def_id == info.def_id } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index ad7853b7cd0f1..ee5e46d07a757 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -886,7 +886,7 @@ fn bounds_from_generic_predicates<'tcx>( debug!("predicate {:?}", predicate); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(trait_predicate, _) => { + ty::PredicateKind::Trait(trait_predicate, _, _) => { let entry = types.entry(trait_predicate.self_ty()).or_default(); let def_id = trait_predicate.def_id(); if Some(def_id) != tcx.lang_items().sized_trait() { diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 0528f8812f920..22fce6ebcb299 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -619,7 +619,7 @@ fn type_param_predicates( ) .into_iter() .filter(|(predicate, _)| match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(data, _) => data.self_ty().is_param(index), + ty::PredicateKind::Trait(data, _, _) => data.self_ty().is_param(index), _ => false, }), ); @@ -1153,7 +1153,7 @@ fn super_predicates_that_define_assoc_type( // which will, in turn, reach indirect supertraits. for &(pred, span) in superbounds { debug!("superbound: {:?}", pred); - if let ty::PredicateKind::Trait(bound, _) = pred.kind().skip_binder() { + if let ty::PredicateKind::Trait(bound, _, _) = pred.kind().skip_binder() { tcx.at(span).super_predicates_of(bound.def_id()); } } @@ -2331,7 +2331,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat .iter() .copied() .filter(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Trait(tr, _) => !is_assoc_item_ty(tr.self_ty()), + ty::PredicateKind::Trait(tr, _, _) => !is_assoc_item_ty(tr.self_ty()), ty::PredicateKind::Projection(proj) => { !is_assoc_item_ty(proj.projection_ty.self_ty()) } diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs index a5b36445aae2e..706bdb4fa5736 100644 --- a/compiler/rustc_typeck/src/collect/item_bounds.rs +++ b/compiler/rustc_typeck/src/collect/item_bounds.rs @@ -38,7 +38,7 @@ fn associated_type_bounds<'tcx>( let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { match pred.kind().skip_binder() { - ty::PredicateKind::Trait(tr, _) => tr.self_ty() == item_ty, + ty::PredicateKind::Trait(tr, _, _) => tr.self_ty() == item_ty, ty::PredicateKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty, ty::PredicateKind::TypeOutlives(outlives) => outlives.0 == item_ty, _ => false, diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index 505d9a59d9c2f..cfa0ce948105e 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -366,7 +366,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc _ if predicate.is_global() => (), // We allow specializing on explicitly marked traits with no associated // items. - ty::PredicateKind::Trait(pred, hir::Constness::NotConst) => { + ty::PredicateKind::Trait(pred, hir::Constness::NotConst, _) => { if !matches!( trait_predicate_kind(tcx, predicate), Some(TraitSpecializationKind::Marker) @@ -394,10 +394,12 @@ fn trait_predicate_kind<'tcx>( predicate: ty::Predicate<'tcx>, ) -> Option { match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(pred, hir::Constness::NotConst) => { + ty::PredicateKind::Trait(pred, hir::Constness::NotConst, ty::ImplPolarity::Positive) => { Some(tcx.trait_def(pred.def_id()).specialization_kind) } - ty::PredicateKind::Trait(_, hir::Constness::Const) + ty::PredicateKind::Trait(_, hir::Constness::Const, _) + | ty::PredicateKind::Trait(_, _, ty::ImplPolarity::Negative) + | ty::PredicateKind::Trait(_, _, ty::ImplPolarity::Reservation) | ty::PredicateKind::RegionOutlives(_) | ty::PredicateKind::TypeOutlives(_) | ty::PredicateKind::Projection(_) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 35ff57f85a562..0355eddb18f92 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -316,7 +316,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { let bound_predicate = pred.kind(); let tcx = self.cx.tcx; let regions = match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(poly_trait_pred, _) => { + ty::PredicateKind::Trait(poly_trait_pred, _, _) => { tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_trait_pred)) } ty::PredicateKind::Projection(poly_proj_pred) => { @@ -465,7 +465,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .filter(|p| { !orig_bounds.contains(p) || match p.kind().skip_binder() { - ty::PredicateKind::Trait(pred, _) => pred.def_id() == sized_trait, + ty::PredicateKind::Trait(pred, _, _) => pred.def_id() == sized_trait, _ => false, } }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 231f13adeb68c..96a298d53d4fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -346,7 +346,7 @@ impl<'a> Clean> for ty::Predicate<'a> { fn clean(&self, cx: &mut DocContext<'_>) -> Option { let bound_predicate = self.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), + ty::PredicateKind::Trait(pred, _, _) => Some(bound_predicate.rebind(pred).clean(cx)), ty::PredicateKind::RegionOutlives(pred) => pred.clean(cx), ty::PredicateKind::TypeOutlives(pred) => pred.clean(cx), ty::PredicateKind::Projection(pred) => Some(pred.clean(cx)), @@ -626,7 +626,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx let param_idx = (|| { let bound_p = p.kind(); match bound_p.skip_binder() { - ty::PredicateKind::Trait(pred, _constness) => { + ty::PredicateKind::Trait(pred, _constness, _polarity) => { if let ty::Param(param) = pred.self_ty().kind() { return Some(param.index); } @@ -1559,7 +1559,7 @@ impl<'tcx> Clean for Ty<'tcx> { .filter_map(|bound| { let bound_predicate = bound.kind(); let trait_ref = match bound_predicate.skip_binder() { - ty::PredicateKind::Trait(tr, _constness) => { + ty::PredicateKind::Trait(tr, _constness, _polarity) => { bound_predicate.rebind(tr.trait_ref) } ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index d4d0a8ce24c7b..567ffb64fb45e 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -129,7 +129,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) .predicates .iter() .filter_map(|(pred, _)| { - if let ty::PredicateKind::Trait(pred, _) = pred.kind().skip_binder() { + if let ty::PredicateKind::Trait(pred, _, _) = pred.kind().skip_binder() { if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None } } else { None diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 04730ace887c9..b7150478371ac 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { cx.tcx.infer_ctxt().enter(|infcx| { for FulfillmentError { obligation, .. } in send_errors { infcx.maybe_note_obligation_cause_for_async_await(db, &obligation); - if let Trait(trait_pred, _) = obligation.predicate.kind().skip_binder() { + if let Trait(trait_pred, _, _) = obligation.predicate.kind().skip_binder() { db.note(&format!( "`{}` doesn't implement `{}`", trait_pred.self_ty(), diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index e33a33e238633..7fd3ef48fc369 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -120,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { .filter_map(|obligation| { // Note that we do not want to deal with qualified predicates here. match obligation.predicate.kind().no_bound_vars() { - Some(ty::PredicateKind::Trait(pred, _)) if pred.def_id() != sized_trait => Some(pred), + Some(ty::PredicateKind::Trait(pred, _, _)) if pred.def_id() != sized_trait => Some(pred), _ => None, } }) diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 1c420a5042721..eae07ac92fb26 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -43,7 +43,7 @@ fn get_trait_predicates_for_trait_id<'tcx>( let mut preds = Vec::new(); for (pred, _) in generics.predicates { if_chain! { - if let PredicateKind::Trait(poly_trait_pred, _) = pred.kind().skip_binder(); + if let PredicateKind::Trait(poly_trait_pred, _, _) = pred.kind().skip_binder(); let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred)); if let Some(trait_def_id) = trait_id; if trait_def_id == trait_pred.trait_ref.def_id; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index a08dcf19e5b51..be456621c4b7f 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -36,7 +36,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<&Ru ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate), ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate), - ty::PredicateKind::Trait(pred, _) => { + ty::PredicateKind::Trait(pred, _, _) => { if Some(pred.def_id()) == tcx.lang_items().sized_trait() { continue; } diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c36e215f184ad..1afdf0bd1919a 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -155,7 +155,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { ty::Tuple(ref substs) => substs.types().any(|ty| is_must_use_ty(cx, ty)), ty::Opaque(ref def_id, _) => { for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) { - if let ty::PredicateKind::Trait(trait_predicate, _) = predicate.kind().skip_binder() { + if let ty::PredicateKind::Trait(trait_predicate, _, _) = predicate.kind().skip_binder() { if must_use_attr(&cx.tcx.get_attrs(trait_predicate.trait_ref.def_id)).is_some() { return true; }