Rollup merge of #112870 - compiler-errors:clause-2, r=oli-obk

Migrate `item_bounds` to `ty::Clause`

Should be simpler than the next PR that's coming up. Last three commits are the relevant ones.

r? ``@oli-obk`` or ``@lcnr``
This commit is contained in:
Matthias Krüger 2023-06-23 19:39:59 +02:00 committed by GitHub
commit 4e8983050e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 245 additions and 176 deletions

View File

@ -705,7 +705,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(tcx, substs)
.find_map(find_fn_kind_from_did),
.find_map(|(clause, span)| find_fn_kind_from_did((clause.as_predicate(), span))),
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),

View File

@ -409,9 +409,7 @@ fn fn_sig_suggestion<'tcx>(
output = if let ty::Alias(_, alias_ty) = *output.kind() {
tcx.explicit_item_bounds(alias_ty.def_id)
.subst_iter_copied(tcx, alias_ty.substs)
.find_map(|(bound, _)| {
bound.to_opt_poly_projection_pred()?.no_bound_vars()?.term.ty()
})
.find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
.unwrap_or_else(|| {
span_bug!(
ident.span,

View File

@ -1086,7 +1086,7 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
wfcx.infcx,
wfcx.param_env,
wfcx.body_def_id,
normalized_bound,
normalized_bound.as_predicate(),
bound_span,
)
});
@ -1562,7 +1562,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
self.wfcx.infcx,
self.wfcx.param_env,
self.wfcx.body_def_id,
bound,
bound.as_predicate(),
bound_span,
));
// Set the debruijn index back to innermost here, since we already eagerly

View File

