This commit is contained in:
Bastian Kauschke 2020-06-18 20:33:52 +02:00
parent 4c3b1e89cf
commit 506f4308b7
7 changed files with 54 additions and 46 deletions

View file

@ -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<Item = PredicateObligation<'tcx>>> Iterator for FilterToT
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
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

View file

@ -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| {

View file

@ -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) {

View file

@ -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<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)
}
}
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<PolyTraitRef<'tcx>> {
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)
}
}

View file

@ -652,8 +652,7 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
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 =

View file

@ -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,

View file

@ -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<DefId>,
dummy: PhantomData<TyCtxt<'tcx>>,