diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 71ce50f7453..6dbaf8d225a 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -541,8 +541,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { span_bug!(cause.span, "unexpected const outlives {:?}", constraint); } }; - let predicate = - predicate.rebind(atom).potentially_quantified(self.tcx, ty::PredicateKind::ForAll); + let predicate = predicate.rebind(atom).potentially_quantified(self.tcx); Obligation::new(cause.clone(), param_env, predicate) }) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 8273c2d291d..d9ef5d88f1c 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -14,7 +14,6 @@ pub fn anonymize_predicate<'tcx>( let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder)); tcx.reuse_or_mk_predicate(pred, new) } - ty::PredicateKind::Atom(_) => pred, } } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 4de3d159248..47ada10f55f 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -211,7 +211,6 @@ impl FlagComputation { computation.add_predicate_atom(atom) }); } - ty::PredicateKind::Atom(atom) => self.add_predicate_atom(atom), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1399fc76e02..53950640966 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1037,7 +1037,7 @@ crate struct PredicateInner<'tcx> { } #[cfg(target_arch = "x86_64")] -static_assert_size!(PredicateInner<'_>, 48); +static_assert_size!(PredicateInner<'_>, 40); #[derive(Clone, Copy, Lift)] pub struct Predicate<'tcx> { @@ -1074,10 +1074,6 @@ impl<'tcx> Predicate<'tcx> { pub fn skip_binders(self) -> PredicateAtom<'tcx> { match self.kind() { &PredicateKind::ForAll(binder) => binder.skip_binder(), - &PredicateKind::Atom(atom) => { - debug_assert!(!atom.has_escaping_bound_vars()); - atom - } } } @@ -1090,7 +1086,6 @@ impl<'tcx> Predicate<'tcx> { pub fn skip_binders_unchecked(self) -> PredicateAtom<'tcx> { match self.kind() { &PredicateKind::ForAll(binder) => binder.skip_binder(), - &PredicateKind::Atom(atom) => atom, } } @@ -1099,19 +1094,14 @@ impl<'tcx> Predicate<'tcx> { pub fn bound_atom(self) -> Binder> { match self.kind() { &PredicateKind::ForAll(binder) => binder, - &PredicateKind::Atom(atom) => { - debug_assert!(!atom.has_escaping_bound_vars()); - Binder::dummy(atom) - } } } /// Allows using a `Binder>` even if the given predicate previously /// contained unbound variables by shifting these variables outwards. - pub fn bound_atom_with_opt_escaping(self, tcx: TyCtxt<'tcx>) -> Binder> { + pub fn bound_atom_with_opt_escaping(self, _tcx: TyCtxt<'tcx>) -> Binder> { match self.kind() { &PredicateKind::ForAll(binder) => binder, - &PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom), } } } @@ -1136,7 +1126,6 @@ impl<'a, 'tcx> HashStable> for Predicate<'tcx> { pub enum PredicateKind<'tcx> { /// `for<'a>: ...` ForAll(Binder>), - Atom(PredicateAtom<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -1189,16 +1178,8 @@ pub enum PredicateAtom<'tcx> { impl<'tcx> Binder> { /// Wraps `self` with the given qualifier if this predicate has any unbound variables. - pub fn potentially_quantified( - self, - tcx: TyCtxt<'tcx>, - qualifier: impl FnOnce(Binder>) -> PredicateKind<'tcx>, - ) -> Predicate<'tcx> { - match self.no_bound_vars() { - Some(atom) => PredicateKind::Atom(atom), - None => qualifier(self), - } - .to_predicate(tcx) + pub fn potentially_quantified(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + PredicateKind::ForAll(self).to_predicate(tcx) } } @@ -1289,11 +1270,7 @@ impl<'tcx> Predicate<'tcx> { let substs = trait_ref.skip_binder().substs; let pred = self.skip_binders(); let new = pred.subst(tcx, substs); - if new != pred { - ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll) - } else { - self - } + if new != pred { ty::Binder::bind(new).potentially_quantified(tcx) } else { self } } } @@ -1425,7 +1402,7 @@ impl ToPredicate<'tcx> for PredicateAtom<'tcx> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { debug_assert!(!self.has_escaping_bound_vars(), "escaping bound vars for {:?}", self); - tcx.mk_predicate(PredicateKind::Atom(self)) + tcx.mk_predicate(PredicateKind::ForAll(Binder::dummy(self))) } } @@ -1450,27 +1427,25 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.value .map_bound(|value| PredicateAtom::Trait(value, self.constness)) - .potentially_quantified(tcx, PredicateKind::ForAll) + .potentially_quantified(tcx) } } impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(PredicateAtom::RegionOutlives) - .potentially_quantified(tcx, PredicateKind::ForAll) + self.map_bound(PredicateAtom::RegionOutlives).potentially_quantified(tcx) } } impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(PredicateAtom::TypeOutlives) - .potentially_quantified(tcx, PredicateKind::ForAll) + self.map_bound(PredicateAtom::TypeOutlives).potentially_quantified(tcx) } } impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx, PredicateKind::ForAll) + self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 893572785f7..bc9ea3728b6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2069,7 +2069,6 @@ define_print_and_forward_display! { ty::Predicate<'tcx> { match self.kind() { - &ty::PredicateKind::Atom(atom) => p!(print(atom)), ty::PredicateKind::ForAll(binder) => p!(print(binder)), } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7a1ca6a6c2b..934d97d00e8 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -232,7 +232,6 @@ impl fmt::Debug for ty::PredicateKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { ty::PredicateKind::ForAll(binder) => write!(f, "ForAll({:?})", binder), - ty::PredicateKind::Atom(atom) => write!(f, "{:?}", atom), } } } @@ -486,7 +485,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { match self { ty::PredicateKind::ForAll(binder) => tcx.lift(binder).map(ty::PredicateKind::ForAll), - ty::PredicateKind::Atom(atom) => tcx.lift(atom).map(ty::PredicateKind::Atom), } } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a04f816b0f8..55d5331ae37 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -346,45 +346,47 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { let infcx = self.selcx.infcx(); match *obligation.predicate.kind() { + ty::PredicateKind::ForAll(binder) if binder.skip_binder().has_escaping_bound_vars() => { + match binder.skip_binder() { + // Evaluation will discard candidates using the leak check. + // This means we need to pass it the bound version of our + // predicate. + ty::PredicateAtom::Trait(trait_ref, _constness) => { + let trait_obligation = obligation.with(binder.rebind(trait_ref)); + + self.process_trait_obligation( + obligation, + trait_obligation, + &mut pending_obligation.stalled_on, + ) + } + ty::PredicateAtom::Projection(data) => { + let project_obligation = obligation.with(binder.rebind(data)); + + self.process_projection_obligation( + project_obligation, + &mut pending_obligation.stalled_on, + ) + } + ty::PredicateAtom::RegionOutlives(_) + | ty::PredicateAtom::TypeOutlives(_) + | ty::PredicateAtom::WellFormed(_) + | ty::PredicateAtom::ObjectSafe(_) + | ty::PredicateAtom::ClosureKind(..) + | ty::PredicateAtom::Subtype(_) + | ty::PredicateAtom::ConstEvaluatable(..) + | ty::PredicateAtom::ConstEquate(..) => { + let pred = infcx.replace_bound_vars_with_placeholders(binder); + ProcessResult::Changed(mk_pending(vec![ + obligation.with(pred.to_predicate(self.selcx.tcx())), + ])) + } + ty::PredicateAtom::TypeWellFormedFromEnv(..) => { + bug!("TypeWellFormedFromEnv is only used for Chalk") + } + } + } ty::PredicateKind::ForAll(binder) => match binder.skip_binder() { - // Evaluation will discard candidates using the leak check. - // This means we need to pass it the bound version of our - // predicate. - ty::PredicateAtom::Trait(trait_ref, _constness) => { - let trait_obligation = obligation.with(binder.rebind(trait_ref)); - - self.process_trait_obligation( - obligation, - trait_obligation, - &mut pending_obligation.stalled_on, - ) - } - ty::PredicateAtom::Projection(data) => { - let project_obligation = obligation.with(binder.rebind(data)); - - self.process_projection_obligation( - project_obligation, - &mut pending_obligation.stalled_on, - ) - } - ty::PredicateAtom::RegionOutlives(_) - | ty::PredicateAtom::TypeOutlives(_) - | ty::PredicateAtom::WellFormed(_) - | ty::PredicateAtom::ObjectSafe(_) - | ty::PredicateAtom::ClosureKind(..) - | ty::PredicateAtom::Subtype(_) - | ty::PredicateAtom::ConstEvaluatable(..) - | ty::PredicateAtom::ConstEquate(..) => { - let pred = infcx.replace_bound_vars_with_placeholders(binder); - ProcessResult::Changed(mk_pending(vec![ - obligation.with(pred.to_predicate(self.selcx.tcx())), - ])) - } - ty::PredicateAtom::TypeWellFormedFromEnv(..) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } - }, - ty::PredicateKind::Atom(atom) => match atom { ty::PredicateAtom::Trait(data, _) => { let trait_obligation = obligation.with(Binder::dummy(data)); diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 97017fbf2e5..a4da22fc2ca 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -95,8 +95,12 @@ fn compute_implied_outlives_bounds<'tcx>( implied_bounds.extend(obligations.into_iter().flat_map(|obligation| { assert!(!obligation.has_escaping_bound_vars()); match obligation.predicate.kind() { - &ty::PredicateKind::ForAll(..) => vec![], - &ty::PredicateKind::Atom(atom) => match atom { + &ty::PredicateKind::ForAll(binder) + if binder.skip_binder().has_escaping_bound_vars() => + { + vec![] + } + &ty::PredicateKind::ForAll(binder) => match binder.skip_binder() { ty::PredicateAtom::Trait(..) | ty::PredicateAtom::Subtype(..) | ty::PredicateAtom::Projection(..) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index a6677328f8f..b1242f0d1d5 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1949,10 +1949,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP let predicate = ty::Binder::bind(ty::PredicateAtom::TypeOutlives( ty::OutlivesPredicate(ty, re_root_empty), )); - predicates.insert(( - predicate.potentially_quantified(tcx, ty::PredicateKind::ForAll), - span, - )); + predicates.insert((predicate.potentially_quantified(tcx), span)); } } @@ -1996,7 +1993,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP ty::Binder::bind(ty::PredicateAtom::TypeOutlives( ty::OutlivesPredicate(ty, region), )) - .potentially_quantified(tcx, ty::PredicateKind::ForAll), + .potentially_quantified(tcx), lifetime.span, )); } diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs index b1f79331d5f..649edfb8f52 100644 --- a/compiler/rustc_typeck/src/outlives/mod.rs +++ b/compiler/rustc_typeck/src/outlives/mod.rs @@ -31,13 +31,11 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate let mut pred: Vec = predicates .iter() .map(|(out_pred, _)| match out_pred.kind() { - ty::PredicateKind::Atom(ty::PredicateAtom::RegionOutlives(p)) => { - p.to_string() - } - ty::PredicateKind::Atom(ty::PredicateAtom::TypeOutlives(p)) => { - p.to_string() - } - err => bug!("unexpected predicate {:?}", err), + ty::PredicateKind::ForAll(binder) => match binder.skip_binder() { + ty::PredicateAtom::RegionOutlives(p) => p.to_string(), + ty::PredicateAtom::TypeOutlives(p) => p.to_string(), + err => bug!("unexpected predicate {:?}", err), + }, }) .collect(); pred.sort(); diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr index fee8b06e94c..fab36adb0f4 100644 --- a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr +++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr @@ -1,4 +1,4 @@ -error: cannot specialize on `ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))` +error: cannot specialize on `ForAll(Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))))` --> $DIR/repeated_projection_type.rs:19:1 | LL | / impl> X for V { 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 a435f86bfd8..ad50a6a0405 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 @@ -115,13 +115,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { .filter(|p| !p.is_global()) .filter_map(|obligation| { // Note that we do not want to deal with qualified predicates here. - if let ty::PredicateKind::Atom(ty::PredicateAtom::Trait(pred, _)) = obligation.predicate.kind() { - if pred.def_id() == sized_trait { - return None; + let ty::PredicateKind::ForAll(binder) = obligation.predicate.kind(); + match binder.skip_binder() { + ty::PredicateAtom::Trait(pred, _) if !binder.has_escaping_bound_vars() => { + if pred.def_id() == sized_trait { + return None; + } + Some(pred) } - Some(pred) - } else { - None + _ => None, } }) .collect::>();