@ -19,7 +19,7 @@ fn associated_type_bounds<'tcx>(
assoc_item_def_id: LocalDefId,
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
let item_ty = tcx.mk_projection(
assoc_item_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
@ -33,8 +33,11 @@ fn associated_type_bounds<'tcx>(
let trait_def_id = tcx.local_parent(assoc_item_def_id);
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
match pred.kind().skip_binder() {
let bounds_from_parent = trait_predicates
.predicates
.iter()
.copied()
.filter(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => tr.self_ty() == item_ty,
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
proj.projection_ty.self_ty() == item_ty
@ -43,15 +46,10 @@ fn associated_type_bounds<'tcx>(
outlives.0 == item_ty
}
_ => false,
}
});
})
.map(|(pred, span)| (pred.expect_clause(), span));
let all_bounds = tcx.arena.alloc_from_iter(
bounds
.clauses()
.map(|(clause, span)| (clause.as_predicate(), span))
.chain(bounds_from_parent),
);
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
debug!(
"associated_type_bounds({}) = {:?}",
tcx.def_path_str(assoc_item_def_id.to_def_id()),
@ -71,7 +69,7 @@ fn opaque_type_bounds<'tcx>(
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
item_ty: Ty<'tcx>,
span: Span,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
ty::print::with_no_queries!({
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
@ -79,15 +77,14 @@ fn opaque_type_bounds<'tcx>(
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
debug!(?bounds);
tcx.arena
.alloc_from_iter(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)))
tcx.arena.alloc_from_iter(bounds.clauses())
})
}
pub(super) fn explicit_item_bounds(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
) -> ty::EarlyBinder<&'_ [(ty::Predicate<'_>, Span)]> {
) -> ty::EarlyBinder<&'_ [(ty::Clause<'_>, Span)]> {
match tcx.opt_rpitit_info(def_id.to_def_id()) {
// RPITIT's bounds are the same as opaque type bounds, but with
// a projection self type.
@ -139,11 +136,8 @@ pub(super) fn explicit_item_bounds(
pub(super) fn item_bounds(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> {
) -> ty::EarlyBinder<&'_ ty::List<ty::Clause<'_>>> {
tcx.explicit_item_bounds(def_id).map_bound(|bounds| {
tcx.mk_predicates_from_iter(util::elaborate(
tcx,
bounds.iter().map(|&(bound, _span)| bound),
))
tcx.mk_clauses_from_iter(util::elaborate(tcx, bounds.iter().map(|&(bound, _span)| bound)))
})
}

View File

@ -3,7 +3,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::query::Providers;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@ -17,7 +17,7 @@ pub fn provide(providers: &mut Providers) {
*providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers };
}
fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::ClauseKind<'_>, Span)] {
fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clause<'_>, Span)] {
let id = tcx.hir().local_def_id_to_hir_id(item_def_id);
if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst)
@ -52,7 +52,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
if tcx.has_attr(item_def_id, sym::rustc_outlives) {
let mut pred: Vec<String> = predicates
.iter()
.map(|(out_pred, _)| match out_pred {
.map(|(out_pred, _)| match out_pred.kind().skip_binder() {
ty::ClauseKind::RegionOutlives(p) => p.to_string(),
ty::ClauseKind::TypeOutlives(p) => p.to_string(),
err => bug!("unexpected clause {:?}", err),
@ -104,13 +104,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|(ty::OutlivesPredicate(kind1, region2), &span)| {
match kind1.unpack() {
GenericArgKind::Type(ty1) => Some((
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)),
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty1, *region2))
.to_predicate(tcx),
span,
)),
GenericArgKind::Lifetime(region1) => Some((
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
region1, *region2,
)),
))
.to_predicate(tcx),
span,
)),
GenericArgKind::Const(_) => {

View File

@ -162,28 +162,25 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
// which thus mentions `'a` and should thus accept hidden types that borrow 'a
// instead of requiring an additional `+ 'a`.
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef { def_id: _, substs, .. },
constness: _,
polarity: _,
})) => {
}) => {
for subst in &substs[1..] {
subst.visit_with(&mut collector);
}
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_ty: ty::AliasTy { substs, .. },
term,
})) => {
}) => {
for subst in &substs[1..] {
subst.visit_with(&mut collector);
}
term.visit_with(&mut collector);
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
_,
region,
))) => {
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_, region)) => {
region.visit_with(&mut collector);
}
_ => {

View File

@ -536,33 +536,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
for ty in [first_ty, second_ty] {
for (pred, _) in self
for (clause, _) in self
.tcx
.explicit_item_bounds(rpit_def_id)
.subst_iter_copied(self.tcx, substs)
{
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
let pred = clause.kind().rebind(match clause.kind().skip_binder() {
ty::ClauseKind::Trait(trait_pred) => {
// FIXME(rpitit): This will need to be fixed when we move to associated types
assert!(matches!(
*trait_pred.trait_ref.self_ty().kind(),
ty::Alias(_, ty::AliasTy { def_id, substs: alias_substs, .. })
if def_id == rpit_def_id && substs == alias_substs
));
ty::PredicateKind::Clause(ty::ClauseKind::Trait(
trait_pred.with_self_ty(self.tcx, ty),
))
ty::ClauseKind::Trait(trait_pred.with_self_ty(self.tcx, ty))
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(
mut proj_pred,
)) => {
ty::ClauseKind::Projection(mut proj_pred) => {
assert!(matches!(
*proj_pred.projection_ty.self_ty().kind(),
ty::Alias(_, ty::AliasTy { def_id, substs: alias_substs, .. })
if def_id == rpit_def_id && substs == alias_substs
));
proj_pred = proj_pred.with_self_ty(self.tcx, ty);
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj_pred))
ty::ClauseKind::Projection(proj_pred)
}
_ => continue,
});

View File

@ -174,7 +174,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self
.deduce_closure_signature_from_predicates(
expected_ty,
self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs),
self.tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(self.tcx, substs)
.map(|(c, s)| (c.as_predicate(), s)),
),
ty::Dynamic(ref object_type, ..) => {
let sig = object_type.projection_bounds().find_map(|pb| {
@ -717,13 +720,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(self.tcx, substs)
.find_map(|(p, s)| get_future_output(p, s))?,
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
ty::Error(_) => return None,
ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self
.tcx
.explicit_item_bounds(proj.def_id)
.subst_iter_copied(self.tcx, proj.substs)
.find_map(|(p, s)| get_future_output(p, s))?,
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
_ => span_bug!(
self.tcx.def_span(expr_def_id),
"async fn generator return type not an inference variable: {ret_ty}"

View File

@ -577,7 +577,7 @@ fn check_must_not_suspend_ty<'tcx>(
let mut has_emitted = false;
for &(predicate, _) in fcx.tcx.explicit_item_bounds(def).skip_binder() {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ref poly_trait_predicate)) =
if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
predicate.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;

View File

@ -408,9 +408,9 @@ impl<'tcx> InferCtxt<'tcx> {
predicate
.kind()
.map_bound(|kind| match kind {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(
projection_predicate,
)) if projection_predicate.projection_ty.def_id == item_def_id => {
ty::ClauseKind::Projection(projection_predicate)
if projection_predicate.projection_ty.def_id == item_def_id =>
{
projection_predicate.term.ty()
}
_ => None,

View File

@ -649,9 +649,7 @@ impl<'tcx> InferCtxt<'tcx> {
ct_op: |ct| ct,
});
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection)) =
predicate.kind().skip_binder()
{
if let ty::ClauseKind::Projection(projection) = predicate.kind().skip_binder() {
if projection.term.references_error() {
// No point on adding any obligations since there's a type error involved.
obligations.clear();

View File

@ -296,7 +296,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
trace!("{:#?}", bounds.skip_binder());
bounds
.subst_iter(tcx, alias_ty.substs)
.filter_map(|p| p.to_opt_type_outlives())
.filter_map(|p| p.as_type_outlives_clause())
.filter_map(|p| p.no_bound_vars())
.map(|OutlivesPredicate(_, r)| r)
}

View File

@ -167,13 +167,13 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) {
}
}
impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
impl<'tcx> Elaboratable<'tcx> for (ty::Clause<'tcx>, Span) {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.as_predicate()
self.0.as_predicate()
}
fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
predicate.as_clause().unwrap()
(predicate.expect_clause(), self.1)
}
fn child_with_derived_cause(
@ -183,7 +183,27 @@ impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
predicate.as_clause().unwrap()
(predicate.expect_clause(), self.1)
}
}
impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx> {
self.as_predicate()
}
fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
predicate.expect_clause()
}
fn child_with_derived_cause(
&self,
predicate: ty::Predicate<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
predicate.expect_clause()
}
}

