diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index 02a30195cc8e..2a09d9dbee39 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -3,7 +3,7 @@ use smallvec::smallvec; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::ty::outlives::Component; -use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness}; +use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness}; use rustc_span::Span; pub fn anonymize_predicate<'tcx>( @@ -330,8 +330,8 @@ impl<'tcx, I: Iterator>> Iterator for FilterToT fn next(&mut self) -> Option> { while let Some(obligation) = self.base_iterator.next() { - if let ty::PredicateKind::Trait(data, _) = obligation.predicate.kind() { - return Some(data.to_poly_trait_ref()); + if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() { + return Some(data); } } None diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5c4be715add7..a9490c954b55 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1202,13 +1202,15 @@ declare_lint_pass!( impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { use rustc_middle::ty::fold::TypeFoldable; - use rustc_middle::ty::PredicateKind::*; + use rustc_middle::ty::PredicateKint::*; if cx.tcx.features().trivial_bounds { let def_id = cx.tcx.hir().local_def_id(item.hir_id); let predicates = cx.tcx.predicates_of(def_id); for &(predicate, span) in predicates.predicates { - let predicate_kind_name = match predicate.kind() { + // We don't actually look inside of the predicate, + // so it is safe to skip this binder here. + let predicate_kind_name = match predicate.kint(cx.tcx).ignore_qualifiers().skip_binder() { Trait(..) => "Trait", TypeOutlives(..) | RegionOutlives(..) => "Lifetime", @@ -1223,6 +1225,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Subtype(..) | ConstEvaluatable(..) | ConstEquate(..) => continue, + ForAll(_) => bug!("unexpected predicate: {:?}", predicate) }; if predicate.is_global() { cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 6d6c7b24101c..62127f3e12ca 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -146,11 +146,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in cx.tcx.predicates_of(def).predicates { - if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) = - predicate.kind() + // We only look at the `DefId`, so it is safe to skip the binder here. + if let ty::PredicateKint::Trait(ref poly_trait_predicate, _) = + predicate.kint(cx.tcx).ignore_qualifiers().skip_binder() { - let trait_ref = poly_trait_predicate.skip_binder().trait_ref; - let def_id = trait_ref.def_id; + let def_id = poly_trait_predicate.trait_ref.def_id; let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix,); if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index ac1642ec8661..b8f955012624 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1217,6 +1217,16 @@ pub enum PredicateKind<'tcx> { ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>), } +impl<'tcx> PredicateKint<'tcx> { + /// Skips `PredicateKint::ForAll`. + pub fn ignore_qualifiers(&'tcx self) -> Binder<&'tcx PredicateKint<'tcx>> { + match self { + &PredicateKint::ForAll(binder) => binder, + pred => Binder::dummy(pred), + } + } +} + /// The crate outlives map is computed during typeck and contains the /// outlives of every item in the local crate. You should not use it /// directly, because to do so will make your pass dependent on the @@ -1513,34 +1523,37 @@ impl ToPredicate<'tcx> for PredicateKint<'tcx> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::PredicateKind::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value }), - self.constness, - ) - .to_predicate(tcx) - } -} - -impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::PredicateKind::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: *self.value }), - self.constness, - ) - .to_predicate(tcx) + ty::PredicateKint::Trait(ty::TraitPredicate { trait_ref: self.value }, self.constness) + .to_predicate(tcx) } } impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - ty::PredicateKind::Trait(self.value.to_poly_trait_predicate(), self.constness) - .to_predicate(tcx) + if let Some(trait_ref) = self.value.no_bound_vars() { + ty::PredicateKint::Trait(ty::TraitPredicate { trait_ref }, self.constness) + } else { + ty::PredicateKint::ForAll(self.value.map_bound(|trait_ref| { + tcx.intern_predicate_kint(ty::PredicateKint::Trait( + ty::TraitPredicate { trait_ref }, + self.constness, + )) + })) + } + .to_predicate(tcx) } } impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { - PredicateKind::RegionOutlives(self).to_predicate(tcx) + if let Some(outlives) = self.no_bound_vars() { + PredicateKint::RegionOutlives(outlives) + } else { + ty::PredicateKint::ForAll(self.map_bound(|outlives| { + tcx.intern_predicate_kint(PredicateKint::RegionOutlives(outlives)) + })) + } + .to_predicate(tcx) } } diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 03bf51c95c5a..cf9d40a6dc6c 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -652,8 +652,7 @@ impl<'tcx> Binder> { Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) } ExistentialPredicate::Projection(p) => { - ty::PredicateKind::Projection(Binder(p.with_self_ty(tcx, self_ty))) - .to_predicate(tcx) + Binder(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } ExistentialPredicate::AutoTrait(did) => { let trait_ref = diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 5491c3fb2486..9fc5dc0d131c 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -28,7 +28,7 @@ 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, + TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, }; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; @@ -2022,18 +2022,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { traits::ObligationCauseCode::RepeatVec(should_suggest), ), self.param_env, - ty::PredicateKind::Trait( - ty::Binder::bind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new( - self.tcx().require_lang_item( - CopyTraitLangItem, - Some(self.last_span), - ), - tcx.mk_substs_trait(ty, &[]), - ), - }), - hir::Constness::NotConst, - ) + ty::Binder::bind(ty::TraitRef::new( + self.tcx().require_lang_item( + CopyTraitLangItem, + Some(self.last_span), + ), + tcx.mk_substs_trait(ty, &[]), + )) + .without_const() .to_predicate(self.tcx()), ), &traits::SelectionError::Unimplemented, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 1ecb0320744f..0b97695041be 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -68,10 +68,7 @@ trait DefIdVisitor<'tcx> { } } -struct DefIdVisitorSkeleton<'v, 'tcx, V> -where - V: DefIdVisitor<'tcx> + ?Sized, -{ +struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> { def_id_visitor: &'v mut V, visited_opaque_tys: FxHashSet, dummy: PhantomData>,