mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Overhaul PredicateInner
and Predicate
.
Specifically, change `Ty` from this: ``` pub struct Predicate<'tcx> { inner: &'tcx PredicateInner<'tcx> } ``` to this: ``` pub struct Predicate<'tcx>(&'tcx Interned<PredicateS<'tcx>>) ``` where `PredicateInner` is renamed as `PredicateS`. This (plus a few other minor changes) makes the parallels with `Ty` and `TyS` much clearer, and makes the uniqueness more explicit.
This commit is contained in:
parent
e9a0c429c5
commit
925ec0d3c7
@ -88,7 +88,7 @@ macro_rules! arena_types {
|
|||||||
|
|
||||||
// Interned types
|
// Interned types
|
||||||
[] tys: rustc_middle::ty::TyS<'tcx>,
|
[] tys: rustc_middle::ty::TyS<'tcx>,
|
||||||
[] predicates: rustc_middle::ty::PredicateInner<'tcx>,
|
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
|
||||||
|
|
||||||
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
||||||
// since we need to allocate this type on both the `rustc_hir` arena
|
// since we need to allocate this type on both the `rustc_hir` arena
|
||||||
|
@ -20,7 +20,7 @@ use crate::ty::{
|
|||||||
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
|
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
|
||||||
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
|
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
|
||||||
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
|
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
|
||||||
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
|
ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, RegionKind,
|
||||||
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
|
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
|
||||||
};
|
};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
@ -107,7 +107,7 @@ pub struct CtxtInterners<'tcx> {
|
|||||||
region: InternedSet<'tcx, RegionKind>,
|
region: InternedSet<'tcx, RegionKind>,
|
||||||
poly_existential_predicates:
|
poly_existential_predicates:
|
||||||
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
|
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
|
||||||
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
|
predicate: InternedSet<'tcx, PredicateS<'tcx>>,
|
||||||
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
||||||
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
||||||
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
||||||
@ -170,23 +170,22 @@ impl<'tcx> CtxtInterners<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn intern_predicate(
|
fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
||||||
&self,
|
Predicate(Interned::new_unchecked(
|
||||||
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
self.predicate
|
||||||
) -> &'tcx PredicateInner<'tcx> {
|
.intern(kind, |kind| {
|
||||||
self.predicate
|
let flags = super::flags::FlagComputation::for_predicate(kind);
|
||||||
.intern(kind, |kind| {
|
|
||||||
let flags = super::flags::FlagComputation::for_predicate(kind);
|
|
||||||
|
|
||||||
let predicate_struct = PredicateInner {
|
let predicate_struct = PredicateS {
|
||||||
kind,
|
kind,
|
||||||
flags: flags.flags,
|
flags: flags.flags,
|
||||||
outer_exclusive_binder: flags.outer_exclusive_binder,
|
outer_exclusive_binder: flags.outer_exclusive_binder,
|
||||||
};
|
};
|
||||||
|
|
||||||
InternedInSet(self.arena.alloc(predicate_struct))
|
InternedInSet(self.arena.alloc(predicate_struct))
|
||||||
})
|
})
|
||||||
.0
|
.0,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1684,7 +1683,7 @@ nop_lift! {type_; Ty<'a> => Ty<'tcx>}
|
|||||||
nop_lift_old! {region; Region<'a> => Region<'tcx>}
|
nop_lift_old! {region; Region<'a> => Region<'tcx>}
|
||||||
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
nop_lift_old! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
||||||
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
|
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
|
||||||
nop_lift_old! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
|
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
|
||||||
|
|
||||||
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
|
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
|
||||||
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
|
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
|
||||||
@ -2040,23 +2039,23 @@ impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateInner<'tcx>> {
|
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateS<'tcx>> {
|
||||||
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
|
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
|
||||||
&self.0.kind
|
&self.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateInner<'tcx>> {
|
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateS<'tcx>> {
|
||||||
fn eq(&self, other: &InternedInSet<'tcx, PredicateInner<'tcx>>) -> bool {
|
fn eq(&self, other: &InternedInSet<'tcx, PredicateS<'tcx>>) -> bool {
|
||||||
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
|
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
|
||||||
// `x == y`.
|
// `x == y`.
|
||||||
self.0.kind == other.0.kind
|
self.0.kind == other.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Eq for InternedInSet<'tcx, PredicateInner<'tcx>> {}
|
impl<'tcx> Eq for InternedInSet<'tcx, PredicateS<'tcx>> {}
|
||||||
|
|
||||||
impl<'tcx> Hash for InternedInSet<'tcx, PredicateInner<'tcx>> {
|
impl<'tcx> Hash for InternedInSet<'tcx, PredicateS<'tcx>> {
|
||||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||||
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
|
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
|
||||||
self.0.kind.hash(s)
|
self.0.kind.hash(s)
|
||||||
@ -2237,8 +2236,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
||||||
let inner = self.interners.intern_predicate(binder);
|
self.interners.intern_predicate(binder)
|
||||||
Predicate { inner }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1181,7 +1181,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
if predicate.inner.outer_exclusive_binder > self.outer_index {
|
if predicate.outer_exclusive_binder() > self.outer_index {
|
||||||
ControlFlow::Break(FoundEscapingVars)
|
ControlFlow::Break(FoundEscapingVars)
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
@ -1263,9 +1263,11 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
|||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
debug!(
|
debug!(
|
||||||
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
|
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
|
||||||
predicate, predicate.inner.flags, self.flags
|
predicate,
|
||||||
|
predicate.flags(),
|
||||||
|
self.flags
|
||||||
);
|
);
|
||||||
if predicate.inner.flags.intersects(self.flags) {
|
if predicate.flags().intersects(self.flags) {
|
||||||
ControlFlow::Break(FoundFlags)
|
ControlFlow::Break(FoundFlags)
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::CONTINUE
|
ControlFlow::CONTINUE
|
||||||
|
@ -43,9 +43,9 @@ use rustc_span::symbol::{kw, Ident, Symbol};
|
|||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
use rustc_target::abi::Align;
|
use rustc_target::abi::Align;
|
||||||
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::Hash;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
use std::{fmt, ptr, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
pub use crate::ty::diagnostics::*;
|
pub use crate::ty::diagnostics::*;
|
||||||
pub use rustc_type_ir::InferTy::*;
|
pub use rustc_type_ir::InferTy::*;
|
||||||
@ -466,51 +466,50 @@ impl ty::EarlyBoundRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a predicate.
|
||||||
|
///
|
||||||
|
/// See comments on `TyS`, which apply here too (albeit for
|
||||||
|
/// `PredicateS`/`Predicate` rather than `TyS`/`Ty`).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
crate struct PredicateInner<'tcx> {
|
crate struct PredicateS<'tcx> {
|
||||||
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
||||||
flags: TypeFlags,
|
flags: TypeFlags,
|
||||||
/// See the comment for the corresponding field of [TyS].
|
/// See the comment for the corresponding field of [TyS].
|
||||||
outer_exclusive_binder: ty::DebruijnIndex,
|
outer_exclusive_binder: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This type is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||||
static_assert_size!(PredicateInner<'_>, 56);
|
static_assert_size!(PredicateS<'_>, 56);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Lift)]
|
/// Use this rather than `PredicateS`, whenever possible.
|
||||||
pub struct Predicate<'tcx> {
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
inner: &'tcx PredicateInner<'tcx>,
|
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
|
||||||
}
|
pub struct Predicate<'tcx>(Interned<'tcx, PredicateS<'tcx>>);
|
||||||
|
|
||||||
impl<'tcx> PartialEq for Predicate<'tcx> {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
// `self.kind` is always interned.
|
|
||||||
ptr::eq(self.inner, other.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for Predicate<'_> {
|
|
||||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
|
||||||
(self.inner as *const PredicateInner<'_>).hash(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Eq for Predicate<'tcx> {}
|
|
||||||
|
|
||||||
impl<'tcx> Predicate<'tcx> {
|
impl<'tcx> Predicate<'tcx> {
|
||||||
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
|
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
|
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
|
||||||
self.inner.kind
|
self.0.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn flags(self) -> TypeFlags {
|
||||||
|
self.0.flags
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
|
||||||
|
self.0.outer_exclusive_binder
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flips the polarity of a Predicate.
|
/// Flips the polarity of a Predicate.
|
||||||
///
|
///
|
||||||
/// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
|
/// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
|
||||||
pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
|
pub fn flip_polarity(self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
|
||||||
let kind = self
|
let kind = self
|
||||||
.inner
|
.kind()
|
||||||
.kind
|
|
||||||
.map_bound(|kind| match kind {
|
.map_bound(|kind| match kind {
|
||||||
PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
|
PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
|
||||||
Some(PredicateKind::Trait(TraitPredicate {
|
Some(PredicateKind::Trait(TraitPredicate {
|
||||||
@ -530,14 +529,14 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
let PredicateInner {
|
let PredicateS {
|
||||||
ref kind,
|
ref kind,
|
||||||
|
|
||||||
// The other fields just provide fast access to information that is
|
// The other fields just provide fast access to information that is
|
||||||
// also contained in `kind`, so no need to hash them.
|
// also contained in `kind`, so no need to hash them.
|
||||||
flags: _,
|
flags: _,
|
||||||
outer_exclusive_binder: _,
|
outer_exclusive_binder: _,
|
||||||
} = self.inner;
|
} = self.0.0;
|
||||||
|
|
||||||
kind.hash_stable(hcx, hasher);
|
kind.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
|
@ -1112,12 +1112,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
|||||||
self,
|
self,
|
||||||
folder: &mut F,
|
folder: &mut F,
|
||||||
) -> Result<Self, F::Error> {
|
) -> Result<Self, F::Error> {
|
||||||
let new = self.inner.kind.try_fold_with(folder)?;
|
let new = self.kind().try_fold_with(folder)?;
|
||||||
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
|
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
self.inner.kind.visit_with(visitor)
|
self.kind().visit_with(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
@ -1125,11 +1125,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||||
self.inner.outer_exclusive_binder > binder
|
self.outer_exclusive_binder() > binder
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
|
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
|
||||||
self.inner.flags.intersects(flags)
|
self.flags().intersects(flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
|||||||
trait_ref: &ty::TraitRef<'tcx>,
|
trait_ref: &ty::TraitRef<'tcx>,
|
||||||
item: Option<&hir::Item<'tcx>>,
|
item: Option<&hir::Item<'tcx>>,
|
||||||
cause: &mut traits::ObligationCause<'tcx>,
|
cause: &mut traits::ObligationCause<'tcx>,
|
||||||
pred: &ty::Predicate<'tcx>,
|
pred: ty::Predicate<'tcx>,
|
||||||
) {
|
) {
|
||||||
debug!(
|
debug!(
|
||||||
"extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
|
"extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
|
||||||
@ -319,7 +319,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||||||
trait_ref,
|
trait_ref,
|
||||||
item,
|
item,
|
||||||
&mut cause,
|
&mut cause,
|
||||||
&obligation.predicate,
|
obligation.predicate,
|
||||||
);
|
);
|
||||||
traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate)
|
traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate)
|
||||||
};
|
};
|
||||||
|
@ -39,7 +39,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
|
|||||||
// always only region relations, and we are about to
|
// always only region relations, and we are about to
|
||||||
// erase those anyway:
|
// erase those anyway:
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
normalized_obligations.iter().find(|p| not_outlives_predicate(&p.predicate)),
|
normalized_obligations.iter().find(|p| not_outlives_predicate(p.predicate)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq +
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn not_outlives_predicate<'tcx>(p: &ty::Predicate<'tcx>) -> bool {
|
fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool {
|
||||||
match p.kind().skip_binder() {
|
match p.kind().skip_binder() {
|
||||||
ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false,
|
ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false,
|
||||||
ty::PredicateKind::Trait(..)
|
ty::PredicateKind::Trait(..)
|
||||||
|
@ -703,7 +703,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let mut bound_spans = vec![];
|
let mut bound_spans = vec![];
|
||||||
|
|
||||||
let mut collect_type_param_suggestions =
|
let mut collect_type_param_suggestions =
|
||||||
|self_ty: Ty<'tcx>, parent_pred: &ty::Predicate<'tcx>, obligation: &str| {
|
|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.
|
// 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())
|
(self_ty.kind(), parent_pred.kind().skip_binder())
|
||||||
@ -892,7 +892,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred))
|
.filter(|(pred, _, _parent_pred)| !skip_list.contains(&pred))
|
||||||
.filter_map(|(pred, parent_pred, _cause)| {
|
.filter_map(|(pred, parent_pred, _cause)| {
|
||||||
format_pred(*pred).map(|(p, self_ty)| {
|
format_pred(*pred).map(|(p, self_ty)| {
|
||||||
collect_type_param_suggestions(self_ty, pred, &p);
|
collect_type_param_suggestions(self_ty, *pred, &p);
|
||||||
match parent_pred {
|
match parent_pred {
|
||||||
None => format!("`{}`", &p),
|
None => format!("`{}`", &p),
|
||||||
Some(parent_pred) => match format_pred(*parent_pred) {
|
Some(parent_pred) => match format_pred(*parent_pred) {
|
||||||
@ -900,7 +900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Some((parent_p, _)) => {
|
Some((parent_p, _)) => {
|
||||||
collect_type_param_suggestions(
|
collect_type_param_suggestions(
|
||||||
self_ty,
|
self_ty,
|
||||||
parent_pred,
|
*parent_pred,
|
||||||
&p,
|
&p,
|
||||||
);
|
);
|
||||||
format!("`{}`\nwhich is required by `{}`", p, parent_p)
|
format!("`{}`\nwhich is required by `{}`", p, parent_p)
|
||||||
|
Loading…
Reference in New Issue
Block a user