View File

@ -1984,12 +1984,12 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
impl ExplicitOutlivesRequirements {
fn lifetimes_outliving_lifetime<'tcx>(
inferred_outlives: &'tcx [(ty::ClauseKind<'tcx>, Span)],
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
def_id: DefId,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(clause, _)| match *clause {
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b),
_ => None,
@ -2000,12 +2000,12 @@ impl ExplicitOutlivesRequirements {
}
fn lifetimes_outliving_type<'tcx>(
inferred_outlives: &'tcx [(ty::ClauseKind<'tcx>, Span)],
inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)],
index: u32,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives
.iter()
.filter_map(|(clause, _)| match *clause {
.filter_map(|(clause, _)| match clause.kind().skip_binder() {
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
a.is_param(index).then_some(b)
}

View File

@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// Liberate bound regions in the predicate since we
// don't actually care about lifetimes in this check.
let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind());
let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) = predicate else {
let ty::ClauseKind::Projection(proj) = predicate else {
continue;
};
// Only check types, since those are the only things that may
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
(
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }),
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)),
ty::ClauseKind::Trait(trait_pred),
) => Some(AddBound {
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
trait_ref: trait_pred.print_modifiers_and_trait_path(),

View File

@ -289,9 +289,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
.filter_only_self()
.find_map(|(pred, _span)| {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(
ref poly_trait_predicate,
)) = pred.kind().skip_binder()
if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
pred.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;

View File

@ -25,7 +25,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::GeneratorDiagnosticData;
use rustc_middle::ty::{self, ParameterizedOverTcx, Predicate, Ty, TyCtxt, Visibility};
use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
use rustc_serialize::opaque::MemDecoder;
use rustc_serialize::{Decodable, Decoder};
use rustc_session::cstore::{
@ -642,6 +642,12 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyValue<T> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
decoder.read_lazy()
@ -854,7 +860,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self,
index: DefIndex,
tcx: TyCtxt<'tcx>,
) -> ty::EarlyBinder<&'tcx [(Predicate<'tcx>, Span)]> {
) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
let lazy = self.root.tables.explicit_item_bounds.get(self, index);
let output = if lazy.is_default() {
&mut []

View File

@ -375,8 +375,8 @@ define_tables! {
is_type_alias_impl_trait: Table<DefIndex, bool>,
attr_flags: Table<DefIndex, AttrFlags>,
def_path_hashes: Table<DefIndex, DefPathHash>,
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::ClauseKind<'static>, Span)>>,
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,

View File

@ -346,7 +346,7 @@ rustc_queries! {
/// `key` is the `DefId` of the associated type or opaque type.
///
/// Bounds from the parent (e.g. with nested impl trait) are not included.
query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, Span)]> {
query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Clause<'tcx>, Span)]> {
desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
@ -373,7 +373,7 @@ rustc_queries! {
/// ```
///
/// Bounds from the parent (e.g. with nested impl trait) are not included.
query item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
query item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<ty::Clause<'tcx>>> {
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
}
@ -647,7 +647,7 @@ rustc_queries! {
/// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
query inferred_outlives_of(key: DefId) -> &'tcx [(ty::ClauseKind<'tcx>, Span)] {
query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] {
desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern

View File

@ -798,7 +798,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::ClauseKind<'tcx>, Span)] {
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
#[inline]
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)

View File

@ -128,6 +128,12 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Predicate<'tcx>
}
}
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Clause<'tcx> {
fn encode(&self, e: &mut E) {
self.as_predicate().encode(e);
}
}
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Region<'tcx> {
fn encode(&self, e: &mut E) {
self.kind().encode(e);
@ -241,6 +247,13 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Predicate<'tcx>
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Clause<'tcx> {
fn decode(decoder: &mut D) -> ty::Clause<'tcx> {
let pred: ty::Predicate<'tcx> = Decodable::decode(decoder);
pred.expect_clause()
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for SubstsRef<'tcx> {
fn decode(decoder: &mut D) -> Self {
let len = decoder.read_usize();
@ -365,9 +378,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
for [(ty::ClauseKind<'tcx>, Span)]
{
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] {
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.interner().arena.alloc_from_iter(
(0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),

View File

@ -25,10 +25,10 @@ use crate::traits::solve::{
ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData,
};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid,
GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions,
TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, FloatTy, FloatVar,
FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind,
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
};
use crate::ty::{GenericArg, InternalSubsts, SubstsRef};
use rustc_ast::{self as ast, attr};
@ -141,7 +141,9 @@ pub struct CtxtInterners<'tcx> {
region: InternedSet<'tcx, RegionKind<'tcx>>,
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
// FIXME(clause): remove this when all usages are moved to predicate
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, ConstData<'tcx>>,
@ -167,6 +169,7 @@ impl<'tcx> CtxtInterners<'tcx> {
canonical_var_infos: Default::default(),
predicate: Default::default(),
predicates: Default::default(),
clauses: Default::default(),
projs: Default::default(),
place_elems: Default::default(),
const_: Default::default(),
@ -1533,6 +1536,7 @@ slice_interners!(
canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
predicates: intern_predicates(Predicate<'tcx>),
clauses: intern_clauses(Clause<'tcx>),
projs: pub mk_projs(ProjectionKind),
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
@ -1564,7 +1568,7 @@ impl<'tcx> TyCtxt<'tcx> {
let future_trait = self.require_lang_item(LangItem::Future, None);
self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| {
let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) = predicate.kind().skip_binder() else {
let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
return false;
};
trait_predicate.trait_ref.def_id == future_trait
@ -2084,6 +2088,13 @@ impl<'tcx> TyCtxt<'tcx> {
self.intern_predicates(preds)
}
pub fn mk_clauses(self, preds: &[Clause<'tcx>]) -> &'tcx List<Clause<'tcx>> {
// FIXME consider asking the input slice to be sorted to avoid
// re-interning permutations, in which case that would be asserted
// here.
self.intern_clauses(preds)
}
pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
@ -2135,6 +2146,14 @@ impl<'tcx> TyCtxt<'tcx> {
T::collect_and_apply(iter, |xs| self.mk_predicates(xs))
}
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Clause<'tcx>, &'tcx List<Clause<'tcx>>>,
{
T::collect_and_apply(iter, |xs| self.mk_clauses(xs))
}
pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,

View File

@ -602,6 +602,24 @@ impl<'tcx> Clause<'tcx> {
None
}
}
pub fn as_type_outlives_clause(self) -> Option<Binder<'tcx, TypeOutlivesPredicate<'tcx>>> {
let clause = self.kind();
if let ty::ClauseKind::TypeOutlives(o) = clause.skip_binder() {
Some(clause.rebind(o))
} else {
None
}
}
pub fn as_region_outlives_clause(self) -> Option<Binder<'tcx, RegionOutlivesPredicate<'tcx>>> {
let clause = self.kind();
if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() {
Some(clause.rebind(o))
} else {
None
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
@ -713,7 +731,7 @@ pub struct CratePredicatesMap<'tcx> {
/// predicate of its outlive bounds. If an item has no outlives
/// bounds, it will have no entry.
// FIXME(clause): should this be a `Clause`?
pub predicates: FxHashMap<DefId, &'tcx [(ClauseKind<'tcx>, Span)]>,
pub predicates: FxHashMap<DefId, &'tcx [(Clause<'tcx>, Span)]>,
}
impl<'tcx> Predicate<'tcx> {
@ -1243,7 +1261,21 @@ impl<'tcx> ToPredicate<'tcx> for ClauseKind<'tcx> {
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, ClauseKind<'tcx>> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause)))
tcx.mk_predicate(self.map_bound(ty::PredicateKind::Clause))
}
}
impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> {
#[inline(always)]
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.as_predicate()
}
}
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ClauseKind<'tcx> {
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(self))).expect_clause()
}
}

View File

@ -128,6 +128,7 @@ parameterized_over_tcx! {
ty::TraitRef,
ty::Const,
ty::Predicate,
ty::Clause,
ty::ClauseKind,
ty::GeneratorDiagnosticData,
}

View File

@ -928,7 +928,7 @@ pub trait PrettyPrinter<'tcx>:
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
ty::ClauseKind::Trait(pred) => {
let trait_ref = bound_predicate.rebind(pred.trait_ref);
// Don't print + Sized, but rather + ?Sized if absent.
@ -939,7 +939,7 @@ pub trait PrettyPrinter<'tcx>:
self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits);
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
ty::ClauseKind::Projection(pred) => {
let proj_ref = bound_predicate.rebind(pred);
let trait_ref = proj_ref.required_poly_trait_ref(tcx);
@ -953,7 +953,7 @@ pub trait PrettyPrinter<'tcx>:
&mut fn_traits,
);
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
ty::ClauseKind::TypeOutlives(outlives) => {
lifetimes.push(outlives.1);
}
_ => {}

View File

@ -666,10 +666,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(folder
.try_fold_predicate(self.as_predicate())?
.as_clause()
.expect("no sensible folder would do this"))
Ok(folder.try_fold_predicate(self.as_predicate())?.expect_clause())
}
}
@ -713,6 +710,15 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> {
}
}
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Clause<'tcx>> {
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
ty::util::fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
}
}
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
self,

