From 93856e54eb83cf54287cc16066e11e11579f4d8a Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Tue, 1 Jun 2021 15:11:54 -0700 Subject: [PATCH 1/8] Add NotTrait PredicateKind --- compiler/rustc_infer/src/infer/outlives/mod.rs | 1 + compiler/rustc_infer/src/traits/util.rs | 3 +++ compiler/rustc_lint/src/builtin.rs | 1 + compiler/rustc_middle/src/ty/flags.rs | 3 +++ compiler/rustc_middle/src/ty/mod.rs | 11 +++++++++++ compiler/rustc_middle/src/ty/print/pretty.rs | 3 +++ compiler/rustc_middle/src/ty/structural_impls.rs | 4 ++++ .../src/transform/check_consts/validation.rs | 3 +++ compiler/rustc_trait_selection/src/opaque_types.rs | 1 + .../src/traits/error_reporting/mod.rs | 4 ++++ compiler/rustc_trait_selection/src/traits/fulfill.rs | 7 +++++++ .../rustc_trait_selection/src/traits/object_safety.rs | 6 ++++++ .../rustc_trait_selection/src/traits/select/mod.rs | 4 ++++ compiler/rustc_trait_selection/src/traits/wf.rs | 3 +++ compiler/rustc_traits/src/chalk/lowering.rs | 4 ++++ compiler/rustc_traits/src/implied_outlives_bounds.rs | 1 + .../rustc_traits/src/normalize_erasing_regions.rs | 1 + compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 3 +++ compiler/rustc_typeck/src/check/method/probe.rs | 3 +++ .../src/impl_wf_check/min_specialization.rs | 3 +++ compiler/rustc_typeck/src/outlives/explicit.rs | 2 ++ src/librustdoc/clean/mod.rs | 1 + .../clippy/clippy_utils/src/qualify_min_const_fn.rs | 1 + 23 files changed, 73 insertions(+) diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 07c75d50d91da..25a4d8e7654b6 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -27,6 +27,7 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, + ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { Some(OutlivesBound::RegionSubRegion(r_b, r_a)) } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 1cde4802a40b0..22ec9d4f3362a 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -146,6 +146,9 @@ impl Elaborator<'tcx> { self.stack.extend(obligations); } + ty::PredicateKind::NotTrait(_data, _) => { + todo!("yaahc") + } ty::PredicateKind::WellFormed(..) => { // Currently, we do not elaborate WF predicates, // although we easily could. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e7275374b8915..b8b343de431a5 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1581,6 +1581,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { for &(predicate, span) in predicates.predicates { let predicate_kind_name = match predicate.kind().skip_binder() { Trait(..) => "Trait", + NotTrait(..) => todo!("yaahc"), TypeOutlives(..) | RegionOutlives(..) => "Lifetime", diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 9faa172a4973f..19228ff70e6c9 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -219,6 +219,9 @@ impl FlagComputation { ty::PredicateKind::Trait(trait_pred, _constness) => { self.add_substs(trait_pred.trait_ref.substs); } + ty::PredicateKind::NotTrait(_trait_pred, _constness) => { + todo!("yaahc") + } ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { self.add_region(a); self.add_region(b); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 94e325e9e8784..fec650d56c35a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -437,6 +437,15 @@ pub enum PredicateKind<'tcx> { /// `const fn foobar() {}`). Trait(TraitPredicate<'tcx>, Constness), + /// Corresponds to `where Foo: !Bar`. `Foo` here would be + /// the `Self` type of the trait reference and `A`, `B`, and `C` + /// would be the type parameters. + /// + /// 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() {}`). + NotTrait(TraitPredicate<'tcx>, Constness), + /// `where 'a: 'b` RegionOutlives(RegionOutlivesPredicate<'tcx>), @@ -770,6 +779,7 @@ impl<'tcx> Predicate<'tcx> { PredicateKind::Trait(t, constness) => { Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) }) } + PredicateKind::NotTrait(..) => todo!("yaahc"), PredicateKind::Projection(..) | PredicateKind::Subtype(..) | PredicateKind::RegionOutlives(..) @@ -787,6 +797,7 @@ impl<'tcx> Predicate<'tcx> { let predicate = self.kind(); match predicate.skip_binder() { PredicateKind::TypeOutlives(data) => Some(predicate.rebind(data)), + PredicateKind::NotTrait(..) => todo!("yaahc"), PredicateKind::Trait(..) | PredicateKind::Projection(..) | PredicateKind::Subtype(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f514278a11c93..fdecbc1379524 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2197,6 +2197,9 @@ define_print_and_forward_display! { } p!(print(data)) } + ty::PredicateKind::NotTrait(ref _data, _constness) => { + todo!("yaahc") + } ty::PredicateKind::Subtype(predicate) => p!(print(predicate)), ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)), ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7290c41d615df..bb7400d177d9e 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -180,6 +180,7 @@ impl fmt::Debug for ty::PredicateKind<'tcx> { } a.fmt(f) } + ty::PredicateKind::NotTrait(ref _a, _constness) => todo!("yaahc"), ty::PredicateKind::Subtype(ref pair) => pair.fmt(f), ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f), ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f), @@ -422,6 +423,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { ty::PredicateKind::Trait(data, constness) => { tcx.lift(data).map(|data| ty::PredicateKind::Trait(data, constness)) } + ty::PredicateKind::NotTrait(_data, _constness) => { + todo!("yaahc") + } ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype), ty::PredicateKind::RegionOutlives(data) => { tcx.lift(data).map(ty::PredicateKind::RegionOutlives) diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 41d9d0d04b50c..1ff07702533fe 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -445,6 +445,9 @@ impl Validator<'mir, 'tcx> { _ => continue, } } + ty::PredicateKind::NotTrait(_pred, _constness) => { + todo!("yaahc") + } } } match predicates.parent { diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 163df26e9ffaf..d956fe4057848 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1200,6 +1200,7 @@ crate fn required_region_bounds( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, + ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { // Search for a bound of the form `erased_self_ty // : 'a`, but be wary of something like `for<'a> 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..788865cc9024c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -517,6 +517,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err } + ty::PredicateKind::NotTrait(_trait_predicate, _) => { + todo!("yaahc") + } + ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as // `FulfillmentErrorCode::CodeSubtypeError`, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 120680092baaa..16c9bfb493734 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -362,6 +362,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { &mut pending_obligation.stalled_on, ) } + ty::PredicateKind::NotTrait(_trait_ref, _constness) => { + todo!("yaahc") + } ty::PredicateKind::Projection(data) => { let project_obligation = obligation.with(binder.rebind(data)); @@ -398,6 +401,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ) } + ty::PredicateKind::NotTrait(_data, _) => { + todo!("yaahc") + } + ty::PredicateKind::RegionOutlives(data) => { match infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)) { Ok(()) => ProcessResult::Changed(vec![]), diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index d5e1bd3f9ea2e..7e0aaaa811b85 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -284,6 +284,9 @@ fn predicate_references_self( // 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 } } + ty::PredicateKind::NotTrait(ref _data, _) => { + todo!("yaahc") + } ty::PredicateKind::Projection(ref data) => { // And similarly for projections. This should be redundant with // the previous check because any projection should have a @@ -334,6 +337,9 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { ty::PredicateKind::Trait(ref trait_pred, _) => { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } + ty::PredicateKind::NotTrait(ref _trait_pred, _) => { + todo!("yaahc") + } ty::PredicateKind::Projection(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::RegionOutlives(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ea5eb2b68667f..0cc31958b1952 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -461,6 +461,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.evaluate_trait_predicate_recursively(previous_stack, obligation) } + ty::PredicateKind::NotTrait(_t, _) => { + todo!("yaahc") + } + ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); // Does this code ever run? diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f592cf1cd249d..75628ad4c4fd0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -110,6 +110,9 @@ pub fn predicate_obligations<'a, 'tcx>( ty::PredicateKind::Trait(t, _) => { wf.compute_trait_ref(&t.trait_ref, Elaborate::None); } + ty::PredicateKind::NotTrait(_t, _) => { + todo!("yaahc") + } ty::PredicateKind::RegionOutlives(..) => {} ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 39890fd5b0574..1015c2efb4a12 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -90,6 +90,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment chalk_ir::DomainGoal::FromEnv( chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)), ), + ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => chalk_ir::DomainGoal::Holds( chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { a: predicate.0.lower_into(interner), @@ -142,6 +143,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)), )) } + ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => { chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { @@ -572,6 +574,7 @@ impl<'tcx> LowerInto<'tcx, Option { Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner))) } + ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => { Some(chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { a: predicate.0.lower_into(interner), @@ -708,6 +711,7 @@ impl<'tcx> LowerInto<'tcx, Option todo!("yaahc"), ty::PredicateKind::Projection(predicate) => Some(chalk_ir::Binders::new( binders, chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)), diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 90ba90259c32b..be146da7525c0 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -105,6 +105,7 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![], + ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::WellFormed(arg) => { wf_args.push(arg); vec![] diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 5ad0684fe6ee2..7bf17d7b35b06 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -59,6 +59,7 @@ fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Cop fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool { match p.kind().skip_binder() { ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false, + ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::Trait(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::WellFormed(..) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 96569ae0e7720..6872de4a4dc58 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -796,6 +796,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Trait(data, _) => { Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation)) } + ty::PredicateKind::NotTrait(_data, _) => { + todo!("yaahc") + } ty::PredicateKind::Subtype(..) => None, ty::PredicateKind::RegionOutlives(..) => None, ty::PredicateKind::TypeOutlives(..) => None, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 440e0f4e1a2ac..db805aa2eed51 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -840,6 +840,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { _ => None, } } + ty::PredicateKind::NotTrait(_trait_predicate, _) => { + todo!("yaahc") + } ty::PredicateKind::Subtype(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::RegionOutlives(..) 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..9bf01bf46f76c 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -397,6 +397,9 @@ fn trait_predicate_kind<'tcx>( ty::PredicateKind::Trait(pred, hir::Constness::NotConst) => { Some(tcx.trait_def(pred.def_id()).specialization_kind) } + ty::PredicateKind::NotTrait(_pred, _) => { + todo!("yaahc") + } ty::PredicateKind::Trait(_, hir::Constness::Const) | ty::PredicateKind::RegionOutlives(_) | ty::PredicateKind::TypeOutlives(_) diff --git a/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs index 6e5be87928d59..3182222c67f4b 100644 --- a/compiler/rustc_typeck/src/outlives/explicit.rs +++ b/compiler/rustc_typeck/src/outlives/explicit.rs @@ -50,6 +50,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ) } + ty::PredicateKind::NotTrait(..) => todo!("yaahc"), + ty::PredicateKind::Trait(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::WellFormed(..) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 231f13adeb68c..dbfa20f090f9e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -347,6 +347,7 @@ impl<'a> Clean> for ty::Predicate<'a> { let bound_predicate = self.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)), + ty::PredicateKind::NotTrait(_pred, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(pred) => pred.clean(cx), ty::PredicateKind::TypeOutlives(pred) => pred.clean(cx), ty::PredicateKind::Projection(pred) => Some(pred.clean(cx)), 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..45a6eca906a53 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 @@ -57,6 +57,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<&Ru _ => continue, } }, + ty::PredicateKind::NotTrait(_pred, _) => todo!("yaahc"), } } match predicates.parent { From 6d508f804b090bfa75b64537ca759f6979f8a056 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Mon, 12 Jul 2021 11:39:45 -0700 Subject: [PATCH 2/8] WIP --- .../rustc_trait_selection/src/traits/coherence.rs | 14 +++++++++++++- .../rustc_trait_selection/src/traits/select/mod.rs | 10 ++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9bb4af16a8f53..e360746debc72 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -184,6 +184,8 @@ fn overlap_within_probe( debug!("overlap: unification check succeeded"); + let negate_obligation = |obligation| todo!("yaahc"); + // Are any of the obligations unsatisfiable? If so, no overlap. let infcx = selcx.infcx(); let opt_failing_obligation = a_impl_header @@ -199,7 +201,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) { + // given o = `T: Trait` this produces `T: !Trait` + if selcx.predicate_must_hold(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/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0cc31958b1952..51dc97c0ba033 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -461,9 +461,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.evaluate_trait_predicate_recursively(previous_stack, obligation) } - ty::PredicateKind::NotTrait(_t, _) => { - todo!("yaahc") - } + ty::PredicateKind::NotTrait(..) => Ok(EvaluatedToErr), ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); @@ -2438,7 +2436,11 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { } fn depth(&self) -> usize { - if let Some(head) = self.head { head.depth } else { 0 } + if let Some(head) = self.head { + head.depth + } else { + 0 + } } } From 914428df89e0e19691fe0ebcfc18ae6d9c744fa4 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 11:35:57 -0700 Subject: [PATCH 3/8] try negating --- .../src/traits/coherence.rs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e360746debc72..4b7cc59dd6e6d 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,7 +11,7 @@ use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionCont use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, fast_reject, Ty, TyCtxt}; +use rustc_middle::ty::{self, fast_reject, PredicateKind, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::iter; @@ -184,7 +184,20 @@ fn overlap_within_probe( debug!("overlap: unification check succeeded"); - let negate_obligation = |obligation| todo!("yaahc"); + let negate_obligation = |mut obligation| { + let predicate_kind = obligation.predicate.inner.kind.0; + let predicate_kind = match predicate_kind { + PredicateKind::Trait(trait_pred, constness) => { + PredicateKind::NotTrait(trait_pred, constness) + } + PredicateKind::NotTrait(trait_pred, constness) => { + PredicateKind::Trait(trait_pred, constness) + } + _ => todo!("yaahc"), + }; + obligation.predicate.inner.kind.0 = predicate_kind; + obligation + }; // Are any of the obligations unsatisfiable? If so, no overlap. let infcx = selcx.infcx(); @@ -201,7 +214,7 @@ fn overlap_within_probe( predicate: p, }) .chain(obligations) - .find(|o| { + .find(|&o| { if let Some(o_neg) = negate_obligation(o) { // given o = `T: Trait` this produces `T: !Trait` if selcx.predicate_must_hold(o_neg) { @@ -210,7 +223,7 @@ fn overlap_within_probe( } } - !selcx.predicate_may_hold_fatal(o) + !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 From e3c459cd13b79065ee9edcbd10ec534c87eca02d Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 11:41:45 -0700 Subject: [PATCH 4/8] bit better --- .../rustc_trait_selection/src/traits/coherence.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 4b7cc59dd6e6d..446cb64b9c768 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -186,17 +186,14 @@ fn overlap_within_probe( let negate_obligation = |mut obligation| { let predicate_kind = obligation.predicate.inner.kind.0; - let predicate_kind = match predicate_kind { + match predicate_kind { PredicateKind::Trait(trait_pred, constness) => { - PredicateKind::NotTrait(trait_pred, constness) + // call predicate.map here + obligation.predicate.inner.kind.0 = PredicateKind::NotTrait(trait_pred, constness); + Some(obligation) } - PredicateKind::NotTrait(trait_pred, constness) => { - PredicateKind::Trait(trait_pred, constness) - } - _ => todo!("yaahc"), - }; - obligation.predicate.inner.kind.0 = predicate_kind; - obligation + _ => return None, + } }; // Are any of the obligations unsatisfiable? If so, no overlap. From d91db3d7551b563c2313233237f1c062bebe8f3b Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 15:37:43 -0700 Subject: [PATCH 5/8] swap to using a polarity member --- .../rustc_infer/src/infer/outlives/mod.rs | 1 - compiler/rustc_infer/src/traits/util.rs | 5 +- compiler/rustc_lint/src/builtin.rs | 1 - compiler/rustc_lint/src/traits.rs | 2 +- compiler/rustc_lint/src/unused.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 76 ++++++++++++++----- compiler/rustc_middle/src/ty/flags.rs | 5 +- compiler/rustc_middle/src/ty/mod.rs | 62 +++++++++------ compiler/rustc_middle/src/ty/print/pretty.rs | 7 +- .../rustc_middle/src/ty/structural_impls.rs | 10 +-- .../src/borrow_check/type_check/mod.rs | 6 +- .../src/transform/check_consts/validation.rs | 5 +- .../src/transform/function_item_references.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 2 +- .../rustc_trait_selection/src/opaque_types.rs | 1 - .../src/traits/auto_trait.rs | 6 +- .../src/traits/coherence.rs | 27 +++---- .../src/traits/error_reporting/mod.rs | 14 ++-- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/fulfill.rs | 11 +-- .../src/traits/object_safety.rs | 10 +-- .../traits/query/type_op/prove_predicate.rs | 2 +- .../src/traits/select/mod.rs | 10 ++- .../rustc_trait_selection/src/traits/wf.rs | 7 +- compiler/rustc_traits/src/chalk/lowering.rs | 12 +-- .../src/implied_outlives_bounds.rs | 1 - .../src/normalize_erasing_regions.rs | 1 - compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/check/_match.rs | 3 +- compiler/rustc_typeck/src/check/coercion.rs | 2 +- compiler/rustc_typeck/src/check/dropck.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 5 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 4 +- .../rustc_typeck/src/check/fn_ctxt/mod.rs | 2 +- .../rustc_typeck/src/check/method/confirm.rs | 2 +- .../rustc_typeck/src/check/method/probe.rs | 5 +- .../rustc_typeck/src/check/method/suggest.rs | 6 +- compiler/rustc_typeck/src/check/mod.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 6 +- .../rustc_typeck/src/collect/item_bounds.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 11 ++- .../rustc_typeck/src/outlives/explicit.rs | 2 - src/librustdoc/clean/auto_trait.rs | 4 +- src/librustdoc/clean/mod.rs | 7 +- src/librustdoc/clean/simplify.rs | 2 +- .../clippy_lints/src/future_not_send.rs | 2 +- .../src/needless_pass_by_value.rs | 2 +- .../src/unit_return_expecting_ord.rs | 2 +- .../clippy_utils/src/qualify_min_const_fn.rs | 3 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 51 files changed, 187 insertions(+), 185 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 25a4d8e7654b6..07c75d50d91da 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -27,7 +27,6 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, - ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { Some(OutlivesBound::RegionSubRegion(r_b, r_a)) } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 22ec9d4f3362a..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()); @@ -146,9 +146,6 @@ impl Elaborator<'tcx> { self.stack.extend(obligations); } - ty::PredicateKind::NotTrait(_data, _) => { - todo!("yaahc") - } ty::PredicateKind::WellFormed(..) => { // Currently, we do not elaborate WF predicates, // although we easily could. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b8b343de431a5..e7275374b8915 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1581,7 +1581,6 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { for &(predicate, span) in predicates.predicates { let predicate_kind_name = match predicate.kind().skip_binder() { Trait(..) => "Trait", - NotTrait(..) => todo!("yaahc"), TypeOutlives(..) | RegionOutlives(..) => "Lifetime", 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..ecf814b49128b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1259,7 +1259,11 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { - if let Some(id) = id.as_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) } + if let Some(id) = id.as_local() { + self.hir().def_key(id) + } else { + self.cstore.def_key(id) + } } /// Converts a `DefId` into its fully expanded `DefPath` (every @@ -1278,7 +1282,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns whether or not the crate with CrateNum 'cnum' /// is marked as a private dependency pub fn is_private_dep(self, cnum: CrateNum) -> bool { - if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) } + if cnum == LOCAL_CRATE { + false + } else { + self.cstore.crate_is_private_dep_untracked(cnum) + } } #[inline] @@ -2127,7 +2135,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()); } @@ -2163,7 +2171,11 @@ impl<'tcx> TyCtxt<'tcx> { /// `*r == kind`. #[inline] pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tcx> { - if *r == kind { r } else { self.mk_region(kind) } + if *r == kind { + r + } else { + self.mk_region(kind) + } } #[allow(rustc::usage_of_ty_tykind)] @@ -2184,7 +2196,11 @@ impl<'tcx> TyCtxt<'tcx> { pred: Predicate<'tcx>, binder: Binder<'tcx, PredicateKind<'tcx>>, ) -> Predicate<'tcx> { - if pred.kind() != binder { self.mk_predicate(binder) } else { pred } + if pred.kind() != binder { + self.mk_predicate(binder) + } else { + pred + } } pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> { @@ -2333,7 +2349,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_diverging_default(self) -> Ty<'tcx> { - if self.features().never_type_fallback { self.types.never } else { self.types.unit } + if self.features().never_type_fallback { + self.types.never + } else { + self.types.unit + } } #[inline] @@ -2484,11 +2504,9 @@ impl<'tcx> TyCtxt<'tcx> { eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>], ) -> &'tcx List>> { assert!(!eps.is_empty()); - assert!( - eps.array_windows() - .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) - != Ordering::Greater) - ); + assert!(eps + .array_windows() + .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) != Ordering::Greater)); self._intern_poly_existential_predicates(eps) } @@ -2505,33 +2523,57 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List> { - if ts.is_empty() { List::empty() } else { self._intern_type_list(ts) } + if ts.is_empty() { + List::empty() + } else { + self._intern_type_list(ts) + } } pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List> { - if ts.is_empty() { List::empty() } else { self._intern_substs(ts) } + if ts.is_empty() { + List::empty() + } else { + self._intern_substs(ts) + } } pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List { - if ps.is_empty() { List::empty() } else { self._intern_projs(ps) } + if ps.is_empty() { + List::empty() + } else { + self._intern_projs(ps) + } } pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List> { - if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) } + if ts.is_empty() { + List::empty() + } else { + self._intern_place_elems(ts) + } } pub fn intern_canonical_var_infos( self, ts: &[CanonicalVarInfo<'tcx>], ) -> CanonicalVarInfos<'tcx> { - if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } + if ts.is_empty() { + List::empty() + } else { + self._intern_canonical_var_infos(ts) + } } pub fn intern_bound_variable_kinds( self, ts: &[ty::BoundVariableKind], ) -> &'tcx List { - if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } + if ts.is_empty() { + List::empty() + } else { + self._intern_bound_variable_kinds(ts) + } } pub fn mk_fn_sig( diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 19228ff70e6c9..9efa8d216c0fa 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -216,12 +216,9 @@ 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::NotTrait(_trait_pred, _constness) => { - todo!("yaahc") - } ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { self.add_region(a); self.add_region(b); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index fec650d56c35a..eef8e9fb03408 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -136,7 +136,11 @@ pub struct MainDefinition { impl MainDefinition { pub fn opt_fn_def_id(self) -> Option { - if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None } + if let Res::Def(DefKind::Fn, def_id) = self.res { + Some(def_id) + } else { + None + } } } @@ -151,7 +155,7 @@ 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 +375,7 @@ impl ty::EarlyBoundRegion { } } -#[derive(Debug)] +#[derive(Debug, Clone)] crate struct PredicateInner<'tcx> { kind: Binder<'tcx, PredicateKind<'tcx>>, flags: TypeFlags, @@ -408,6 +412,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,16 +459,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), - - /// Corresponds to `where Foo: !Bar`. `Foo` here would be - /// the `Self` type of the trait reference and `A`, `B`, and `C` - /// would be the type parameters. - /// - /// 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() {}`). - NotTrait(TraitPredicate<'tcx>, Constness), + Trait(TraitPredicate<'tcx>, Constness, ImplPolarity), /// `where 'a: 'b` RegionOutlives(RegionOutlivesPredicate<'tcx>), @@ -733,7 +748,7 @@ 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) + PredicateKind::Trait(ty::TraitPredicate { trait_ref: self.value }, self.constness, self.polarity) .to_predicate(tcx) } } @@ -742,7 +757,7 @@ 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 }, self.constness, self.polarity) }) .to_predicate(tcx) } @@ -750,7 +765,7 @@ 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) } } @@ -776,10 +791,9 @@ 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::NotTrait(..) => todo!("yaahc"), PredicateKind::Projection(..) | PredicateKind::Subtype(..) | PredicateKind::RegionOutlives(..) @@ -797,7 +811,6 @@ impl<'tcx> Predicate<'tcx> { let predicate = self.kind(); match predicate.skip_binder() { PredicateKind::TypeOutlives(data) => Some(predicate.rebind(data)), - PredicateKind::NotTrait(..) => todo!("yaahc"), PredicateKind::Trait(..) | PredicateKind::Projection(..) | PredicateKind::Subtype(..) @@ -1056,7 +1069,11 @@ impl WithOptConstParam { } pub fn def_id_for_type_of(self) -> DefId { - if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() } + if let Some(did) = self.const_param_did { + did + } else { + self.did.to_def_id() + } } } @@ -1245,6 +1262,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, } @@ -1253,7 +1271,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 fdecbc1379524..bf3b2ef0acdd1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -630,7 +630,7 @@ 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,15 +2191,12 @@ 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 "); } p!(print(data)) } - ty::PredicateKind::NotTrait(ref _data, _constness) => { - todo!("yaahc") - } ty::PredicateKind::Subtype(predicate) => p!(print(predicate)), ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)), ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index bb7400d177d9e..c78bfb4e27fdd 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -174,13 +174,12 @@ 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 ")?; } a.fmt(f) } - ty::PredicateKind::NotTrait(ref _a, _constness) => todo!("yaahc"), ty::PredicateKind::Subtype(ref pair) => pair.fmt(f), ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f), ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f), @@ -420,11 +419,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::NotTrait(_data, _constness) => { - todo!("yaahc") + 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_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index d27fcb2f26f19..dce8d0b6359a9 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -26,10 +26,7 @@ use rustc_middle::ty::adjustment::PointerCast; 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, -}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ImplPolarity, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -2720,6 +2717,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some(ty::PredicateKind::Trait( ty::TraitPredicate { trait_ref }, 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 1ff07702533fe..d5373b6eb483b 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; } @@ -445,9 +445,6 @@ impl Validator<'mir, 'tcx> { _ => continue, } } - ty::PredicateKind::NotTrait(_pred, _constness) => { - todo!("yaahc") - } } } match predicates.parent { 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..16b07fbe11aff 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/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index d956fe4057848..163df26e9ffaf 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1200,7 +1200,6 @@ crate fn required_region_bounds( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, - ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { // Search for a bound of the form `erased_self_ty // : 'a`, but be wary of something like `for<'a> diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index f54eb0914a5a7..f6a363362b44b 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -415,8 +415,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 +638,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 446cb64b9c768..749c5f4011870 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -9,12 +9,14 @@ 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, PredicateKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, fast_reject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::iter; +use crate::traits::query::evaluate_obligation::InferCtxtExt; /// Whether we do the orphan check relative to this crate or /// to some remote crate. @@ -184,16 +186,11 @@ fn overlap_within_probe( debug!("overlap: unification check succeeded"); - let negate_obligation = |mut obligation| { - let predicate_kind = obligation.predicate.inner.kind.0; - match predicate_kind { - PredicateKind::Trait(trait_pred, constness) => { - // call predicate.map here - obligation.predicate.inner.kind.0 = PredicateKind::NotTrait(trait_pred, constness); - Some(obligation) - } - _ => return None, - } + 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. @@ -211,16 +208,16 @@ fn overlap_within_probe( predicate: p, }) .chain(obligations) - .find(|&o| { - if let Some(o_neg) = negate_obligation(o) { + .find(|o| { + if let Some(o_neg) = negate_obligation(o, infcx.tcx) { // given o = `T: Trait` this produces `T: !Trait` - if selcx.predicate_must_hold(o_neg) { + 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) + !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 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 788865cc9024c..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); @@ -517,10 +517,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err } - ty::PredicateKind::NotTrait(_trait_predicate, _) => { - todo!("yaahc") - } - ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as // `FulfillmentErrorCode::CodeSubtypeError`, @@ -1110,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)) } _ => { @@ -1121,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. @@ -1497,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); @@ -1762,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 16c9bfb493734..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( @@ -362,9 +362,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { &mut pending_obligation.stalled_on, ) } - ty::PredicateKind::NotTrait(_trait_ref, _constness) => { - todo!("yaahc") - } ty::PredicateKind::Projection(data) => { let project_obligation = obligation.with(binder.rebind(data)); @@ -391,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( @@ -401,10 +398,6 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ) } - ty::PredicateKind::NotTrait(_data, _) => { - todo!("yaahc") - } - ty::PredicateKind::RegionOutlives(data) => { match infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)) { Ok(()) => ProcessResult::Changed(vec![]), diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 7e0aaaa811b85..081c2e446ceda 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -280,13 +280,10 @@ 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 } } - ty::PredicateKind::NotTrait(ref _data, _) => { - todo!("yaahc") - } ty::PredicateKind::Projection(ref data) => { // And similarly for projections. This should be redundant with // the previous check because any projection should have a @@ -334,12 +331,9 @@ 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::NotTrait(ref _trait_pred, _) => { - todo!("yaahc") - } ty::PredicateKind::Projection(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::RegionOutlives(..) 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..20862380b7108 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,7 @@ 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 51dc97c0ba033..2f0ce6b90d5ee 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -36,6 +36,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::ty::ImplPolarity; use rustc_middle::ty::fast_reject; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; @@ -454,14 +455,15 @@ 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::NotTrait(..) => Ok(EvaluatedToErr), + 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); @@ -867,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"); @@ -1207,7 +1209,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 75628ad4c4fd0..145468c42efda 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -107,12 +107,9 @@ 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::NotTrait(_t, _) => { - todo!("yaahc") - } ty::PredicateKind::RegionOutlives(..) => {} ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); @@ -228,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 1015c2efb4a12..6d4855c3ecd36 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -87,10 +87,9 @@ 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::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => chalk_ir::DomainGoal::Holds( chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { a: predicate.0.lower_into(interner), @@ -138,12 +137,11 @@ 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)), )) } - ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => { chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { @@ -571,10 +569,9 @@ impl<'tcx> LowerInto<'tcx, Option { + ty::PredicateKind::Trait(predicate, _, _) => { Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner))) } - ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::RegionOutlives(predicate) => { Some(chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { a: predicate.0.lower_into(interner), @@ -705,13 +702,12 @@ 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), ), )), - ty::PredicateKind::NotTrait(_predicate, _) => todo!("yaahc"), ty::PredicateKind::Projection(predicate) => Some(chalk_ir::Binders::new( binders, chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)), diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index be146da7525c0..90ba90259c32b 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -105,7 +105,6 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => vec![], - ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::WellFormed(arg) => { wf_args.push(arg); vec![] diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 7bf17d7b35b06..5ad0684fe6ee2 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -59,7 +59,6 @@ fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Cop fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool { match p.kind().skip_binder() { ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false, - ty::PredicateKind::NotTrait(..) => todo!("yaahc"), ty::PredicateKind::Trait(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::WellFormed(..) 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..10e03da192a0f 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -603,7 +603,7 @@ 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 { @@ -612,6 +612,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, }, 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 6872de4a4dc58..c38fd79740c58 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -793,12 +793,9 @@ 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::NotTrait(_data, _) => { - todo!("yaahc") - } ty::PredicateKind::Subtype(..) => None, ty::PredicateKind::RegionOutlives(..) => None, ty::PredicateKind::TypeOutlives(..) => 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..daeafc8395801 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -496,7 +496,7 @@ 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 db805aa2eed51..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)) @@ -840,9 +840,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { _ => None, } } - ty::PredicateKind::NotTrait(_trait_predicate, _) => { - todo!("yaahc") - } ty::PredicateKind::Subtype(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::RegionOutlives(..) 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 9bf01bf46f76c..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,13 +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::NotTrait(_pred, _) => { - todo!("yaahc") - } - 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/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs index 3182222c67f4b..6e5be87928d59 100644 --- a/compiler/rustc_typeck/src/outlives/explicit.rs +++ b/compiler/rustc_typeck/src/outlives/explicit.rs @@ -50,8 +50,6 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { ) } - ty::PredicateKind::NotTrait(..) => todo!("yaahc"), - ty::PredicateKind::Trait(..) | ty::PredicateKind::Projection(..) | ty::PredicateKind::WellFormed(..) 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 dbfa20f090f9e..96a298d53d4fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -346,8 +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::NotTrait(_pred, _) => todo!("yaahc"), + 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)), @@ -627,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); } @@ -1560,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 45a6eca906a53..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; } @@ -57,7 +57,6 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<&Ru _ => continue, } }, - ty::PredicateKind::NotTrait(_pred, _) => todo!("yaahc"), } } match predicates.parent { 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; } From c6a10e2108db841a752bfe99adde8c26f069acb2 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 15:39:42 -0700 Subject: [PATCH 6/8] run fmt --- compiler/rustc_middle/src/ty/context.rs | 74 ++++--------------- compiler/rustc_middle/src/ty/mod.rs | 43 +++++++---- compiler/rustc_middle/src/ty/print/pretty.rs | 3 +- .../src/borrow_check/type_check/mod.rs | 5 +- .../src/traits/coherence.rs | 14 ++-- .../traits/query/type_op/prove_predicate.rs | 3 +- .../src/traits/select/mod.rs | 8 +- .../rustc_typeck/src/check/method/confirm.rs | 4 +- 8 files changed, 65 insertions(+), 89 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ecf814b49128b..1f97a761a66d2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1259,11 +1259,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { - if let Some(id) = id.as_local() { - self.hir().def_key(id) - } else { - self.cstore.def_key(id) - } + if let Some(id) = id.as_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) } } /// Converts a `DefId` into its fully expanded `DefPath` (every @@ -1282,11 +1278,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns whether or not the crate with CrateNum 'cnum' /// is marked as a private dependency pub fn is_private_dep(self, cnum: CrateNum) -> bool { - if cnum == LOCAL_CRATE { - false - } else { - self.cstore.crate_is_private_dep_untracked(cnum) - } + if cnum == LOCAL_CRATE { false } else { self.cstore.crate_is_private_dep_untracked(cnum) } } #[inline] @@ -2171,11 +2163,7 @@ impl<'tcx> TyCtxt<'tcx> { /// `*r == kind`. #[inline] pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tcx> { - if *r == kind { - r - } else { - self.mk_region(kind) - } + if *r == kind { r } else { self.mk_region(kind) } } #[allow(rustc::usage_of_ty_tykind)] @@ -2196,11 +2184,7 @@ impl<'tcx> TyCtxt<'tcx> { pred: Predicate<'tcx>, binder: Binder<'tcx, PredicateKind<'tcx>>, ) -> Predicate<'tcx> { - if pred.kind() != binder { - self.mk_predicate(binder) - } else { - pred - } + if pred.kind() != binder { self.mk_predicate(binder) } else { pred } } pub fn mk_mach_int(self, tm: IntTy) -> Ty<'tcx> { @@ -2349,11 +2333,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_diverging_default(self) -> Ty<'tcx> { - if self.features().never_type_fallback { - self.types.never - } else { - self.types.unit - } + if self.features().never_type_fallback { self.types.never } else { self.types.unit } } #[inline] @@ -2504,9 +2484,11 @@ impl<'tcx> TyCtxt<'tcx> { eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>], ) -> &'tcx List>> { assert!(!eps.is_empty()); - assert!(eps - .array_windows() - .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) != Ordering::Greater)); + assert!( + eps.array_windows() + .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) + != Ordering::Greater) + ); self._intern_poly_existential_predicates(eps) } @@ -2523,57 +2505,33 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List> { - if ts.is_empty() { - List::empty() - } else { - self._intern_type_list(ts) - } + if ts.is_empty() { List::empty() } else { self._intern_type_list(ts) } } pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List> { - if ts.is_empty() { - List::empty() - } else { - self._intern_substs(ts) - } + if ts.is_empty() { List::empty() } else { self._intern_substs(ts) } } pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List { - if ps.is_empty() { - List::empty() - } else { - self._intern_projs(ps) - } + if ps.is_empty() { List::empty() } else { self._intern_projs(ps) } } pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List> { - if ts.is_empty() { - List::empty() - } else { - self._intern_place_elems(ts) - } + if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) } } pub fn intern_canonical_var_infos( self, ts: &[CanonicalVarInfo<'tcx>], ) -> CanonicalVarInfos<'tcx> { - if ts.is_empty() { - List::empty() - } else { - self._intern_canonical_var_infos(ts) - } + if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } } pub fn intern_bound_variable_kinds( self, ts: &[ty::BoundVariableKind], ) -> &'tcx List { - if ts.is_empty() { - List::empty() - } else { - self._intern_bound_variable_kinds(ts) - } + if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } } pub fn mk_fn_sig( diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index eef8e9fb03408..b7ca9e4e6767b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -136,11 +136,7 @@ pub struct MainDefinition { impl MainDefinition { pub fn opt_fn_def_id(self) -> Option { - if let Res::Def(DefKind::Fn, def_id) = self.res { - Some(def_id) - } else { - None - } + if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None } } } @@ -155,7 +151,18 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec>, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, TypeFoldable, Debug)] +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + TyEncodable, + TyDecodable, + HashStable, + TypeFoldable, + Debug +)] pub enum ImplPolarity { /// `impl Trait for Type` Positive, @@ -748,8 +755,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, self.polarity) - .to_predicate(tcx) + PredicateKind::Trait( + ty::TraitPredicate { trait_ref: self.value }, + self.constness, + self.polarity, + ) + .to_predicate(tcx) } } @@ -757,7 +768,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, self.polarity) + PredicateKind::Trait( + ty::TraitPredicate { trait_ref }, + self.constness, + self.polarity, + ) }) .to_predicate(tcx) } @@ -765,7 +780,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, self.polarity)).to_predicate(tcx) + self.value + .map_bound(|value| PredicateKind::Trait(value, self.constness, self.polarity)) + .to_predicate(tcx) } } @@ -1069,11 +1086,7 @@ impl WithOptConstParam { } pub fn def_id_for_type_of(self) -> DefId { - if let Some(did) = self.const_param_did { - did - } else { - self.did.to_def_id() - } + if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index bf3b2ef0acdd1..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() { 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 dce8d0b6359a9..1ac268f49de9d 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -26,7 +26,10 @@ use rustc_middle::ty::adjustment::PointerCast; 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, ImplPolarity, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness}; +use rustc_middle::ty::{ + self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ImplPolarity, RegionVid, + ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, +}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_trait_selection::infer::InferCtxtExt as _; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 749c5f4011870..5c4f6291a6566 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -5,6 +5,7 @@ //! [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}; @@ -16,7 +17,6 @@ use rustc_middle::ty::{self, fast_reject, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::iter; -use crate::traits::query::evaluate_obligation::InferCtxtExt; /// Whether we do the orphan check relative to this crate or /// to some remote crate. @@ -186,11 +186,13 @@ 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 }) + 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. 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 20862380b7108..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 2f0ce6b90d5ee..37f8f45376c3e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -36,11 +36,11 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::ImplPolarity; 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; @@ -2438,11 +2438,7 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { } fn depth(&self) -> usize { - if let Some(head) = self.head { - head.depth - } else { - 0 - } + if let Some(head) = self.head { head.depth } else { 0 } } } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index daeafc8395801..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)| { From 0f8fe20fefa4a1bad37fc873792721785b268cb3 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 15:50:53 -0700 Subject: [PATCH 7/8] checkpoint --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 37f8f45376c3e..57351350eecd7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1051,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); From 3549e93ee61d16a2ec01ca80dbaec2ec6864d90e Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 15 Jul 2021 16:09:16 -0700 Subject: [PATCH 8/8] thread the polarity into the traitpredicate --- compiler/rustc_middle/src/ty/mod.rs | 5 +++-- compiler/rustc_middle/src/ty/relate.rs | 3 ++- compiler/rustc_middle/src/ty/structural_impls.rs | 3 ++- compiler/rustc_middle/src/ty/sty.rs | 3 ++- .../rustc_mir/src/borrow_check/type_check/mod.rs | 2 +- .../src/transform/check_consts/validation.rs | 2 ++ compiler/rustc_privacy/src/lib.rs | 2 +- .../rustc_trait_selection/src/traits/auto_trait.rs | 2 ++ .../rustc_trait_selection/src/traits/select/mod.rs | 12 ++++++------ compiler/rustc_typeck/src/check/_match.rs | 1 + 10 files changed, 22 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b7ca9e4e6767b..3da76095131d8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -622,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>>; @@ -756,7 +757,7 @@ 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 }, + ty::TraitPredicate { trait_ref: self.value, polarity: self.polarity }, self.constness, self.polarity, ) @@ -769,7 +770,7 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { self.value .map_bound(|trait_ref| { PredicateKind::Trait( - ty::TraitPredicate { trait_ref }, + ty::TraitPredicate { trait_ref, polarity: self.polarity }, self.constness, self.polarity, ) 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 c78bfb4e27fdd..51668d429bb9b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -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 }) } } 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 1ac268f49de9d..72840f314e66f 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -2718,7 +2718,7 @@ 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, )), diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index d5373b6eb483b..3765ea53e4e05 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -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_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 16b07fbe11aff..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_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index f6a363362b44b..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(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 57351350eecd7..b47724fdc84ec 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1051,12 +1051,12 @@ 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 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); diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 10e03da192a0f..92001ced2d6be 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -610,6 +610,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_id: t.def_id(), substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]), }, + polarity, }, constness, polarity,