View File

@ -1824,7 +1824,7 @@ fn check_must_not_suspend_ty<'tcx>(
let mut has_emitted = false;
for &(predicate, _) in tcx.explicit_item_bounds(def).skip_binder() {
// We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ref poly_trait_predicate)) =
if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
predicate.kind().skip_binder()
{
let def_id = poly_trait_predicate.trait_ref.def_id;

View File

@ -114,6 +114,12 @@ trait DefIdVisitor<'tcx> {
) -> ControlFlow<Self::BreakTy> {
self.skeleton().visit_predicates(predicates)
}
fn visit_clauses(
&mut self,
predicates: &[(ty::Clause<'tcx>, Span)],
) -> ControlFlow<Self::BreakTy> {
self.skeleton().visit_clauses(predicates)
}
}
struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> {
@ -159,42 +165,23 @@ where
}
}
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref,
constness: _,
polarity: _,
})) => self.visit_trait(trait_ref),
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_ty,
term,
})) => {
fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> ControlFlow<V::BreakTy> {
match clause.kind().skip_binder() {
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => {
self.visit_trait(trait_ref)
}
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
term.visit_with(self)?;
self.visit_projection_ty(projection_ty)
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
ty,
_region,
))) => ty.visit_with(self),
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {
ControlFlow::Continue(())
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => ty.visit_with(self),
ty::ClauseKind::RegionOutlives(..) => ControlFlow::Continue(()),
ty::ClauseKind::ConstArgHasType(ct, ty) => {
ct.visit_with(self)?;
ty.visit_with(self)
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => ct.visit_with(self),
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => arg.visit_with(self),
ty::PredicateKind::ObjectSafe(_)
| ty::PredicateKind::ClosureKind(_, _, _)
| ty::PredicateKind::Subtype(_)
| ty::PredicateKind::Coerce(_)
| ty::PredicateKind::ConstEquate(_, _)
| ty::PredicateKind::TypeWellFormedFromEnv(_)
| ty::PredicateKind::Ambiguous
| ty::PredicateKind::AliasRelate(..) => bug!("unexpected predicate: {:?}", predicate),
ty::ClauseKind::ConstEvaluatable(ct) => ct.visit_with(self),
ty::ClauseKind::WellFormed(arg) => arg.visit_with(self),
}
}
@ -203,7 +190,16 @@ where
predicates: ty::GenericPredicates<'tcx>,
) -> ControlFlow<V::BreakTy> {
let ty::GenericPredicates { parent: _, predicates } = predicates;
predicates.iter().try_for_each(|&(predicate, _span)| self.visit_predicate(predicate))
predicates.iter().try_for_each(|&(predicate, _span)| {
let clause = predicate
.as_clause()
.unwrap_or_else(|| bug!("unexpected predicate: {:?}", predicate));
self.visit_clause(clause)
})
}
fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> ControlFlow<V::BreakTy> {
clauses.iter().try_for_each(|&(clause, _span)| self.visit_clause(clause))
}
}
@ -307,10 +303,7 @@ where
// through the trait list (default type visitor doesn't visit those traits).
// All traits in the list are considered the "primary" part of the type
// and are visited by shallow visitors.
self.visit_predicates(ty::GenericPredicates {
parent: None,
predicates: tcx.explicit_item_bounds(def_id).skip_binder(),
})?;
self.visit_clauses(tcx.explicit_item_bounds(def_id).skip_binder())?;
}
}
// These types don't have their own def-ids (but may have subcomponents
@ -1814,10 +1807,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
fn bounds(&mut self) -> &mut Self {
self.in_primary_interface = false;
self.visit_predicates(ty::GenericPredicates {
parent: None,
predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(),
});
self.visit_clauses(self.tcx.explicit_item_bounds(self.item_def_id).skip_binder());
self
}

View File

@ -522,13 +522,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
{
if let Some(clause) = assumption.as_clause() {
match G::consider_alias_bound_candidate(self, goal, clause) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
}
Err(NoSolution) => (),
match G::consider_alias_bound_candidate(self, goal, assumption) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
}
Err(NoSolution) => (),
}
}
}

View File

@ -353,7 +353,11 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
// FIXME(associated_const_equality): Also add associated consts to
// the requirements here.
if item.kind == ty::AssocKind::Type {
requirements.extend(tcx.item_bounds(item.def_id).subst(tcx, trait_ref.substs));
requirements.extend(
tcx.item_bounds(item.def_id)
.subst_iter(tcx, trait_ref.substs)
.map(|clause| clause.as_predicate()),
);
}
}

View File

@ -1157,7 +1157,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
self.tcx.item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) = pred.kind().skip_binder()
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()

View File

@ -271,7 +271,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied())
.filter_map(|pred_span| predicate_references_self(tcx, pred_span))
.filter_map(|(clause, span)| predicate_references_self(tcx, (clause.as_predicate(), span)))
.collect()
}

View File

@ -1585,7 +1585,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
obligation,
candidate_set,
ProjectionCandidate::TraitDef,
bounds.iter(),
bounds.iter().map(|clause| clause.as_predicate()),
true,
);
}

View File

@ -170,7 +170,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let candidate_predicate = tcx.item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
let candidate = candidate_predicate
.to_opt_poly_trait_pred()
.as_trait_clause()
.expect("projection candidate is not a trait predicate")
.map_bound(|t| t.trait_ref);
let mut obligations = Vec::new();
@ -631,7 +631,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let assoc_ty_substs = tcx.mk_substs(&substs);
let bound =
bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
ty::Binder::bind_with_vars(bound, bound_vars).to_predicate(tcx)
};
let normalized_bound = normalize_with_depth_to(
self,

View File

@ -1668,9 +1668,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.enumerate()
.filter_map(|(idx, bound)| {
let bound_predicate = bound.kind();
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
bound_predicate.skip_binder()
{
if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() {
let bound = bound_predicate.rebind(pred.trait_ref);
if self.infcx.probe(|_| {
match self.match_normalize_trait_ref(

View File

@ -54,7 +54,9 @@ impl<'tcx> RustIrDatabase<'tcx> {
.tcx
.explicit_item_bounds(def_id)
.subst_iter_copied(self.interner.tcx, &bound_vars)
.filter_map(|(bound, _)| LowerInto::<Option<_>>::lower_into(bound, self.interner))
.filter_map(|(bound, _)| {
LowerInto::<Option<_>>::lower_into(bound.as_predicate(), self.interner)
})
.collect()
}
}
@ -520,7 +522,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
.filter_map(|bound| {
LowerInto::<
Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>
>::lower_into(bound, self.interner)
>::lower_into(bound.as_predicate(), self.interner)
})
.collect();

View File

@ -1361,8 +1361,10 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
}
if let ty::TraitContainer = assoc_item.container {
let bounds =
tcx.explicit_item_bounds(assoc_item.def_id).subst_identity_iter_copied();
let bounds = tcx
.explicit_item_bounds(assoc_item.def_id)
.subst_identity_iter_copied()
.map(|(c, s)| (c.as_predicate(), s));
let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
let predicates =
tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
@ -2117,7 +2119,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
fn clean_middle_opaque_bounds<'tcx>(
cx: &mut DocContext<'tcx>,
bounds: Vec<ty::Predicate<'tcx>>,
bounds: Vec<ty::Clause<'tcx>>,
) -> Type {
let mut regions = vec![];
let mut has_sized = false;
@ -2126,13 +2128,8 @@ fn clean_middle_opaque_bounds<'tcx>(
.filter_map(|bound| {
let bound_predicate = bound.kind();
let trait_ref = match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => {
bound_predicate.rebind(tr.trait_ref)
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
_ty,
reg,
))) => {
ty::ClauseKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref),
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
if let Some(r) = clean_middle_region(reg) {
regions.push(GenericBound::Outlives(r));
}
@ -2149,9 +2146,7 @@ fn clean_middle_opaque_bounds<'tcx>(
let bindings: ThinVec<_> = bounds
.iter()
.filter_map(|bound| {
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =
bound.kind().skip_binder()
{
if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
Some(TypeBinding {
assoc: projection_to_path_segment(

View File

@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
let preds = cx.tcx.explicit_item_bounds(def_id);
let mut is_future = false;
for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) {
if let Some(trait_pred) = p.to_opt_poly_trait_pred() {
if let Some(trait_pred) = p.as_trait_clause() {
if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() {
is_future = true;
break;

View File

@ -94,7 +94,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
match predicate.kind().skip_binder() {
// For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
// and check substitutions to find `U`.
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
ty::ClauseKind::Trait(trait_predicate) => {
if trait_predicate
.trait_ref
.substs
@ -107,7 +107,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
},
// For `impl Trait<Assoc=U>`, it will register a predicate of `<T as Trait>::Assoc = U`,
// so we check the term for `U`.
ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection_predicate)) => {
ty::ClauseKind::Projection(projection_predicate) => {
if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack() {
if contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) {
return true;
@ -268,7 +268,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) = predicate.kind().skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
return true;
}
@ -665,7 +665,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds(
cx,
ty,
cx.tcx.item_bounds(def_id).subst(cx.tcx, substs),
cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs).map(|c| c.as_predicate()),
cx.tcx.opt_parent(def_id),
),
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
@ -698,7 +698,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
fn sig_from_bounds<'tcx>(
cx: &LateContext<'tcx>,
ty: Ty<'tcx>,
predicates: &'tcx [Predicate<'tcx>],
predicates: impl IntoIterator<Item = Predicate<'tcx>>,
predicates_id: Option<DefId>,
) -> Option<ExprFnSig<'tcx>> {
let mut inputs = None;
@ -747,7 +747,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
.subst_iter_copied(cx.tcx, ty.substs)
{
match pred.kind().skip_binder() {
PredicateKind::Clause(ty::ClauseKind::Trait(p))
ty::ClauseKind::Trait(p)
if (lang_items.fn_trait() == Some(p.def_id())
|| lang_items.fn_mut_trait() == Some(p.def_id())
|| lang_items.fn_once_trait() == Some(p.def_id())) =>
@ -760,7 +760,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
}
inputs = Some(i);
},
PredicateKind::Clause(ty::ClauseKind::Projection(p))
ty::ClauseKind::Projection(p)
if Some(p.projection_ty.def_id) == lang_items.fn_once_output() =>
{
if output.is_some() {