Migrate predicates_of and caller_bounds to Clause
This commit is contained in:
parent
36fb58e433
commit
fbdef58414
77 changed files with 478 additions and 705 deletions
|
@ -678,8 +678,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
// Find out if the predicates show that the type is a Fn or FnMut
|
// Find out if the predicates show that the type is a Fn or FnMut
|
||||||
let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| {
|
let find_fn_kind_from_did = |(pred, _): (ty::Clause<'tcx>, _)| {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = pred.kind().skip_binder()
|
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
|
||||||
&& pred.self_ty() == ty
|
&& pred.self_ty() == ty
|
||||||
{
|
{
|
||||||
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
|
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
|
||||||
|
@ -705,7 +705,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
|
||||||
.explicit_item_bounds(def_id)
|
.explicit_item_bounds(def_id)
|
||||||
.subst_iter_copied(tcx, substs)
|
.subst_iter_copied(tcx, substs)
|
||||||
.find_map(|(clause, span)| find_fn_kind_from_did((clause.as_predicate(), span))),
|
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
|
||||||
ty::Closure(_, substs) => match substs.as_closure().kind() {
|
ty::Closure(_, substs) => match substs.as_closure().kind() {
|
||||||
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
||||||
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
||||||
|
|
|
@ -928,7 +928,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
fn any_param_predicate_mentions(
|
fn any_param_predicate_mentions(
|
||||||
&self,
|
&self,
|
||||||
predicates: &[ty::Predicate<'tcx>],
|
clauses: &[ty::Clause<'tcx>],
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
region: ty::EarlyBoundRegion,
|
region: ty::EarlyBoundRegion,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -937,10 +937,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
&& let ty::Param(_) = ty.kind()
|
&& let ty::Param(_) = ty.kind()
|
||||||
{
|
{
|
||||||
predicates.iter().any(|pred| {
|
clauses.iter().any(|pred| {
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) if data.self_ty() == ty => {}
|
ty::ClauseKind::Trait(data) if data.self_ty() == ty => {}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) if data.projection_ty.self_ty() == ty => {}
|
ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
|
||||||
_ => return false,
|
_ => return false,
|
||||||
}
|
}
|
||||||
tcx.any_free_region_meets(pred, |r| {
|
tcx.any_free_region_meets(pred, |r| {
|
||||||
|
|
|
@ -945,40 +945,29 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
let mut trait_bounds = vec![];
|
let mut trait_bounds = vec![];
|
||||||
let mut projection_bounds = vec![];
|
let mut projection_bounds = vec![];
|
||||||
for (clause, span) in bounds.clauses() {
|
for (pred, span) in bounds.clauses() {
|
||||||
let pred: ty::Predicate<'tcx> = clause.as_predicate();
|
|
||||||
let bound_pred = pred.kind();
|
let bound_pred = pred.kind();
|
||||||
match bound_pred.skip_binder() {
|
match bound_pred.skip_binder() {
|
||||||
ty::PredicateKind::Clause(clause) => match clause {
|
ty::ClauseKind::Trait(trait_pred) => {
|
||||||
ty::ClauseKind::Trait(trait_pred) => {
|
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
|
||||||
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
|
trait_bounds.push((
|
||||||
trait_bounds.push((
|
bound_pred.rebind(trait_pred.trait_ref),
|
||||||
bound_pred.rebind(trait_pred.trait_ref),
|
span,
|
||||||
span,
|
trait_pred.constness,
|
||||||
trait_pred.constness,
|
));
|
||||||
));
|
}
|
||||||
}
|
ty::ClauseKind::Projection(proj) => {
|
||||||
ty::ClauseKind::Projection(proj) => {
|
projection_bounds.push((bound_pred.rebind(proj), span));
|
||||||
projection_bounds.push((bound_pred.rebind(proj), span));
|
}
|
||||||
}
|
ty::ClauseKind::TypeOutlives(_) => {
|
||||||
ty::ClauseKind::TypeOutlives(_) => {
|
// Do nothing, we deal with regions separately
|
||||||
// Do nothing, we deal with regions separately
|
}
|
||||||
}
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
ty::ClauseKind::RegionOutlives(_)
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
| ty::ClauseKind::ConstArgHasType(..)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::ConstEvaluatable(_) => {
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
bug!()
|
||||||
bug!()
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
|
||||||
| ty::PredicateKind::ClosureKind(_, _, _)
|
|
||||||
| ty::PredicateKind::Subtype(_)
|
|
||||||
| ty::PredicateKind::Coerce(_)
|
|
||||||
| ty::PredicateKind::ConstEquate(_, _)
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(_)
|
|
||||||
| ty::PredicateKind::Ambiguous => bug!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,9 +1414,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|| {
|
|| {
|
||||||
traits::transitive_bounds_that_define_assoc_item(
|
traits::transitive_bounds_that_define_assoc_item(
|
||||||
tcx,
|
tcx,
|
||||||
predicates.iter().filter_map(|(p, _)| {
|
predicates
|
||||||
Some(p.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref))
|
.iter()
|
||||||
}),
|
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
|
||||||
assoc_name,
|
assoc_name,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -220,7 +220,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
// the new hybrid bounds we computed.
|
// the new hybrid bounds we computed.
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates(&hybrid_preds.predicates),
|
tcx.mk_clauses(&hybrid_preds.predicates),
|
||||||
Reveal::UserFacing,
|
Reveal::UserFacing,
|
||||||
hir::Constness::NotConst,
|
hir::Constness::NotConst,
|
||||||
);
|
);
|
||||||
|
@ -1835,7 +1835,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
let impl_ty_span = tcx.def_span(impl_ty_def_id);
|
let impl_ty_span = tcx.def_span(impl_ty_def_id);
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates(&hybrid_preds.predicates),
|
tcx.mk_clauses(&hybrid_preds.predicates),
|
||||||
Reveal::UserFacing,
|
Reveal::UserFacing,
|
||||||
hir::Constness::NotConst,
|
hir::Constness::NotConst,
|
||||||
);
|
);
|
||||||
|
@ -2011,7 +2011,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
.to_predicate(tcx),
|
.to_predicate(tcx),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness())
|
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing, param_env.constness())
|
||||||
};
|
};
|
||||||
debug!(?normalize_param_env);
|
debug!(?normalize_param_env);
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,7 @@ fn default_body_is_unstable(
|
||||||
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
|
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
|
||||||
fn bounds_from_generic_predicates<'tcx>(
|
fn bounds_from_generic_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
|
||||||
) -> (String, String) {
|
) -> (String, String) {
|
||||||
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
|
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
|
||||||
let mut projections = vec![];
|
let mut projections = vec![];
|
||||||
|
@ -304,7 +304,7 @@ fn bounds_from_generic_predicates<'tcx>(
|
||||||
debug!("predicate {:?}", predicate);
|
debug!("predicate {:?}", predicate);
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
ty::ClauseKind::Trait(trait_predicate) => {
|
||||||
let entry = types.entry(trait_predicate.self_ty()).or_default();
|
let entry = types.entry(trait_predicate.self_ty()).or_default();
|
||||||
let def_id = trait_predicate.def_id();
|
let def_id = trait_predicate.def_id();
|
||||||
if Some(def_id) != tcx.lang_items().sized_trait() {
|
if Some(def_id) != tcx.lang_items().sized_trait() {
|
||||||
|
@ -313,7 +313,7 @@ fn bounds_from_generic_predicates<'tcx>(
|
||||||
entry.push(trait_predicate.def_id());
|
entry.push(trait_predicate.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection_pred)) => {
|
ty::ClauseKind::Projection(projection_pred) => {
|
||||||
projections.push(bound_predicate.rebind(projection_pred));
|
projections.push(bound_predicate.rebind(projection_pred));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -362,7 +362,7 @@ fn fn_sig_suggestion<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
sig: ty::FnSig<'tcx>,
|
sig: ty::FnSig<'tcx>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
|
||||||
assoc: ty::AssocItem,
|
assoc: ty::AssocItem,
|
||||||
) -> String {
|
) -> String {
|
||||||
let args = sig
|
let args = sig
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
||||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
|
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
|
||||||
|
@ -322,7 +322,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
// Gather the bounds with which all other items inside of this trait constrain the GAT.
|
// Gather the bounds with which all other items inside of this trait constrain the GAT.
|
||||||
// This is calculated by taking the intersection of the bounds that each item
|
// This is calculated by taking the intersection of the bounds that each item
|
||||||
// constrains the GAT with individually.
|
// constrains the GAT with individually.
|
||||||
let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
|
let mut new_required_bounds: Option<FxHashSet<ty::Clause<'_>>> = None;
|
||||||
for item in associated_items {
|
for item in associated_items {
|
||||||
let item_def_id = item.id.owner_id;
|
let item_def_id = item.id.owner_id;
|
||||||
// Skip our own GAT, since it does not constrain itself at all.
|
// Skip our own GAT, since it does not constrain itself at all.
|
||||||
|
@ -419,9 +419,17 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
let mut unsatisfied_bounds: Vec<_> = required_bounds
|
let mut unsatisfied_bounds: Vec<_> = required_bounds
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|clause| match clause.kind().skip_binder() {
|
.filter(|clause| match clause.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
|
||||||
ty::OutlivesPredicate(a, b),
|
!region_known_to_outlive(
|
||||||
)) => !region_known_to_outlive(
|
tcx,
|
||||||
|
gat_def_id.def_id,
|
||||||
|
param_env,
|
||||||
|
&FxIndexSet::default(),
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => !ty_known_to_outlive(
|
||||||
tcx,
|
tcx,
|
||||||
gat_def_id.def_id,
|
gat_def_id.def_id,
|
||||||
param_env,
|
param_env,
|
||||||
|
@ -429,18 +437,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
),
|
),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
|
_ => bug!("Unexpected ClauseKind"),
|
||||||
a,
|
|
||||||
b,
|
|
||||||
))) => !ty_known_to_outlive(
|
|
||||||
tcx,
|
|
||||||
gat_def_id.def_id,
|
|
||||||
param_env,
|
|
||||||
&FxIndexSet::default(),
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
),
|
|
||||||
_ => bug!("Unexpected PredicateKind"),
|
|
||||||
})
|
})
|
||||||
.map(|clause| clause.to_string())
|
.map(|clause| clause.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -488,7 +485,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
fn augment_param_env<'tcx>(
|
fn augment_param_env<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
new_predicates: Option<&FxHashSet<ty::Predicate<'tcx>>>,
|
new_predicates: Option<&FxHashSet<ty::Clause<'tcx>>>,
|
||||||
) -> ty::ParamEnv<'tcx> {
|
) -> ty::ParamEnv<'tcx> {
|
||||||
let Some(new_predicates) = new_predicates else {
|
let Some(new_predicates) = new_predicates else {
|
||||||
return param_env;
|
return param_env;
|
||||||
|
@ -498,7 +495,7 @@ fn augment_param_env<'tcx>(
|
||||||
return param_env;
|
return param_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bounds = tcx.mk_predicates_from_iter(
|
let bounds = tcx.mk_clauses_from_iter(
|
||||||
param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
|
param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
|
||||||
);
|
);
|
||||||
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
|
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
|
||||||
|
@ -524,7 +521,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
wf_tys: &FxIndexSet<Ty<'tcx>>,
|
wf_tys: &FxIndexSet<Ty<'tcx>>,
|
||||||
gat_def_id: LocalDefId,
|
gat_def_id: LocalDefId,
|
||||||
gat_generics: &'tcx ty::Generics,
|
gat_generics: &'tcx ty::Generics,
|
||||||
) -> Option<FxHashSet<ty::Predicate<'tcx>>> {
|
) -> Option<FxHashSet<ty::Clause<'tcx>>> {
|
||||||
// The bounds we that we would require from `to_check`
|
// The bounds we that we would require from `to_check`
|
||||||
let mut bounds = FxHashSet::default();
|
let mut bounds = FxHashSet::default();
|
||||||
|
|
||||||
|
@ -573,11 +570,10 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
);
|
);
|
||||||
// The predicate we expect to see. (In our example,
|
// The predicate we expect to see. (In our example,
|
||||||
// `Self: 'me`.)
|
// `Self: 'me`.)
|
||||||
let clause = ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
|
bounds.insert(
|
||||||
ty::OutlivesPredicate(ty_param, region_param),
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_param, region_param))
|
||||||
));
|
.to_predicate(tcx),
|
||||||
let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
|
);
|
||||||
bounds.insert(clause);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,11 +618,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// The predicate we expect to see.
|
// The predicate we expect to see.
|
||||||
let clause = ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
bounds.insert(
|
||||||
ty::OutlivesPredicate(region_a_param, region_b_param),
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
||||||
));
|
region_a_param,
|
||||||
let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
|
region_b_param,
|
||||||
bounds.insert(clause);
|
))
|
||||||
|
.to_predicate(tcx),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1406,7 +1404,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
infcx,
|
infcx,
|
||||||
wfcx.param_env.without_const(),
|
wfcx.param_env.without_const(),
|
||||||
wfcx.body_def_id,
|
wfcx.body_def_id,
|
||||||
p,
|
p.as_predicate(),
|
||||||
sp,
|
sp,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1875,9 +1873,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
// We lower empty bounds like `Vec<dyn Copy>:` as
|
// We lower empty bounds like `Vec<dyn Copy>:` as
|
||||||
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
|
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
|
||||||
// regular WF checking
|
// regular WF checking
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) =
|
if let ty::ClauseKind::WellFormed(..) = pred.kind().skip_binder() {
|
||||||
pred.kind().skip_binder()
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Match the existing behavior.
|
// Match the existing behavior.
|
||||||
|
|
|
@ -38,16 +38,12 @@ fn associated_type_bounds<'tcx>(
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|(pred, _)| match pred.kind().skip_binder() {
|
.filter(|(pred, _)| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => tr.self_ty() == item_ty,
|
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
|
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
|
||||||
proj.projection_ty.self_ty() == item_ty
|
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
|
|
||||||
outlives.0 == item_ty
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
.map(|(pred, span)| (pred.expect_clause(), span));
|
.map(|(clause, span)| (clause, span));
|
||||||
|
|
||||||
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
|
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -75,7 +75,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
|
|
||||||
// We use an `IndexSet` to preserve order of insertion.
|
// We use an `IndexSet` to preserve order of insertion.
|
||||||
// Preserving the order of insertion is important here so as not to break UI tests.
|
// Preserving the order of insertion is important here so as not to break UI tests.
|
||||||
let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default();
|
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
|
||||||
|
|
||||||
let ast_generics = match node {
|
let ast_generics = match node {
|
||||||
Node::TraitItem(item) => item.generics,
|
Node::TraitItem(item) => item.generics,
|
||||||
|
@ -126,8 +126,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
predicates.extend(
|
predicates.extend(
|
||||||
icx.astconv()
|
icx.astconv()
|
||||||
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
|
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
|
||||||
.clauses()
|
.clauses(),
|
||||||
.map(|(clause, span)| (clause.as_predicate(), span)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,8 +175,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
param.span,
|
param.span,
|
||||||
);
|
);
|
||||||
trace!(?bounds);
|
trace!(?bounds);
|
||||||
predicates
|
predicates.extend(bounds.clauses());
|
||||||
.extend(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)));
|
|
||||||
trace!(?predicates);
|
trace!(?predicates);
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { .. } => {
|
GenericParamKind::Const { .. } => {
|
||||||
|
@ -188,11 +186,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
|
|
||||||
let ct = tcx.mk_const(param_const, ct_ty);
|
let ct = tcx.mk_const(param_const, ct_ty);
|
||||||
|
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
|
predicates.insert((
|
||||||
ty::ClauseKind::ConstArgHasType(ct, ct_ty),
|
ty::ClauseKind::ConstArgHasType(ct, ct_ty).to_predicate(tcx),
|
||||||
))
|
param.span,
|
||||||
.to_predicate(tcx);
|
));
|
||||||
predicates.insert((predicate, param.span));
|
|
||||||
|
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +218,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
} else {
|
} else {
|
||||||
let span = bound_pred.bounded_ty.span;
|
let span = bound_pred.bounded_ty.span;
|
||||||
let predicate = ty::Binder::bind_with_vars(
|
let predicate = ty::Binder::bind_with_vars(
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty.into())),
|
ty::ClauseKind::WellFormed(ty.into()),
|
||||||
bound_vars,
|
bound_vars,
|
||||||
);
|
);
|
||||||
predicates.insert((predicate.to_predicate(tcx), span));
|
predicates.insert((predicate.to_predicate(tcx), span));
|
||||||
|
@ -236,8 +233,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
bound_vars,
|
bound_vars,
|
||||||
OnlySelfBounds(false),
|
OnlySelfBounds(false),
|
||||||
);
|
);
|
||||||
predicates
|
predicates.extend(bounds.clauses());
|
||||||
.extend(bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::WherePredicate::RegionPredicate(region_pred) => {
|
hir::WherePredicate::RegionPredicate(region_pred) => {
|
||||||
|
@ -249,11 +245,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
}
|
}
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let pred = ty::Binder::dummy(ty::PredicateKind::Clause(
|
let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2))
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)),
|
.to_predicate(icx.tcx);
|
||||||
))
|
|
||||||
.to_predicate(icx.tcx);
|
|
||||||
|
|
||||||
(pred, span)
|
(pred, span)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -318,17 +311,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
predicates.push((
|
predicates.push((
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
|
||||||
ty::OutlivesPredicate(orig_region, dup_region),
|
.to_predicate(icx.tcx),
|
||||||
)))
|
|
||||||
.to_predicate(icx.tcx),
|
|
||||||
duplicate.span,
|
duplicate.span,
|
||||||
));
|
));
|
||||||
predicates.push((
|
predicates.push((
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
|
||||||
ty::OutlivesPredicate(dup_region, orig_region),
|
.to_predicate(icx.tcx),
|
||||||
)))
|
|
||||||
.to_predicate(icx.tcx),
|
|
||||||
duplicate.span,
|
duplicate.span,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -344,10 +333,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
fn const_evaluatable_predicates_of(
|
fn const_evaluatable_predicates_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> FxIndexSet<(ty::Predicate<'_>, Span)> {
|
) -> FxIndexSet<(ty::Clause<'_>, Span)> {
|
||||||
struct ConstCollector<'tcx> {
|
struct ConstCollector<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>,
|
preds: FxIndexSet<(ty::Clause<'tcx>, Span)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
|
impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
|
||||||
|
@ -355,13 +344,8 @@ fn const_evaluatable_predicates_of(
|
||||||
let ct = ty::Const::from_anon_const(self.tcx, c.def_id);
|
let ct = ty::Const::from_anon_const(self.tcx, c.def_id);
|
||||||
if let ty::ConstKind::Unevaluated(_) = ct.kind() {
|
if let ty::ConstKind::Unevaluated(_) = ct.kind() {
|
||||||
let span = self.tcx.def_span(c.def_id);
|
let span = self.tcx.def_span(c.def_id);
|
||||||
self.preds.insert((
|
self.preds
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(
|
.insert((ty::ClauseKind::ConstEvaluatable(ct).to_predicate(self.tcx), span));
|
||||||
ct,
|
|
||||||
)))
|
|
||||||
.to_predicate(self.tcx),
|
|
||||||
span,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,15 +433,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|(pred, _)| match pred.kind().skip_binder() {
|
.filter(|(pred, _)| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr)) => {
|
ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
|
||||||
!is_assoc_item_ty(tr.self_ty())
|
ty::ClauseKind::Projection(proj) => !is_assoc_item_ty(proj.projection_ty.self_ty()),
|
||||||
}
|
ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
|
|
||||||
!is_assoc_item_ty(proj.projection_ty.self_ty())
|
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
|
|
||||||
!is_assoc_item_ty(outlives.0)
|
|
||||||
}
|
|
||||||
_ => true,
|
_ => true,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -498,9 +476,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(pred, _)| {
|
.filter(|(pred, _)| {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) =
|
if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
|
||||||
pred.kind().skip_binder()
|
|
||||||
{
|
|
||||||
match ct.kind() {
|
match ct.kind() {
|
||||||
ty::ConstKind::Param(param_const) => {
|
ty::ConstKind::Param(param_const) => {
|
||||||
let defaulted_param_idx = tcx
|
let defaulted_param_idx = tcx
|
||||||
|
@ -665,12 +641,8 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Combine the two lists to form the complete set of superbounds:
|
// Combine the two lists to form the complete set of superbounds:
|
||||||
let implied_bounds = &*tcx.arena.alloc_from_iter(
|
let implied_bounds =
|
||||||
superbounds
|
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
|
||||||
.clauses()
|
|
||||||
.map(|(clause, span)| (clause.as_predicate(), span))
|
|
||||||
.chain(where_bounds_that_match),
|
|
||||||
);
|
|
||||||
debug!(?implied_bounds);
|
debug!(?implied_bounds);
|
||||||
|
|
||||||
// Now require that immediate supertraits are converted, which will, in
|
// Now require that immediate supertraits are converted, which will, in
|
||||||
|
@ -679,7 +651,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
if matches!(filter, PredicateFilter::SelfOnly) {
|
if matches!(filter, PredicateFilter::SelfOnly) {
|
||||||
for &(pred, span) in implied_bounds {
|
for &(pred, span) in implied_bounds {
|
||||||
debug!("superbound: {:?}", pred);
|
debug!("superbound: {:?}", pred);
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(bound)) = pred.kind().skip_binder()
|
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
|
||||||
&& bound.polarity == ty::ImplPolarity::Positive
|
&& bound.polarity == ty::ImplPolarity::Positive
|
||||||
{
|
{
|
||||||
tcx.at(span).super_predicates_of(bound.def_id());
|
tcx.at(span).super_predicates_of(bound.def_id());
|
||||||
|
@ -776,9 +748,7 @@ pub(super) fn type_param_predicates(
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(predicate, _)| match predicate.kind().skip_binder() {
|
.filter(|(predicate, _)| match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
|
ty::ClauseKind::Trait(data) => data.self_ty().is_param(index),
|
||||||
data.self_ty().is_param(index)
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -800,7 +770,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
assoc_name: Option<Ident>,
|
assoc_name: Option<Ident>,
|
||||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
) -> Vec<(ty::Clause<'tcx>, Span)> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
|
|
||||||
for predicate in ast_generics.predicates {
|
for predicate in ast_generics.predicates {
|
||||||
|
@ -829,7 +799,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds.clauses().map(|(clause, span)| (clause.as_predicate(), span)).collect()
|
bounds.clauses().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
|
|
|
@ -1761,7 +1761,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
|
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
|
ty::ClauseKind::Trait(data) => {
|
||||||
// The order here needs to match what we would get from `subst_supertrait`
|
// The order here needs to match what we would get from `subst_supertrait`
|
||||||
let pred_bound_vars = bound_predicate.bound_vars();
|
let pred_bound_vars = bound_predicate.bound_vars();
|
||||||
let mut all_bound_vars = bound_vars.clone();
|
let mut all_bound_vars = bound_vars.clone();
|
||||||
|
|
|
@ -151,7 +151,7 @@ pub fn identify_constrained_generic_params<'tcx>(
|
||||||
/// think of any.
|
/// think of any.
|
||||||
pub fn setup_constraining_predicates<'tcx>(
|
pub fn setup_constraining_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicates: &mut [(ty::Predicate<'tcx>, Span)],
|
predicates: &mut [(ty::Clause<'tcx>, Span)],
|
||||||
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||||
input_parameters: &mut FxHashSet<Parameter>,
|
input_parameters: &mut FxHashSet<Parameter>,
|
||||||
) {
|
) {
|
||||||
|
@ -187,9 +187,7 @@ pub fn setup_constraining_predicates<'tcx>(
|
||||||
for j in i..predicates.len() {
|
for j in i..predicates.len() {
|
||||||
// Note that we don't have to care about binders here,
|
// Note that we don't have to care about binders here,
|
||||||
// as the impl trait ref never contains any late-bound regions.
|
// as the impl trait ref never contains any late-bound regions.
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(projection)) =
|
if let ty::ClauseKind::Projection(projection) = predicates[j].0.kind().skip_binder() {
|
||||||
predicates[j].0.kind().skip_binder()
|
|
||||||
{
|
|
||||||
// Special case: watch out for some kind of sneaky attempt
|
// Special case: watch out for some kind of sneaky attempt
|
||||||
// to project out an associated type defined by this very
|
// to project out an associated type defined by this very
|
||||||
// trait.
|
// trait.
|
||||||
|
|
|
@ -235,10 +235,8 @@ fn unconstrained_parent_impl_substs<'tcx>(
|
||||||
// what we want here. We want only a list of constrained parameters while
|
// what we want here. We want only a list of constrained parameters while
|
||||||
// the functions in `cgp` add the constrained parameters to a list of
|
// the functions in `cgp` add the constrained parameters to a list of
|
||||||
// unconstrained parameters.
|
// unconstrained parameters.
|
||||||
for (predicate, _) in impl_generic_predicates.predicates.iter() {
|
for (clause, _) in impl_generic_predicates.predicates.iter() {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =
|
if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() {
|
||||||
predicate.kind().skip_binder()
|
|
||||||
{
|
|
||||||
let projection_ty = proj.projection_ty;
|
let projection_ty = proj.projection_ty;
|
||||||
let projected_ty = proj.term;
|
let projected_ty = proj.term;
|
||||||
|
|
||||||
|
@ -340,8 +338,11 @@ fn check_predicates<'tcx>(
|
||||||
impl2_substs: SubstsRef<'tcx>,
|
impl2_substs: SubstsRef<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
|
let impl1_predicates: Vec<_> = traits::elaborate(
|
||||||
let impl1_predicates: Vec<_> = traits::elaborate(tcx, instantiated.into_iter()).collect();
|
tcx,
|
||||||
|
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).into_iter(),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
let mut impl2_predicates = if impl2_node.is_from_trait() {
|
let mut impl2_predicates = if impl2_node.is_from_trait() {
|
||||||
// Always applicable traits have to be always applicable without any
|
// Always applicable traits have to be always applicable without any
|
||||||
|
@ -352,8 +353,8 @@ fn check_predicates<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.predicates_of(impl2_node.def_id())
|
tcx.predicates_of(impl2_node.def_id())
|
||||||
.instantiate(tcx, impl2_substs)
|
.instantiate(tcx, impl2_substs)
|
||||||
.predicates
|
.into_iter()
|
||||||
.into_iter(),
|
.map(|(c, _s)| c.as_predicate()),
|
||||||
)
|
)
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
@ -377,13 +378,13 @@ fn check_predicates<'tcx>(
|
||||||
let always_applicable_traits = impl1_predicates
|
let always_applicable_traits = impl1_predicates
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|&(predicate, _)| {
|
.filter(|(clause, _span)| {
|
||||||
matches!(
|
matches!(
|
||||||
trait_predicate_kind(tcx, predicate),
|
trait_predicate_kind(tcx, clause.as_predicate()),
|
||||||
Some(TraitSpecializationKind::AlwaysApplicable)
|
Some(TraitSpecializationKind::AlwaysApplicable)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(pred, _span)| pred);
|
.map(|(c, _span)| c.as_predicate());
|
||||||
|
|
||||||
// Include the well-formed predicates of the type parameters of the impl.
|
// Include the well-formed predicates of the type parameters of the impl.
|
||||||
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity().substs {
|
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity().substs {
|
||||||
|
@ -398,9 +399,12 @@ fn check_predicates<'tcx>(
|
||||||
}
|
}
|
||||||
impl2_predicates.extend(traits::elaborate(tcx, always_applicable_traits));
|
impl2_predicates.extend(traits::elaborate(tcx, always_applicable_traits));
|
||||||
|
|
||||||
for (predicate, span) in impl1_predicates {
|
for (clause, span) in impl1_predicates {
|
||||||
if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(tcx, predicate, *pred2, span)) {
|
if !impl2_predicates
|
||||||
check_specialization_on(tcx, predicate, span)
|
.iter()
|
||||||
|
.any(|pred2| trait_predicates_eq(tcx, clause.as_predicate(), *pred2, span))
|
||||||
|
{
|
||||||
|
check_specialization_on(tcx, clause.as_predicate(), span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,40 +30,30 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
// process predicates and convert to `RequiredPredicates` entry, see below
|
// process predicates and convert to `RequiredPredicates` entry, see below
|
||||||
for &(predicate, span) in predicates.predicates {
|
for &(predicate, span) in predicates.predicates {
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(OutlivesPredicate(
|
ty::ClauseKind::TypeOutlives(OutlivesPredicate(ty, reg)) => {
|
||||||
ty,
|
insert_outlives_predicate(
|
||||||
reg,
|
tcx,
|
||||||
))) => insert_outlives_predicate(
|
ty.into(),
|
||||||
tcx,
|
reg,
|
||||||
ty.into(),
|
span,
|
||||||
reg,
|
&mut required_predicates,
|
||||||
span,
|
)
|
||||||
&mut required_predicates,
|
}
|
||||||
),
|
|
||||||
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
|
ty::ClauseKind::RegionOutlives(OutlivesPredicate(reg1, reg2)) => {
|
||||||
OutlivesPredicate(reg1, reg2),
|
insert_outlives_predicate(
|
||||||
)) => insert_outlives_predicate(
|
tcx,
|
||||||
tcx,
|
reg1.into(),
|
||||||
reg1.into(),
|
reg2,
|
||||||
reg2,
|
span,
|
||||||
span,
|
&mut required_predicates,
|
||||||
&mut required_predicates,
|
)
|
||||||
),
|
}
|
||||||
|
ty::ClauseKind::Trait(_)
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
| ty::ClauseKind::ConstEvaluatable(_) => {}
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Subtype(..)
|
|
||||||
| ty::PredicateKind::Coerce(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,16 +25,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
|
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
ty::ClauseKind::Trait(pred) => pred.trait_ref.substs.to_vec(),
|
||||||
pred.trait_ref.substs.to_vec()
|
ty::ClauseKind::Projection(pred) => pred.projection_ty.substs.to_vec(),
|
||||||
}
|
ty::ClauseKind::ConstArgHasType(arg, ty) => {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
|
|
||||||
pred.projection_ty.substs.to_vec()
|
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(arg, ty)) => {
|
|
||||||
vec![ty.into(), arg.into()]
|
vec![ty.into(), arg.into()]
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(e)) => vec![e.into()],
|
ty::ClauseKind::ConstEvaluatable(e) => vec![e.into()],
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -512,11 +508,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// This shouldn't happen, but since this is only a diagnostic improvement, avoid breaking things.
|
// This shouldn't happen, but since this is only a diagnostic improvement, avoid breaking things.
|
||||||
return Err(expr);
|
return Err(expr);
|
||||||
}
|
}
|
||||||
let relevant_broken_predicate: ty::PredicateKind<'tcx> =
|
|
||||||
impl_predicates.predicates[impl_predicate_index].0.kind().skip_binder();
|
|
||||||
|
|
||||||
match relevant_broken_predicate {
|
match impl_predicates.predicates[impl_predicate_index].0.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(broken_trait)) => {
|
ty::ClauseKind::Trait(broken_trait) => {
|
||||||
// ...
|
// ...
|
||||||
self.blame_specific_part_of_expr_corresponding_to_generic_param(
|
self.blame_specific_part_of_expr_corresponding_to_generic_param(
|
||||||
broken_trait.trait_ref.self_ty().into(),
|
broken_trait.trait_ref.self_ty().into(),
|
||||||
|
|
|
@ -1948,7 +1948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// do that, so it's OK.
|
// do that, so it's OK.
|
||||||
for (predicate, span) in instantiated
|
for (predicate, span) in instantiated
|
||||||
{
|
{
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = predicate.kind().skip_binder()
|
if let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder()
|
||||||
&& pred.self_ty().peel_refs() == callee_ty
|
&& pred.self_ty().peel_refs() == callee_ty
|
||||||
&& self.tcx.is_fn_trait(pred.def_id())
|
&& self.tcx.is_fn_trait(pred.def_id())
|
||||||
{
|
{
|
||||||
|
|
|
@ -226,9 +226,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
predicates: tcx.arena.alloc_from_iter(
|
predicates: tcx.arena.alloc_from_iter(
|
||||||
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data))
|
ty::ClauseKind::Trait(data) if data.self_ty().is_param(index) => {
|
||||||
if data.self_ty().is_param(index) =>
|
|
||||||
{
|
|
||||||
// HACK(eddyb) should get the original `Span`.
|
// HACK(eddyb) should get the original `Span`.
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
Some((predicate, span))
|
Some((predicate, span))
|
||||||
|
|
|
@ -606,9 +606,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
traits::elaborate(self.tcx, predicates.predicates.iter().copied())
|
traits::elaborate(self.tcx, predicates.predicates.iter().copied())
|
||||||
// We don't care about regions here.
|
// We don't care about regions here.
|
||||||
.filter_map(|pred| match pred.kind().skip_binder() {
|
.filter_map(|pred| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred))
|
ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => {
|
||||||
if trait_pred.def_id() == sized_def_id =>
|
|
||||||
{
|
|
||||||
let span = predicates
|
let span = predicates
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(p, span)| if p == pred { Some(span) } else { None })
|
.find_map(|(p, span)| if p == pred { Some(span) } else { None })
|
||||||
|
|
|
@ -834,7 +834,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
ty::ClauseKind::Trait(trait_predicate) => {
|
||||||
match *trait_predicate.trait_ref.self_ty().kind() {
|
match *trait_predicate.trait_ref.self_ty().kind() {
|
||||||
ty::Param(p) if p == param_ty => {
|
ty::Param(p) if p == param_ty => {
|
||||||
Some(bound_predicate.rebind(trait_predicate.trait_ref))
|
Some(bound_predicate.rebind(trait_predicate.trait_ref))
|
||||||
|
@ -842,20 +842,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(..)
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::ClauseKind::TypeOutlives(_)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
| ty::ClauseKind::ConstEvaluatable(_) => None,
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -739,10 +739,8 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
||||||
self.obligations.push(Obligation {
|
self.obligations.push(Obligation {
|
||||||
cause: self.cause.clone(),
|
cause: self.cause.clone(),
|
||||||
param_env: self.param_env,
|
param_env: self.param_env,
|
||||||
predicate: ty::Binder::dummy(ty::PredicateKind::Clause(
|
predicate: ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(sup, sub))
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(sup, sub)),
|
.to_predicate(self.infcx.tcx),
|
||||||
))
|
|
||||||
.to_predicate(self.infcx.tcx),
|
|
||||||
recursion_depth: 0,
|
recursion_depth: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,27 +20,18 @@ pub fn explicit_outlives_bounds<'tcx>(
|
||||||
param_env
|
param_env
|
||||||
.caller_bounds()
|
.caller_bounds()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(ty::Predicate::kind)
|
.map(ty::Clause::kind)
|
||||||
.filter_map(ty::Binder::no_bound_vars)
|
.filter_map(ty::Binder::no_bound_vars)
|
||||||
.filter_map(move |kind| match kind {
|
.filter_map(move |kind| match kind {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
}
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
ty::ClauseKind::Trait(_)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::ClauseKind::TypeOutlives(_)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::ClauseKind::ConstEvaluatable(_) => None,
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
|
||||||
r_a,
|
|
||||||
r_b,
|
|
||||||
))) => Some(OutlivesBound::RegionSubRegion(r_b, r_a)),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
// parameter environments are already elaborated, so we don't
|
// parameter environments are already elaborated, so we don't
|
||||||
// have to worry about that.
|
// have to worry about that.
|
||||||
let c_b = self.param_env.caller_bounds();
|
let c_b = self.param_env.caller_bounds();
|
||||||
let param_bounds = self.collect_outlives_from_predicate_list(erased_ty, c_b.into_iter());
|
let param_bounds = self.collect_outlives_from_clause_list(erased_ty, c_b.into_iter());
|
||||||
|
|
||||||
// Next, collect regions we scraped from the well-formedness
|
// Next, collect regions we scraped from the well-formedness
|
||||||
// constraints in the fn signature. To do that, we walk the list
|
// constraints in the fn signature. To do that, we walk the list
|
||||||
|
@ -307,15 +307,15 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
||||||
/// when comparing `ty` for equality, so `ty` must be something
|
/// when comparing `ty` for equality, so `ty` must be something
|
||||||
/// that does not involve inference variables and where you
|
/// that does not involve inference variables and where you
|
||||||
/// otherwise want a precise match.
|
/// otherwise want a precise match.
|
||||||
fn collect_outlives_from_predicate_list(
|
fn collect_outlives_from_clause_list(
|
||||||
&self,
|
&self,
|
||||||
erased_ty: Ty<'tcx>,
|
erased_ty: Ty<'tcx>,
|
||||||
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
clauses: impl Iterator<Item = ty::Clause<'tcx>>,
|
||||||
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
|
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
|
||||||
{
|
{
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
predicates.filter_map(|p| p.to_opt_type_outlives()).filter(move |outlives_predicate| {
|
clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| {
|
||||||
super::test_type_match::can_match_erased_ty(
|
super::test_type_match::can_match_erased_ty(
|
||||||
tcx,
|
tcx,
|
||||||
param_env,
|
param_env,
|
||||||
|
|
|
@ -258,7 +258,8 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
||||||
pred = pred.without_const(tcx);
|
pred = pred.without_const(tcx);
|
||||||
}
|
}
|
||||||
elaboratable.child_with_derived_cause(
|
elaboratable.child_with_derived_cause(
|
||||||
pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
|
pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref))
|
||||||
|
.as_predicate(),
|
||||||
span,
|
span,
|
||||||
bound_predicate.rebind(data),
|
bound_predicate.rebind(data),
|
||||||
index,
|
index,
|
||||||
|
@ -440,7 +441,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
|
||||||
tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name));
|
tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name));
|
||||||
for (super_predicate, _) in super_predicates.predicates {
|
for (super_predicate, _) in super_predicates.predicates {
|
||||||
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
|
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
|
||||||
if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() {
|
if let Some(binder) = subst_predicate.as_trait_clause() {
|
||||||
stack.push(binder.map_bound(|t| t.trait_ref));
|
stack.push(binder.map_bound(|t| t.trait_ref));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1593,33 +1593,24 @@ declare_lint_pass!(
|
||||||
impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||||
use rustc_middle::ty::ClauseKind;
|
use rustc_middle::ty::ClauseKind;
|
||||||
use rustc_middle::ty::PredicateKind::*;
|
|
||||||
|
|
||||||
if cx.tcx.features().trivial_bounds {
|
if cx.tcx.features().trivial_bounds {
|
||||||
let predicates = cx.tcx.predicates_of(item.owner_id);
|
let predicates = cx.tcx.predicates_of(item.owner_id);
|
||||||
for &(predicate, span) in predicates.predicates {
|
for &(predicate, span) in predicates.predicates {
|
||||||
let predicate_kind_name = match predicate.kind().skip_binder() {
|
let predicate_kind_name = match predicate.kind().skip_binder() {
|
||||||
Clause(ClauseKind::Trait(..)) => "trait",
|
ClauseKind::Trait(..) => "trait",
|
||||||
Clause(ClauseKind::TypeOutlives(..)) |
|
ClauseKind::TypeOutlives(..) |
|
||||||
Clause(ClauseKind::RegionOutlives(..)) => "lifetime",
|
ClauseKind::RegionOutlives(..) => "lifetime",
|
||||||
|
|
||||||
// `ConstArgHasType` is never global as `ct` is always a param
|
// `ConstArgHasType` is never global as `ct` is always a param
|
||||||
Clause(ClauseKind::ConstArgHasType(..)) |
|
ClauseKind::ConstArgHasType(..)
|
||||||
// Ignore projections, as they can only be global
|
// Ignore projections, as they can only be global
|
||||||
// if the trait bound is global
|
// if the trait bound is global
|
||||||
Clause(ClauseKind::Projection(..)) |
|
| ClauseKind::Projection(..)
|
||||||
// Ignore bounds that a user can't type
|
// Ignore bounds that a user can't type
|
||||||
Clause(ClauseKind::WellFormed(..)) |
|
| ClauseKind::WellFormed(..)
|
||||||
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
||||||
Clause(ClauseKind::ConstEvaluatable(..)) |
|
| ClauseKind::ConstEvaluatable(..) => continue,
|
||||||
AliasRelate(..) |
|
|
||||||
ObjectSafe(..) |
|
|
||||||
ClosureKind(..) |
|
|
||||||
Subtype(..) |
|
|
||||||
Coerce(..) |
|
|
||||||
ConstEquate(..) |
|
|
||||||
Ambiguous |
|
|
||||||
TypeWellFormedFromEnv(..) => continue,
|
|
||||||
};
|
};
|
||||||
if predicate.is_global() {
|
if predicate.is_global() {
|
||||||
cx.emit_spanned_lint(
|
cx.emit_spanned_lint(
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_errors::{
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
inhabitedness::InhabitedPredicate, PolyExistentialTraitRef, Predicate, Ty, TyCtxt,
|
inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
|
||||||
};
|
};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
|
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
|
||||||
|
@ -352,7 +352,7 @@ impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
|
||||||
#[diag(lint_builtin_trivial_bounds)]
|
#[diag(lint_builtin_trivial_bounds)]
|
||||||
pub struct BuiltinTrivialBounds<'a> {
|
pub struct BuiltinTrivialBounds<'a> {
|
||||||
pub predicate_kind_name: &'a str,
|
pub predicate_kind_name: &'a str,
|
||||||
pub predicate: Predicate<'a>,
|
pub predicate: Clause<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
|
@ -1262,7 +1262,7 @@ pub struct RedundantSemicolonsDiag {
|
||||||
|
|
||||||
// traits.rs
|
// traits.rs
|
||||||
pub struct DropTraitConstraintsDiag<'a> {
|
pub struct DropTraitConstraintsDiag<'a> {
|
||||||
pub predicate: Predicate<'a>,
|
pub predicate: Clause<'a>,
|
||||||
pub tcx: TyCtxt<'a>,
|
pub tcx: TyCtxt<'a>,
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
|
||||||
.super_predicates_of(def_id)
|
.super_predicates_of(def_id)
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(pred, _)| pred.to_opt_poly_trait_pred());
|
.filter_map(|(pred, _)| pred.as_trait_clause());
|
||||||
if direct_super_traits_iter.count() > 1 {
|
if direct_super_traits_iter.count() > 1 {
|
||||||
cx.emit_spanned_lint(
|
cx.emit_spanned_lint(
|
||||||
MULTIPLE_SUPERTRAIT_UPCASTABLE,
|
MULTIPLE_SUPERTRAIT_UPCASTABLE,
|
||||||
|
|
|
@ -88,11 +88,10 @@ declare_lint_pass!(
|
||||||
impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||||
use rustc_middle::ty::ClauseKind;
|
use rustc_middle::ty::ClauseKind;
|
||||||
use rustc_middle::ty::PredicateKind::*;
|
|
||||||
|
|
||||||
let predicates = cx.tcx.explicit_predicates_of(item.owner_id);
|
let predicates = cx.tcx.explicit_predicates_of(item.owner_id);
|
||||||
for &(predicate, span) in predicates.predicates {
|
for &(predicate, span) in predicates.predicates {
|
||||||
let Clause(ClauseKind::Trait(trait_predicate)) = predicate.kind().skip_binder() else {
|
let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else {
|
||||||
continue
|
continue
|
||||||
};
|
};
|
||||||
let def_id = trait_predicate.trait_ref.def_id;
|
let def_id = trait_predicate.trait_ref.def_id;
|
||||||
|
|
|
@ -636,12 +636,6 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
|
|
||||||
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
|
|
||||||
ty::codec::RefDecodable::decode(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
|
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||||
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
|
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
|
||||||
ty::codec::RefDecodable::decode(d)
|
ty::codec::RefDecodable::decode(d)
|
||||||
|
|
|
@ -83,9 +83,9 @@ macro_rules! arena_types {
|
||||||
rustc_middle::infer::canonical::Canonical<'tcx,
|
rustc_middle::infer::canonical::Canonical<'tcx,
|
||||||
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
|
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
|
||||||
>,
|
>,
|
||||||
[] type_op_normalize_predicate:
|
[] type_op_normalize_clause:
|
||||||
rustc_middle::infer::canonical::Canonical<'tcx,
|
rustc_middle::infer::canonical::Canonical<'tcx,
|
||||||
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Predicate<'tcx>>
|
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Clause<'tcx>>
|
||||||
>,
|
>,
|
||||||
[] type_op_normalize_ty:
|
[] type_op_normalize_ty:
|
||||||
rustc_middle::infer::canonical::Canonical<'tcx,
|
rustc_middle::infer::canonical::Canonical<'tcx,
|
||||||
|
|
|
@ -420,7 +420,7 @@ impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> {
|
impl<'tcx> Key for &'tcx ty::List<ty::Clause<'tcx>> {
|
||||||
type CacheSelector = DefaultCacheSelector<Self>;
|
type CacheSelector = DefaultCacheSelector<Self>;
|
||||||
|
|
||||||
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
fn default_span(&self, _: TyCtxt<'_>) -> Span {
|
||||||
|
|
|
@ -2031,10 +2031,10 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do not call this query directly: part of the `Normalize` type-op
|
/// Do not call this query directly: part of the `Normalize` type-op
|
||||||
query type_op_normalize_predicate(
|
query type_op_normalize_clause(
|
||||||
goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>
|
goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Clause<'tcx>>
|
||||||
) -> Result<
|
) -> Result<
|
||||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>,
|
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Clause<'tcx>>>,
|
||||||
NoSolution,
|
NoSolution,
|
||||||
> {
|
> {
|
||||||
desc { "normalizing `{:?}`", goal.value.value.value }
|
desc { "normalizing `{:?}`", goal.value.value.value }
|
||||||
|
@ -2125,7 +2125,7 @@ rustc_queries! {
|
||||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Clause<'tcx>>) -> &'tcx ty::List<ty::Clause<'tcx>> {
|
||||||
desc { "revealing opaque types in `{:?}`", key }
|
desc { "revealing opaque types in `{:?}`", key }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -791,13 +791,6 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
|
|
||||||
#[inline]
|
|
||||||
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
|
||||||
RefDecodable::decode(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
|
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
|
||||||
|
|
|
@ -385,7 +385,7 @@ impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
|
||||||
/// A chalk environment and goal.
|
/// A chalk environment and goal.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)]
|
||||||
pub struct ChalkEnvironmentAndGoal<'tcx> {
|
pub struct ChalkEnvironmentAndGoal<'tcx> {
|
||||||
pub environment: &'tcx ty::List<ty::Predicate<'tcx>>,
|
pub environment: &'tcx ty::List<ty::Clause<'tcx>>,
|
||||||
pub goal: ty::Predicate<'tcx>,
|
pub goal: ty::Predicate<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@ impl<'tcx> Elaborator<'tcx> {
|
||||||
.super_predicates_of(trait_ref.def_id())
|
.super_predicates_of(trait_ref.def_id())
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|(pred, _)| {
|
.flat_map(|(pred, _)| pred.subst_supertrait(self.tcx, &trait_ref).as_trait_clause())
|
||||||
pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_pred()
|
|
||||||
})
|
|
||||||
.map(|t| t.map_bound(|pred| pred.trait_ref))
|
.map(|t| t.map_bound(|pred| pred.trait_ref))
|
||||||
.filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
|
.filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
|
||||||
|
|
||||||
|
|
|
@ -368,16 +368,6 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AdtDef<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
|
||||||
for [(ty::Predicate<'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<_>>(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] {
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] {
|
||||||
fn decode(decoder: &mut D) -> &'tcx Self {
|
fn decode(decoder: &mut D) -> &'tcx Self {
|
||||||
decoder.interner().arena.alloc_from_iter(
|
decoder.interner().arena.alloc_from_iter(
|
||||||
|
@ -406,11 +396,11 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Predicate<'tcx>> {
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Clause<'tcx>> {
|
||||||
fn decode(decoder: &mut D) -> &'tcx Self {
|
fn decode(decoder: &mut D) -> &'tcx Self {
|
||||||
let len = decoder.read_usize();
|
let len = decoder.read_usize();
|
||||||
decoder.interner().mk_predicates_from_iter(
|
decoder.interner().mk_clauses_from_iter(
|
||||||
(0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)),
|
(0..len).map::<ty::Clause<'tcx>, _>(|_| Decodable::decode(decoder)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +424,7 @@ impl_decodable_via_ref! {
|
||||||
&'tcx mir::BorrowCheckResult<'tcx>,
|
&'tcx mir::BorrowCheckResult<'tcx>,
|
||||||
&'tcx mir::coverage::CodeRegion,
|
&'tcx mir::coverage::CodeRegion,
|
||||||
&'tcx ty::List<ty::BoundVariableKind>,
|
&'tcx ty::List<ty::BoundVariableKind>,
|
||||||
&'tcx ty::List<ty::Predicate<'tcx>>,
|
&'tcx ty::List<ty::Clause<'tcx>>,
|
||||||
&'tcx ty::List<FieldIdx>,
|
&'tcx ty::List<FieldIdx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,8 +141,6 @@ pub struct CtxtInterners<'tcx> {
|
||||||
region: InternedSet<'tcx, RegionKind<'tcx>>,
|
region: InternedSet<'tcx, RegionKind<'tcx>>,
|
||||||
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
|
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
|
||||||
predicate: InternedSet<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'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>>>,
|
clauses: InternedSet<'tcx, List<Clause<'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>>>,
|
||||||
|
@ -168,7 +166,6 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||||
poly_existential_predicates: Default::default(),
|
poly_existential_predicates: Default::default(),
|
||||||
canonical_var_infos: Default::default(),
|
canonical_var_infos: Default::default(),
|
||||||
predicate: Default::default(),
|
predicate: Default::default(),
|
||||||
predicates: Default::default(),
|
|
||||||
clauses: Default::default(),
|
clauses: Default::default(),
|
||||||
projs: Default::default(),
|
projs: Default::default(),
|
||||||
place_elems: Default::default(),
|
place_elems: Default::default(),
|
||||||
|
@ -1260,10 +1257,11 @@ nop_lift! {region; Region<'a> => Region<'tcx>}
|
||||||
nop_lift! {const_; Const<'a> => Const<'tcx>}
|
nop_lift! {const_; Const<'a> => Const<'tcx>}
|
||||||
nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
|
nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>}
|
||||||
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
|
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
|
||||||
|
nop_lift! {predicate; Clause<'a> => Clause<'tcx>}
|
||||||
|
|
||||||
nop_list_lift! {type_lists; Ty<'a> => Ty<'tcx>}
|
nop_list_lift! {type_lists; Ty<'a> => Ty<'tcx>}
|
||||||
nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>}
|
nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>}
|
||||||
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
|
nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
|
||||||
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
|
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
|
||||||
nop_list_lift! {projs; ProjectionKind => ProjectionKind}
|
nop_list_lift! {projs; ProjectionKind => ProjectionKind}
|
||||||
nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
|
nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
|
||||||
|
@ -1541,7 +1539,6 @@ slice_interners!(
|
||||||
type_lists: pub mk_type_list(Ty<'tcx>),
|
type_lists: pub mk_type_list(Ty<'tcx>),
|
||||||
canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
|
canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
|
||||||
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
|
poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
|
||||||
predicates: intern_predicates(Predicate<'tcx>),
|
|
||||||
clauses: intern_clauses(Clause<'tcx>),
|
clauses: intern_clauses(Clause<'tcx>),
|
||||||
projs: pub mk_projs(ProjectionKind),
|
projs: pub mk_projs(ProjectionKind),
|
||||||
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
|
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
|
||||||
|
@ -1597,9 +1594,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let generic_predicates = self.super_predicates_of(trait_did);
|
let generic_predicates = self.super_predicates_of(trait_did);
|
||||||
|
|
||||||
for (predicate, _) in generic_predicates.predicates {
|
for (predicate, _) in generic_predicates.predicates {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) =
|
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
|
||||||
predicate.kind().skip_binder()
|
|
||||||
{
|
|
||||||
if set.insert(data.def_id()) {
|
if set.insert(data.def_id()) {
|
||||||
stack.push(data.def_id());
|
stack.push(data.def_id());
|
||||||
}
|
}
|
||||||
|
@ -2087,18 +2082,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.intern_poly_existential_predicates(eps)
|
self.intern_poly_existential_predicates(eps)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
|
pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> &'tcx List<Clause<'tcx>> {
|
||||||
// FIXME consider asking the input slice to be sorted to avoid
|
// FIXME consider asking the input slice to be sorted to avoid
|
||||||
// re-interning permutations, in which case that would be asserted
|
// re-interning permutations, in which case that would be asserted
|
||||||
// here.
|
// here.
|
||||||
self.intern_predicates(preds)
|
self.intern_clauses(clauses)
|
||||||
}
|
|
||||||
|
|
||||||
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
|
pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
|
||||||
|
@ -2144,14 +2132,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
|
T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_predicates_from_iter<I, T>(self, iter: I) -> T::Output
|
|
||||||
where
|
|
||||||
I: Iterator<Item = T>,
|
|
||||||
T: CollectAndApply<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>,
|
|
||||||
{
|
|
||||||
T::collect_and_apply(iter, |xs| self.mk_predicates(xs))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
|
pub fn mk_clauses_from_iter<I, T>(self, iter: I) -> T::Output
|
||||||
where
|
where
|
||||||
I: Iterator<Item = T>,
|
I: Iterator<Item = T>,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_span::symbol::{kw, Symbol};
|
use rustc_span::symbol::{kw, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt};
|
use super::{Clause, EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, TyCtxt};
|
||||||
|
|
||||||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
pub enum GenericParamDefKind {
|
pub enum GenericParamDefKind {
|
||||||
|
@ -323,7 +323,7 @@ impl<'tcx> Generics {
|
||||||
#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
pub struct GenericPredicates<'tcx> {
|
pub struct GenericPredicates<'tcx> {
|
||||||
pub parent: Option<DefId>,
|
pub parent: Option<DefId>,
|
||||||
pub predicates: &'tcx [(Predicate<'tcx>, Span)],
|
pub predicates: &'tcx [(Clause<'tcx>, Span)],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> GenericPredicates<'tcx> {
|
impl<'tcx> GenericPredicates<'tcx> {
|
||||||
|
@ -341,8 +341,7 @@ impl<'tcx> GenericPredicates<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
) -> impl Iterator<Item = (Predicate<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
) -> impl Iterator<Item = (Clause<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator {
|
||||||
{
|
|
||||||
EarlyBinder::bind(self.predicates).subst_iter_copied(tcx, substs)
|
EarlyBinder::bind(self.predicates).subst_iter_copied(tcx, substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,12 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
|
||||||
|
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||||
|
rustc_errors::DiagnosticArgValue::Str(std::borrow::Cow::Owned(self.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A subset of predicates which can be assumed by the trait solver. They show up in
|
/// A subset of predicates which can be assumed by the trait solver. They show up in
|
||||||
/// an item's where clauses, hence the name `Clause`, and may either be user-written
|
/// an item's where clauses, hence the name `Clause`, and may either be user-written
|
||||||
/// (such as traits) or may be inserted during lowering.
|
/// (such as traits) or may be inserted during lowering.
|
||||||
|
@ -620,6 +626,10 @@ impl<'tcx> Clause<'tcx> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
|
||||||
|
self.as_predicate().without_const(tcx).expect_clause()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||||
|
@ -730,11 +740,10 @@ pub struct CratePredicatesMap<'tcx> {
|
||||||
/// For each struct with outlive bounds, maps to a vector of the
|
/// For each struct with outlive bounds, maps to a vector of the
|
||||||
/// predicate of its outlive bounds. If an item has no outlives
|
/// predicate of its outlive bounds. If an item has no outlives
|
||||||
/// bounds, it will have no entry.
|
/// bounds, it will have no entry.
|
||||||
// FIXME(clause): should this be a `Clause`?
|
|
||||||
pub predicates: FxHashMap<DefId, &'tcx [(Clause<'tcx>, Span)]>,
|
pub predicates: FxHashMap<DefId, &'tcx [(Clause<'tcx>, Span)]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Predicate<'tcx> {
|
impl<'tcx> Clause<'tcx> {
|
||||||
/// Performs a substitution suitable for going from a
|
/// Performs a substitution suitable for going from a
|
||||||
/// poly-trait-ref to supertraits that must hold if that
|
/// poly-trait-ref to supertraits that must hold if that
|
||||||
/// poly-trait-ref holds. This is slightly different from a normal
|
/// poly-trait-ref holds. This is slightly different from a normal
|
||||||
|
@ -744,7 +753,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||||
) -> Predicate<'tcx> {
|
) -> Clause<'tcx> {
|
||||||
// The interaction between HRTB and supertraits is not entirely
|
// The interaction between HRTB and supertraits is not entirely
|
||||||
// obvious. Let me walk you (and myself) through an example.
|
// obvious. Let me walk you (and myself) through an example.
|
||||||
//
|
//
|
||||||
|
@ -830,7 +839,13 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
// 3) ['x] + ['b] -> ['x, 'b]
|
// 3) ['x] + ['b] -> ['x, 'b]
|
||||||
let bound_vars =
|
let bound_vars =
|
||||||
tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
|
tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
|
||||||
tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars))
|
|
||||||
|
// FIXME: Is it really perf sensitive to use reuse_or_mk_predicate here?
|
||||||
|
tcx.reuse_or_mk_predicate(
|
||||||
|
self.as_predicate(),
|
||||||
|
ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars),
|
||||||
|
)
|
||||||
|
.expect_clause()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,6 +1316,14 @@ impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitPredicate<'tcx> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
|
||||||
|
let p: Predicate<'tcx> = self.to_predicate(tcx);
|
||||||
|
p.expect_clause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||||
|
@ -1456,8 +1479,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns a predicate into a clause without checking that it is a `PredicateKind::Clause`
|
/// Assert that the predicate is a clause.
|
||||||
/// first. This will ICE when methods are called on `Clause`.
|
|
||||||
pub fn expect_clause(self) -> Clause<'tcx> {
|
pub fn expect_clause(self) -> Clause<'tcx> {
|
||||||
match self.kind().skip_binder() {
|
match self.kind().skip_binder() {
|
||||||
PredicateKind::Clause(..) => Clause(self.0),
|
PredicateKind::Clause(..) => Clause(self.0),
|
||||||
|
@ -1487,7 +1509,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
/// [usize:Bar<isize>]]`.
|
/// [usize:Bar<isize>]]`.
|
||||||
#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
|
#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
|
||||||
pub struct InstantiatedPredicates<'tcx> {
|
pub struct InstantiatedPredicates<'tcx> {
|
||||||
pub predicates: Vec<Predicate<'tcx>>,
|
pub predicates: Vec<Clause<'tcx>>,
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1506,9 +1528,9 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
|
impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
|
||||||
type Item = (Predicate<'tcx>, Span);
|
type Item = (Clause<'tcx>, Span);
|
||||||
|
|
||||||
type IntoIter = std::iter::Zip<std::vec::IntoIter<Predicate<'tcx>>, std::vec::IntoIter<Span>>;
|
type IntoIter = std::iter::Zip<std::vec::IntoIter<Clause<'tcx>>, std::vec::IntoIter<Span>>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
||||||
|
@ -1517,10 +1539,10 @@ impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
|
impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
|
||||||
type Item = (Predicate<'tcx>, Span);
|
type Item = (Clause<'tcx>, Span);
|
||||||
|
|
||||||
type IntoIter = std::iter::Zip<
|
type IntoIter = std::iter::Zip<
|
||||||
std::iter::Copied<std::slice::Iter<'a, Predicate<'tcx>>>,
|
std::iter::Copied<std::slice::Iter<'a, Clause<'tcx>>>,
|
||||||
std::iter::Copied<std::slice::Iter<'a, Span>>,
|
std::iter::Copied<std::slice::Iter<'a, Span>>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -1670,7 +1692,7 @@ pub struct ParamEnv<'tcx> {
|
||||||
/// want `Reveal::All`.
|
/// want `Reveal::All`.
|
||||||
///
|
///
|
||||||
/// Note: This is packed, use the reveal() method to access it.
|
/// Note: This is packed, use the reveal() method to access it.
|
||||||
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, ParamTag, true>,
|
packed: CopyTaggedPtr<&'tcx List<Clause<'tcx>>, ParamTag, true>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -1736,7 +1758,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn caller_bounds(self) -> &'tcx List<Predicate<'tcx>> {
|
pub fn caller_bounds(self) -> &'tcx List<Clause<'tcx>> {
|
||||||
self.packed.pointer()
|
self.packed.pointer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1770,7 +1792,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
/// Construct a trait environment with the given set of predicates.
|
/// Construct a trait environment with the given set of predicates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
caller_bounds: &'tcx List<Predicate<'tcx>>,
|
caller_bounds: &'tcx List<Clause<'tcx>>,
|
||||||
reveal: Reveal,
|
reveal: Reveal,
|
||||||
constness: hir::Constness,
|
constness: hir::Constness,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
@ -2864,20 +2864,35 @@ define_print_and_forward_display! {
|
||||||
p!(print(binder))
|
p!(print(binder))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::Clause<'tcx> {
|
||||||
|
p!(print(self.kind()))
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::ClauseKind<'tcx> {
|
||||||
|
match *self {
|
||||||
|
ty::ClauseKind::Trait(ref data) => {
|
||||||
|
p!(print(data))
|
||||||
|
}
|
||||||
|
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||||
|
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||||
|
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
||||||
|
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||||
|
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||||
|
},
|
||||||
|
ty::ClauseKind::WellFormed(arg) => p!(print(arg), " well-formed"),
|
||||||
|
ty::ClauseKind::ConstEvaluatable(ct) => {
|
||||||
|
p!("the constant `", print(ct), "` can be evaluated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ty::PredicateKind<'tcx> {
|
ty::PredicateKind<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ref data)) => {
|
ty::PredicateKind::Clause(data) => {
|
||||||
p!(print(data))
|
p!(print(data))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
||||||
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
|
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => p!(print(predicate)),
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => p!(print(predicate)),
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => p!(print(predicate)),
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
|
|
||||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
|
||||||
},
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => p!(print(arg), " well-formed"),
|
|
||||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||||
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
||||||
}
|
}
|
||||||
|
@ -2886,9 +2901,6 @@ define_print_and_forward_display! {
|
||||||
print_value_path(closure_def_id, &[]),
|
print_value_path(closure_def_id, &[]),
|
||||||
write("` implements the trait `{}`", kind)
|
write("` implements the trait `{}`", kind)
|
||||||
),
|
),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
|
|
||||||
p!("the constant `", print(ct), "` can be evaluated")
|
|
||||||
}
|
|
||||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||||
p!("the constant `", print(c1), "` equals `", print(c2), "`")
|
p!("the constant `", print(c1), "` equals `", print(c2), "`")
|
||||||
}
|
}
|
||||||
|
|
|
@ -701,15 +701,6 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'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_predicates(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Clause<'tcx>> {
|
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Clause<'tcx>> {
|
||||||
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -715,7 +715,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
|
||||||
/// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
|
/// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
|
||||||
/// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
|
/// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
|
||||||
/// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
|
/// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
|
||||||
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
|
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> {
|
||||||
use crate::ty::ToPredicate;
|
use crate::ty::ToPredicate;
|
||||||
match self.skip_binder() {
|
match self.skip_binder() {
|
||||||
ExistentialPredicate::Trait(tr) => {
|
ExistentialPredicate::Trait(tr) => {
|
||||||
|
|
|
@ -1419,8 +1419,8 @@ pub struct AlwaysRequiresDrop;
|
||||||
/// with their underlying types.
|
/// with their underlying types.
|
||||||
pub fn reveal_opaque_types_in_bounds<'tcx>(
|
pub fn reveal_opaque_types_in_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
val: &'tcx ty::List<ty::Predicate<'tcx>>,
|
val: &'tcx ty::List<ty::Clause<'tcx>>,
|
||||||
) -> &'tcx ty::List<ty::Predicate<'tcx>> {
|
) -> &'tcx ty::List<ty::Clause<'tcx>> {
|
||||||
let mut visitor = OpaqueTypeExpander {
|
let mut visitor = OpaqueTypeExpander {
|
||||||
seen_opaque_tys: FxHashSet::default(),
|
seen_opaque_tys: FxHashSet::default(),
|
||||||
expanded_cache: FxHashMap::default(),
|
expanded_cache: FxHashMap::default(),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::mir::visit::Visitor;
|
use rustc_middle::mir::visit::Visitor;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt};
|
use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt};
|
||||||
use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
|
use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
|
||||||
use rustc_span::{symbol::sym, Span};
|
use rustc_span::{symbol::sym, Span};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
@ -74,7 +74,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
|
||||||
let param_env = self.tcx.param_env(def_id);
|
let param_env = self.tcx.param_env(def_id);
|
||||||
let bounds = param_env.caller_bounds();
|
let bounds = param_env.caller_bounds();
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
if let Some(bound_ty) = self.is_pointer_trait(&bound.kind().skip_binder()) {
|
if let Some(bound_ty) = self.is_pointer_trait(bound) {
|
||||||
// Get the argument types as they appear in the function signature.
|
// Get the argument types as they appear in the function signature.
|
||||||
let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs();
|
let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs();
|
||||||
for (arg_num, arg_def) in arg_defs.iter().enumerate() {
|
for (arg_num, arg_def) in arg_defs.iter().enumerate() {
|
||||||
|
@ -104,8 +104,8 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type.
|
/// If the given predicate is the trait `fmt::Pointer`, returns the bound parameter type.
|
||||||
fn is_pointer_trait(&self, bound: &PredicateKind<'tcx>) -> Option<Ty<'tcx>> {
|
fn is_pointer_trait(&self, bound: ty::Clause<'tcx>) -> Option<Ty<'tcx>> {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) = bound {
|
if let ty::ClauseKind::Trait(predicate) = bound.kind().skip_binder() {
|
||||||
self.tcx
|
self.tcx
|
||||||
.is_diagnostic_item(sym::Pointer, predicate.def_id())
|
.is_diagnostic_item(sym::Pointer, predicate.def_id())
|
||||||
.then(|| predicate.trait_ref.self_ty())
|
.then(|| predicate.trait_ref.self_ty())
|
||||||
|
|
|
@ -112,13 +112,13 @@ trait DefIdVisitor<'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
predicates: ty::GenericPredicates<'tcx>,
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
self.skeleton().visit_predicates(predicates)
|
self.skeleton().visit_clauses(predicates.predicates)
|
||||||
}
|
}
|
||||||
fn visit_clauses(
|
fn visit_clauses(
|
||||||
&mut self,
|
&mut self,
|
||||||
predicates: &[(ty::Clause<'tcx>, Span)],
|
clauses: &[(ty::Clause<'tcx>, Span)],
|
||||||
) -> ControlFlow<Self::BreakTy> {
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
self.skeleton().visit_clauses(predicates)
|
self.skeleton().visit_clauses(clauses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,21 +185,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_predicates(
|
|
||||||
&mut self,
|
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
|
||||||
) -> ControlFlow<V::BreakTy> {
|
|
||||||
let ty::GenericPredicates { parent: _, predicates } = predicates;
|
|
||||||
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> {
|
fn visit_clauses(&mut self, clauses: &[(ty::Clause<'tcx>, Span)]) -> ControlFlow<V::BreakTy> {
|
||||||
clauses.iter().try_for_each(|&(clause, _span)| self.visit_clause(clause))
|
clauses.into_iter().try_for_each(|&(clause, _span)| self.visit_clause(clause))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,13 +469,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
||||||
if let Some(clause) = assumption.as_clause() {
|
match G::consider_implied_clause(self, goal, assumption, []) {
|
||||||
match G::consider_implied_clause(self, goal, clause, []) {
|
Ok(result) => {
|
||||||
Ok(result) => {
|
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
||||||
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
|
||||||
}
|
|
||||||
Err(NoSolution) => (),
|
|
||||||
}
|
}
|
||||||
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,19 +683,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
// since that'll cause ambiguity.
|
// since that'll cause ambiguity.
|
||||||
//
|
//
|
||||||
// We can remove this when we have implemented lifetime intersections in responses.
|
// We can remove this when we have implemented lifetime intersections in responses.
|
||||||
if assumption.to_opt_poly_projection_pred().is_some()
|
if assumption.as_projection_clause().is_some() && !own_bounds.contains(&assumption) {
|
||||||
&& !own_bounds.contains(&assumption)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(clause) = assumption.as_clause() {
|
match G::consider_object_bound_candidate(self, goal, assumption) {
|
||||||
match G::consider_object_bound_candidate(self, goal, clause) {
|
Ok(result) => {
|
||||||
Ok(result) => {
|
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
|
||||||
}
|
|
||||||
Err(NoSolution) => (),
|
|
||||||
}
|
}
|
||||||
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,7 +343,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
trait_ref: ty::TraitRef<'tcx>,
|
trait_ref: ty::TraitRef<'tcx>,
|
||||||
object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||||
) -> Vec<ty::Predicate<'tcx>> {
|
) -> Vec<ty::Clause<'tcx>> {
|
||||||
let tcx = ecx.tcx();
|
let tcx = ecx.tcx();
|
||||||
let mut requirements = vec![];
|
let mut requirements = vec![];
|
||||||
requirements.extend(
|
requirements.extend(
|
||||||
|
@ -353,11 +353,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
|
||||||
// FIXME(associated_const_equality): Also add associated consts to
|
// FIXME(associated_const_equality): Also add associated consts to
|
||||||
// the requirements here.
|
// the requirements here.
|
||||||
if item.kind == ty::AssocKind::Type {
|
if item.kind == ty::AssocKind::Type {
|
||||||
requirements.extend(
|
requirements.extend(tcx.item_bounds(item.def_id).subst_iter(tcx, trait_ref.substs));
|
||||||
tcx.item_bounds(item.def_id)
|
|
||||||
.subst_iter(tcx, trait_ref.substs)
|
|
||||||
.map(|clause| clause.as_predicate()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
// that are already in the `ParamEnv` (modulo regions): we already
|
// that are already in the `ParamEnv` (modulo regions): we already
|
||||||
// know that they must hold.
|
// know that they must hold.
|
||||||
for predicate in param_env.caller_bounds() {
|
for predicate in param_env.caller_bounds() {
|
||||||
fresh_preds.insert(self.clean_pred(infcx, predicate));
|
fresh_preds.insert(self.clean_pred(infcx, predicate.as_predicate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut select = SelectionContext::new(&infcx);
|
let mut select = SelectionContext::new(&infcx);
|
||||||
|
@ -270,8 +270,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let computed_preds = param_env.caller_bounds().iter();
|
let computed_preds = param_env.caller_bounds().iter().map(|c| c.as_predicate());
|
||||||
let mut user_computed_preds: FxIndexSet<_> = user_env.caller_bounds().iter().collect();
|
let mut user_computed_preds: FxIndexSet<_> =
|
||||||
|
user_env.caller_bounds().iter().map(|c| c.as_predicate()).collect();
|
||||||
|
|
||||||
let mut new_env = param_env;
|
let mut new_env = param_env;
|
||||||
let dummy_cause = ObligationCause::dummy();
|
let dummy_cause = ObligationCause::dummy();
|
||||||
|
@ -349,14 +350,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
let normalized_preds =
|
let normalized_preds =
|
||||||
elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
|
elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
|
||||||
new_env = ty::ParamEnv::new(
|
new_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates_from_iter(normalized_preds),
|
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
|
||||||
param_env.reveal(),
|
param_env.reveal(),
|
||||||
param_env.constness(),
|
param_env.constness(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let final_user_env = ty::ParamEnv::new(
|
let final_user_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates_from_iter(user_computed_preds.into_iter()),
|
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
|
||||||
user_env.reveal(),
|
user_env.reveal(),
|
||||||
user_env.constness(),
|
user_env.constness(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -148,7 +148,12 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs),
|
self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs),
|
||||||
trait_ref: tcx.impl_trait_ref(impl_def_id).map(|i| i.subst(tcx, impl_substs)),
|
trait_ref: tcx.impl_trait_ref(impl_def_id).map(|i| i.subst(tcx, impl_substs)),
|
||||||
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
|
predicates: tcx
|
||||||
|
.predicates_of(impl_def_id)
|
||||||
|
.instantiate(tcx, impl_substs)
|
||||||
|
.iter()
|
||||||
|
.map(|(c, _)| c.as_predicate())
|
||||||
|
.collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let InferOk { value: mut header, obligations } =
|
let InferOk { value: mut header, obligations } =
|
||||||
|
|
|
@ -207,7 +207,7 @@ fn satisfied_from_param_env<'tcx>(
|
||||||
|
|
||||||
for pred in param_env.caller_bounds() {
|
for pred in param_env.caller_bounds() {
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ce)) => {
|
ty::ClauseKind::ConstEvaluatable(ce) => {
|
||||||
let b_ct = tcx.expand_abstract_consts(ce);
|
let b_ct = tcx.expand_abstract_consts(ce);
|
||||||
let mut v = Visitor { ct, infcx, param_env, single_match };
|
let mut v = Visitor { ct, infcx, param_env, single_match };
|
||||||
let _ = b_ct.visit_with(&mut v);
|
let _ = b_ct.visit_with(&mut v);
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub fn recompute_applicable_impls<'tcx>(
|
||||||
tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx);
|
tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx);
|
||||||
for (pred, span) in elaborate(tcx, predicates.into_iter()) {
|
for (pred, span) in elaborate(tcx, predicates.into_iter()) {
|
||||||
let kind = pred.kind();
|
let kind = pred.kind();
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = kind.skip_binder()
|
if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder()
|
||||||
&& param_env_candidate_may_apply(kind.rebind(trait_pred))
|
&& param_env_candidate_may_apply(kind.rebind(trait_pred))
|
||||||
{
|
{
|
||||||
if kind.rebind(trait_pred.trait_ref) == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) {
|
if kind.rebind(trait_pred.trait_ref) == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) {
|
||||||
|
|
|
@ -1201,7 +1201,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
DefIdOrName::Name("type parameter")
|
DefIdOrName::Name("type parameter")
|
||||||
};
|
};
|
||||||
param_env.caller_bounds().iter().find_map(|pred| {
|
param_env.caller_bounds().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()
|
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
|
||||||
&& proj.projection_ty.self_ty() == found
|
&& proj.projection_ty.self_ty() == found
|
||||||
// args tuple will always be substs[1]
|
// args tuple will always be substs[1]
|
||||||
|
@ -2001,7 +2001,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
|
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
|
||||||
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
|
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
|
||||||
&& let Some(pred) = predicates.predicates.get(*idx)
|
&& let Some(pred) = predicates.predicates.get(*idx)
|
||||||
&& let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = pred.kind().skip_binder()
|
&& let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder()
|
||||||
&& self.tcx.is_fn_trait(trait_pred.def_id())
|
&& self.tcx.is_fn_trait(trait_pred.def_id())
|
||||||
{
|
{
|
||||||
let expected_self =
|
let expected_self =
|
||||||
|
@ -2015,7 +2015,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let other_pred = predicates.into_iter()
|
let other_pred = predicates.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
|
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred))
|
ty::ClauseKind::Trait(trait_pred)
|
||||||
if self.tcx.is_fn_trait(trait_pred.def_id())
|
if self.tcx.is_fn_trait(trait_pred.def_id())
|
||||||
&& other_idx != idx
|
&& other_idx != idx
|
||||||
// Make sure that the self type matches
|
// Make sure that the self type matches
|
||||||
|
@ -3526,7 +3526,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs)
|
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs)
|
||||||
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
|
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
|
||||||
{
|
{
|
||||||
if let Some(where_pred) = where_pred.to_opt_poly_trait_pred()
|
if let Some(where_pred) = where_pred.as_trait_clause()
|
||||||
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
|
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
|
||||||
{
|
{
|
||||||
let where_pred = self.instantiate_binder_with_placeholders(where_pred);
|
let where_pred = self.instantiate_binder_with_placeholders(where_pred);
|
||||||
|
@ -3549,7 +3549,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
} else if let Some(where_pred) = where_pred.to_opt_poly_projection_pred()
|
} else if let Some(where_pred) = where_pred.as_projection_clause()
|
||||||
&& let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred()
|
&& let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred()
|
||||||
&& let Some(found) = failed_pred.skip_binder().term.ty()
|
&& let Some(found) = failed_pred.skip_binder().term.ty()
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,11 +114,11 @@ pub fn predicates_for_generics<'tcx>(
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
generic_bounds: ty::InstantiatedPredicates<'tcx>,
|
generic_bounds: ty::InstantiatedPredicates<'tcx>,
|
||||||
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
|
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
|
||||||
generic_bounds.into_iter().enumerate().map(move |(idx, (predicate, span))| Obligation {
|
generic_bounds.into_iter().enumerate().map(move |(idx, (clause, span))| Obligation {
|
||||||
cause: cause(idx, span),
|
cause: cause(idx, span),
|
||||||
recursion_depth: 0,
|
recursion_depth: 0,
|
||||||
param_env,
|
param_env,
|
||||||
predicate,
|
predicate: clause.as_predicate(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,8 +185,8 @@ fn do_normalize_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
elaborated_env: ty::ParamEnv<'tcx>,
|
elaborated_env: ty::ParamEnv<'tcx>,
|
||||||
predicates: Vec<ty::Predicate<'tcx>>,
|
predicates: Vec<ty::Clause<'tcx>>,
|
||||||
) -> Result<Vec<ty::Predicate<'tcx>>, ErrorGuaranteed> {
|
) -> Result<Vec<ty::Clause<'tcx>>, ErrorGuaranteed> {
|
||||||
let span = cause.span;
|
let span = cause.span;
|
||||||
// FIXME. We should really... do something with these region
|
// FIXME. We should really... do something with these region
|
||||||
// obligations. But this call just continues the older
|
// obligations. But this call just continues the older
|
||||||
|
@ -330,7 +330,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
||||||
|
|
||||||
let elaborated_env = ty::ParamEnv::new(
|
let elaborated_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates(&predicates),
|
tcx.mk_clauses(&predicates),
|
||||||
unnormalized_env.reveal(),
|
unnormalized_env.reveal(),
|
||||||
unnormalized_env.constness(),
|
unnormalized_env.constness(),
|
||||||
);
|
);
|
||||||
|
@ -355,10 +355,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
// TypeOutlives predicates - these are normally used by regionck.
|
// TypeOutlives predicates - these are normally used by regionck.
|
||||||
let outlives_predicates: Vec<_> = predicates
|
let outlives_predicates: Vec<_> = predicates
|
||||||
.extract_if(|predicate| {
|
.extract_if(|predicate| {
|
||||||
matches!(
|
matches!(predicate.kind().skip_binder(), ty::ClauseKind::TypeOutlives(..))
|
||||||
predicate.kind().skip_binder(),
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -384,7 +381,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
// predicates here anyway. Keeping them here anyway because it seems safer.
|
// predicates here anyway. Keeping them here anyway because it seems safer.
|
||||||
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
|
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
|
||||||
let outlives_env = ty::ParamEnv::new(
|
let outlives_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates_from_iter(outlives_env),
|
tcx.mk_clauses_from_iter(outlives_env),
|
||||||
unnormalized_env.reveal(),
|
unnormalized_env.reveal(),
|
||||||
unnormalized_env.constness(),
|
unnormalized_env.constness(),
|
||||||
);
|
);
|
||||||
|
@ -404,7 +401,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
predicates.extend(outlives_predicates);
|
predicates.extend(outlives_predicates);
|
||||||
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(
|
||||||
tcx.mk_predicates(&predicates),
|
tcx.mk_clauses(&predicates),
|
||||||
unnormalized_env.reveal(),
|
unnormalized_env.reveal(),
|
||||||
unnormalized_env.constness(),
|
unnormalized_env.constness(),
|
||||||
)
|
)
|
||||||
|
@ -439,10 +436,7 @@ where
|
||||||
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
||||||
/// returns true, then either normalize encountered an error or one of the predicates did not
|
/// returns true, then either normalize encountered an error or one of the predicates did not
|
||||||
/// hold. Used when creating vtables to check for unsatisfiable methods.
|
/// hold. Used when creating vtables to check for unsatisfiable methods.
|
||||||
pub fn impossible_predicates<'tcx>(
|
pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause<'tcx>>) -> bool {
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
predicates: Vec<ty::Predicate<'tcx>>,
|
|
||||||
) -> bool {
|
|
||||||
debug!("impossible_predicates(predicates={:?})", predicates);
|
debug!("impossible_predicates(predicates={:?})", predicates);
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
|
|
@ -271,22 +271,22 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||||
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied())
|
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied())
|
||||||
.filter_map(|(clause, span)| predicate_references_self(tcx, (clause.as_predicate(), span)))
|
.filter_map(|c| predicate_references_self(tcx, c))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predicate_references_self<'tcx>(
|
fn predicate_references_self<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
(predicate, sp): (ty::Predicate<'tcx>, Span),
|
(predicate, sp): (ty::Clause<'tcx>, Span),
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
let self_ty = tcx.types.self_param;
|
let self_ty = tcx.types.self_param;
|
||||||
let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk().any(|arg| arg == self_ty.into());
|
let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk().any(|arg| arg == self_ty.into());
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ref data)) => {
|
ty::ClauseKind::Trait(ref data) => {
|
||||||
// In the case of a trait predicate, we can skip the "self" type.
|
// In the case of a trait predicate, we can skip the "self" type.
|
||||||
data.trait_ref.substs[1..].iter().any(has_self_ty).then_some(sp)
|
data.trait_ref.substs[1..].iter().any(has_self_ty).then_some(sp)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data)) => {
|
ty::ClauseKind::Projection(ref data) => {
|
||||||
// And similarly for projections. This should be redundant with
|
// And similarly for projections. This should be redundant with
|
||||||
// the previous check because any projection should have a
|
// the previous check because any projection should have a
|
||||||
// matching `Trait` predicate with the same inputs, but we do
|
// matching `Trait` predicate with the same inputs, but we do
|
||||||
|
@ -304,24 +304,13 @@ fn predicate_references_self<'tcx>(
|
||||||
// possible alternatives.
|
// possible alternatives.
|
||||||
data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp)
|
data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(_ct, ty)) => {
|
ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp),
|
||||||
has_self_ty(&ty.into()).then_some(sp)
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::PredicateKind::AliasRelate(..) => bug!("`AliasRelate` not allowed as assumption"),
|
ty::ClauseKind::WellFormed(..)
|
||||||
|
| ty::ClauseKind::TypeOutlives(..)
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
| ty::ClauseKind::RegionOutlives(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Subtype(..)
|
|
||||||
| ty::PredicateKind::Coerce(..)
|
|
||||||
// FIXME(generic_const_exprs): this can mention `Self`
|
// FIXME(generic_const_exprs): this can mention `Self`
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
| ty::ClauseKind::ConstEvaluatable(..) => None,
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,23 +342,15 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
let predicates = tcx.predicates_of(def_id);
|
let predicates = tcx.predicates_of(def_id);
|
||||||
let predicates = predicates.instantiate_identity(tcx).predicates;
|
let predicates = predicates.instantiate_identity(tcx).predicates;
|
||||||
elaborate(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() {
|
elaborate(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ref trait_pred)) => {
|
ty::ClauseKind::Trait(ref trait_pred) => {
|
||||||
trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
|
trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::ClauseKind::TypeOutlives(_)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
| ty::ClauseKind::ConstEvaluatable(_) => false,
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => false,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +556,7 @@ fn virtual_call_violation_for_method<'tcx>(
|
||||||
// because a trait object can't claim to live longer than the concrete
|
// because a trait object can't claim to live longer than the concrete
|
||||||
// type. If the lifetime bound holds on dyn Trait then it's guaranteed
|
// type. If the lifetime bound holds on dyn Trait then it's guaranteed
|
||||||
// to hold as well on the concrete type.
|
// to hold as well on the concrete type.
|
||||||
if pred.to_opt_type_outlives().is_some() {
|
if pred.as_type_outlives_clause().is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,11 +573,11 @@ fn virtual_call_violation_for_method<'tcx>(
|
||||||
// only if the autotrait is one of the trait object's trait bounds, like
|
// only if the autotrait is one of the trait object's trait bounds, like
|
||||||
// in `dyn Trait + AutoTrait`. This guarantees that trait objects only
|
// in `dyn Trait + AutoTrait`. This guarantees that trait objects only
|
||||||
// implement auto traits if the underlying type does as well.
|
// implement auto traits if the underlying type does as well.
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
|
if let ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||||
trait_ref: pred_trait_ref,
|
trait_ref: pred_trait_ref,
|
||||||
constness: ty::BoundConstness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
polarity: ty::ImplPolarity::Positive,
|
polarity: ty::ImplPolarity::Positive,
|
||||||
})) = pred.kind().skip_binder()
|
}) = pred.kind().skip_binder()
|
||||||
&& pred_trait_ref.self_ty() == tcx.types.self_param
|
&& pred_trait_ref.self_ty() == tcx.types.self_param
|
||||||
&& tcx.trait_is_auto(pred_trait_ref.def_id)
|
&& tcx.trait_is_auto(pred_trait_ref.def_id)
|
||||||
{
|
{
|
||||||
|
@ -764,7 +745,6 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
// Self: Unsize<U>
|
// Self: Unsize<U>
|
||||||
let unsize_predicate =
|
let unsize_predicate =
|
||||||
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty])
|
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty])
|
||||||
.without_const()
|
|
||||||
.to_predicate(tcx);
|
.to_predicate(tcx);
|
||||||
|
|
||||||
// U: Trait<Arg1, ..., ArgN>
|
// U: Trait<Arg1, ..., ArgN>
|
||||||
|
@ -781,7 +761,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
||||||
|
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(
|
||||||
tcx.mk_predicates_from_iter(caller_bounds),
|
tcx.mk_clauses_from_iter(caller_bounds),
|
||||||
param_env.reveal(),
|
param_env.reveal(),
|
||||||
param_env.constness(),
|
param_env.constness(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1585,7 +1585,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
||||||
obligation,
|
obligation,
|
||||||
candidate_set,
|
candidate_set,
|
||||||
ProjectionCandidate::TraitDef,
|
ProjectionCandidate::TraitDef,
|
||||||
bounds.iter().map(|clause| clause.as_predicate()),
|
bounds.iter(),
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1648,15 +1648,13 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||||
ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>,
|
ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>,
|
||||||
env_predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
env_predicates: impl Iterator<Item = ty::Clause<'tcx>>,
|
||||||
potentially_unnormalized_candidates: bool,
|
potentially_unnormalized_candidates: bool,
|
||||||
) {
|
) {
|
||||||
let infcx = selcx.infcx;
|
let infcx = selcx.infcx;
|
||||||
for predicate in env_predicates {
|
for predicate in env_predicates {
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) =
|
if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
|
||||||
predicate.kind().skip_binder()
|
|
||||||
{
|
|
||||||
let data = bound_predicate.rebind(data);
|
let data = bound_predicate.rebind(data);
|
||||||
if data.projection_def_id() != obligation.predicate.def_id {
|
if data.projection_def_id() != obligation.predicate.def_id {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -50,12 +50,12 @@ impl<'tcx> Normalizable<'tcx> for Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Normalizable<'tcx> for ty::Predicate<'tcx> {
|
impl<'tcx> Normalizable<'tcx> for ty::Clause<'tcx> {
|
||||||
fn type_op_method(
|
fn type_op_method(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||||
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
|
) -> Result<CanonicalQueryResponse<'tcx, Self>, NoSolution> {
|
||||||
tcx.type_op_normalize_predicate(canonicalized)
|
tcx.type_op_normalize_clause(canonicalized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.caller_bounds()
|
.caller_bounds()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| !p.references_error())
|
.filter(|p| !p.references_error())
|
||||||
.filter_map(|p| p.to_opt_poly_trait_pred());
|
.filter_map(|p| p.as_trait_clause());
|
||||||
|
|
||||||
// Micro-optimization: filter out predicates relating to different traits.
|
// Micro-optimization: filter out predicates relating to different traits.
|
||||||
let matching_bounds =
|
let matching_bounds =
|
||||||
|
@ -402,7 +402,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for &(predicate, _) in self.tcx().predicates_of(impl_def_id).predicates {
|
for &(predicate, _) in self.tcx().predicates_of(impl_def_id).predicates {
|
||||||
let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
|
let ty::ClauseKind::Trait(pred)
|
||||||
= predicate.kind().skip_binder() else { continue };
|
= predicate.kind().skip_binder() else { continue };
|
||||||
if fn_ptr_trait != pred.trait_ref.def_id {
|
if fn_ptr_trait != pred.trait_ref.def_id {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1108,12 +1108,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
[source],
|
[source],
|
||||||
);
|
);
|
||||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
nested.push(predicate_to_obligation(tr.to_predicate(tcx)));
|
||||||
|
|
||||||
// If the type is `Foo + 'a`, ensure that the type
|
// If the type is `Foo + 'a`, ensure that the type
|
||||||
// being cast to `Foo + 'a` outlives `'a`:
|
// being cast to `Foo + 'a` outlives `'a`:
|
||||||
let outlives = ty::OutlivesPredicate(source, r);
|
let outlives = ty::OutlivesPredicate(source, r);
|
||||||
nested.push(predicate_to_obligation(ty::Binder::dummy(outlives).to_predicate(tcx)));
|
nested.push(predicate_to_obligation(
|
||||||
|
ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// `[T; n]` -> `[T]`
|
// `[T; n]` -> `[T]`
|
||||||
|
|
|
@ -2657,7 +2657,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let predicate = normalize_with_depth_to(
|
let clause = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
param_env,
|
param_env,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
|
@ -2665,7 +2665,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
predicate,
|
predicate,
|
||||||
&mut obligations,
|
&mut obligations,
|
||||||
);
|
);
|
||||||
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
|
obligations.push(Obligation {
|
||||||
|
cause,
|
||||||
|
recursion_depth,
|
||||||
|
param_env,
|
||||||
|
predicate: clause.as_predicate(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
obligations
|
obligations
|
||||||
|
|
|
@ -508,22 +508,14 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
|
||||||
Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
|
Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
|
||||||
|
|
||||||
for (mut p, _) in predicates {
|
for (mut p, _) in predicates {
|
||||||
if let Some(poly_trait_ref) = p.to_opt_poly_trait_pred() {
|
if let Some(poly_trait_ref) = p.as_trait_clause() {
|
||||||
if Some(poly_trait_ref.def_id()) == sized_trait {
|
if Some(poly_trait_ref.def_id()) == sized_trait {
|
||||||
types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder());
|
types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness {
|
if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness {
|
||||||
let new_trait_pred = poly_trait_ref.map_bound(|mut trait_pred| {
|
p = p.without_const(tcx);
|
||||||
trait_pred.constness = ty::BoundConstness::NotConst;
|
|
||||||
trait_pred
|
|
||||||
});
|
|
||||||
|
|
||||||
p = tcx.mk_predicate(
|
|
||||||
new_trait_pred
|
|
||||||
.map_bound(|p| ty::PredicateKind::Clause(ty::ClauseKind::Trait(p))),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pretty_predicates.push(p.to_string());
|
pretty_predicates.push(p.to_string());
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||||
|
|
||||||
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
||||||
pred.subst_supertrait(tcx, &trait_ref)
|
pred.subst_supertrait(tcx, &trait_ref)
|
||||||
.to_opt_poly_trait_pred()
|
.as_trait_clause()
|
||||||
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
||||||
});
|
});
|
||||||
debug!("expand_trait_aliases: items={:?}", items.clone().collect::<Vec<_>>());
|
debug!("expand_trait_aliases: items={:?}", items.clone().collect::<Vec<_>>());
|
||||||
|
@ -182,7 +182,7 @@ impl Iterator for SupertraitDefIds<'_> {
|
||||||
predicates
|
predicates
|
||||||
.predicates
|
.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(pred, _)| pred.to_opt_poly_trait_pred())
|
.filter_map(|(pred, _)| pred.as_trait_clause())
|
||||||
.map(|trait_ref| trait_ref.def_id())
|
.map(|trait_ref| trait_ref.def_id())
|
||||||
.filter(|&super_def_id| visited.insert(super_def_id)),
|
.filter(|&super_def_id| visited.insert(super_def_id)),
|
||||||
);
|
);
|
||||||
|
|
|
@ -115,7 +115,7 @@ pub fn prepare_vtable_segments<'tcx, T>(
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |(pred, _)| {
|
.filter_map(move |(pred, _)| {
|
||||||
pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_pred()
|
pred.subst_supertrait(tcx, &inner_most_trait_ref).as_trait_clause()
|
||||||
});
|
});
|
||||||
|
|
||||||
'diving_in_skip_visited_traits: loop {
|
'diving_in_skip_visited_traits: loop {
|
||||||
|
|
|
@ -976,7 +976,7 @@ pub fn object_region_bounds<'tcx>(
|
||||||
pub(crate) fn required_region_bounds<'tcx>(
|
pub(crate) fn required_region_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
erased_self_ty: Ty<'tcx>,
|
erased_self_ty: Ty<'tcx>,
|
||||||
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
predicates: impl Iterator<Item = ty::Clause<'tcx>>,
|
||||||
) -> Vec<ty::Region<'tcx>> {
|
) -> Vec<ty::Region<'tcx>> {
|
||||||
assert!(!erased_self_ty.has_escaping_bound_vars());
|
assert!(!erased_self_ty.has_escaping_bound_vars());
|
||||||
|
|
||||||
|
@ -984,24 +984,7 @@ pub(crate) fn required_region_bounds<'tcx>(
|
||||||
.filter_map(|pred| {
|
.filter_map(|pred| {
|
||||||
debug!(?pred);
|
debug!(?pred);
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
|
||||||
| ty::PredicateKind::Subtype(..)
|
|
||||||
| ty::PredicateKind::Coerce(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
|
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
|
|
||||||
ref t,
|
|
||||||
ref r,
|
|
||||||
))) => {
|
|
||||||
// Search for a bound of the form `erased_self_ty
|
// Search for a bound of the form `erased_self_ty
|
||||||
// : 'a`, but be wary of something like `for<'a>
|
// : 'a`, but be wary of something like `for<'a>
|
||||||
// erased_self_ty : 'a` (we interpret a
|
// erased_self_ty : 'a` (we interpret a
|
||||||
|
@ -1017,6 +1000,12 @@ pub(crate) fn required_region_bounds<'tcx>(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ty::ClauseKind::Trait(_)
|
||||||
|
| ty::ClauseKind::RegionOutlives(_)
|
||||||
|
| ty::ClauseKind::Projection(_)
|
||||||
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
|
| ty::ClauseKind::WellFormed(_)
|
||||||
|
| ty::ClauseKind::ConstEvaluatable(_) => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
||||||
.tcx
|
.tcx
|
||||||
.predicates_defined_on(def_id)
|
.predicates_defined_on(def_id)
|
||||||
.instantiate_own(self.interner.tcx, bound_vars)
|
.instantiate_own(self.interner.tcx, bound_vars)
|
||||||
.filter_map(|(wc, _)| LowerInto::lower_into(wc, self.interner))
|
.filter_map(|(wc, _)| LowerInto::lower_into(wc.as_predicate(), self.interner))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,36 +93,29 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
let (predicate, binders, _named_regions) =
|
let (predicate, binders, _named_regions) =
|
||||||
collect_bound_vars(interner, interner.tcx, predicate.kind());
|
collect_bound_vars(interner, interner.tcx, predicate.kind());
|
||||||
let consequence = match predicate {
|
let consequence = match predicate {
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
// TODO: FIXME
|
||||||
|
/*ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
||||||
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner)))
|
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner)))
|
||||||
}
|
}*/
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
|
ty::ClauseKind::Trait(predicate) => chalk_ir::DomainGoal::FromEnv(
|
||||||
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Trait(
|
chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)),
|
||||||
predicate.trait_ref.lower_into(interner),
|
),
|
||||||
))
|
ty::ClauseKind::RegionOutlives(predicate) => chalk_ir::DomainGoal::Holds(
|
||||||
}
|
chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
|
a: predicate.0.lower_into(interner),
|
||||||
chalk_ir::DomainGoal::Holds(chalk_ir::WhereClause::LifetimeOutlives(
|
b: predicate.1.lower_into(interner),
|
||||||
chalk_ir::LifetimeOutlives {
|
}),
|
||||||
a: predicate.0.lower_into(interner),
|
),
|
||||||
b: predicate.1.lower_into(interner),
|
ty::ClauseKind::TypeOutlives(predicate) => chalk_ir::DomainGoal::Holds(
|
||||||
},
|
chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives {
|
||||||
))
|
ty: predicate.0.lower_into(interner),
|
||||||
}
|
lifetime: predicate.1.lower_into(interner),
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
|
}),
|
||||||
chalk_ir::DomainGoal::Holds(chalk_ir::WhereClause::TypeOutlives(
|
),
|
||||||
chalk_ir::TypeOutlives {
|
ty::ClauseKind::Projection(predicate) => chalk_ir::DomainGoal::Holds(
|
||||||
ty: predicate.0.lower_into(interner),
|
chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)),
|
||||||
lifetime: predicate.1.lower_into(interner),
|
),
|
||||||
},
|
ty::ClauseKind::WellFormed(arg) => match arg.unpack() {
|
||||||
))
|
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
|
|
||||||
chalk_ir::DomainGoal::Holds(chalk_ir::WhereClause::AliasEq(
|
|
||||||
predicate.lower_into(interner),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => match arg.unpack() {
|
|
||||||
ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed(
|
ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed(
|
||||||
chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
|
chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
|
||||||
),
|
),
|
||||||
|
@ -131,15 +124,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
interner.tcx.types.unit.lower_into(interner),
|
interner.tcx.types.unit.lower_into(interner),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
ty::PredicateKind::ObjectSafe(..)
|
ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::ConstEvaluatable(_) => {
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
bug!("unexpected predicate {}", predicate)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
}
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Subtype(..)
|
|
||||||
| ty::PredicateKind::Coerce(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
|
||||||
};
|
};
|
||||||
let value = chalk_ir::ProgramClauseImplication {
|
let value = chalk_ir::ProgramClauseImplication {
|
||||||
consequence,
|
consequence,
|
||||||
|
|
|
@ -2,8 +2,8 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
|
use rustc_middle::ty::{Clause, ParamEnvAnd};
|
||||||
use rustc_middle::ty::{FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_middle::ty::{ParamEnvAnd, Predicate};
|
|
||||||
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
||||||
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
||||||
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
|
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
|
||||||
|
@ -23,7 +23,7 @@ pub(crate) fn provide(p: &mut Providers) {
|
||||||
type_op_prove_predicate,
|
type_op_prove_predicate,
|
||||||
type_op_subtype,
|
type_op_subtype,
|
||||||
type_op_normalize_ty,
|
type_op_normalize_ty,
|
||||||
type_op_normalize_predicate,
|
type_op_normalize_clause,
|
||||||
type_op_normalize_fn_sig,
|
type_op_normalize_fn_sig,
|
||||||
type_op_normalize_poly_fn_sig,
|
type_op_normalize_poly_fn_sig,
|
||||||
..*p
|
..*p
|
||||||
|
@ -70,10 +70,10 @@ fn type_op_normalize_ty<'tcx>(
|
||||||
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_op_normalize_predicate<'tcx>(
|
fn type_op_normalize_clause<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Predicate<'tcx>>>>,
|
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Clause<'tcx>>>>,
|
||||||
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Predicate<'tcx>>>, NoSolution> {
|
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, Clause<'tcx>>>, NoSolution> {
|
||||||
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ use rustc_hir::def::DefKind;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, ToPredicate, Ty,
|
self, EarlyBinder, ImplTraitInTraitData, ToPredicate, Ty, TyCtxt, TypeSuperVisitable,
|
||||||
TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
|
TypeVisitable, TypeVisitor,
|
||||||
};
|
};
|
||||||
use rustc_session::config::TraitSolver;
|
use rustc_session::config::TraitSolver;
|
||||||
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
||||||
|
@ -245,7 +245,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let unnormalized_env =
|
let unnormalized_env =
|
||||||
ty::ParamEnv::new(tcx.mk_predicates(&predicates), traits::Reveal::UserFacing, constness);
|
ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing, constness);
|
||||||
|
|
||||||
let body_id = local_did.unwrap_or(CRATE_DEF_ID);
|
let body_id = local_did.unwrap_or(CRATE_DEF_ID);
|
||||||
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
||||||
|
@ -258,7 +258,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
/// its corresponding opaque within the body of a default-body trait method.
|
/// its corresponding opaque within the body of a default-body trait method.
|
||||||
struct ImplTraitInTraitFinder<'a, 'tcx> {
|
struct ImplTraitInTraitFinder<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicates: &'a mut Vec<Predicate<'tcx>>,
|
predicates: &'a mut Vec<ty::Clause<'tcx>>,
|
||||||
fn_def_id: DefId,
|
fn_def_id: DefId,
|
||||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
seen: FxHashSet<DefId>,
|
seen: FxHashSet<DefId>,
|
||||||
|
@ -340,9 +340,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||||
/// that are assumed to be well-formed (because they come from the environment).
|
/// that are assumed to be well-formed (because they come from the environment).
|
||||||
///
|
///
|
||||||
/// Used only in chalk mode.
|
/// Used only in chalk mode.
|
||||||
fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predicate<'_>> {
|
fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<ty::Clause<'_>> {
|
||||||
use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
|
use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
|
||||||
|
|
||||||
debug!("environment(def_id = {:?})", def_id);
|
debug!("environment(def_id = {:?})", def_id);
|
||||||
|
|
||||||
|
@ -428,8 +427,9 @@ fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predica
|
||||||
|
|
||||||
NodeKind::Other => (),
|
NodeKind::Other => (),
|
||||||
}
|
}
|
||||||
let input_clauses = inputs.into_iter().filter_map(|arg| {
|
let input_clauses = inputs.into_iter().filter_map(|_arg| {
|
||||||
match arg.unpack() {
|
// TODO: FIXME
|
||||||
|
/*match arg.unpack() {
|
||||||
GenericArgKind::Type(ty) => {
|
GenericArgKind::Type(ty) => {
|
||||||
let binder = Binder::dummy(PredicateKind::TypeWellFormedFromEnv(ty));
|
let binder = Binder::dummy(PredicateKind::TypeWellFormedFromEnv(ty));
|
||||||
Some(tcx.mk_predicate(binder))
|
Some(tcx.mk_predicate(binder))
|
||||||
|
@ -440,10 +440,11 @@ fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predica
|
||||||
|
|
||||||
// FIXME(eddyb) support const generics in Chalk
|
// FIXME(eddyb) support const generics in Chalk
|
||||||
GenericArgKind::Const(_) => None,
|
GenericArgKind::Const(_) => None,
|
||||||
}
|
}*/
|
||||||
|
None
|
||||||
});
|
});
|
||||||
|
|
||||||
tcx.mk_predicates_from_iter(clauses.chain(input_clauses))
|
tcx.mk_clauses_from_iter(clauses.chain(input_clauses))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
|
|
|
@ -317,14 +317,14 @@ where
|
||||||
lifetime_predicates
|
lifetime_predicates
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_for_generics(&self, pred: ty::Predicate<'tcx>) -> FxHashSet<GenericParamDef> {
|
fn extract_for_generics(&self, pred: ty::Clause<'tcx>) -> FxHashSet<GenericParamDef> {
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
let tcx = self.cx.tcx;
|
let tcx = self.cx.tcx;
|
||||||
let regions = match bound_predicate.skip_binder() {
|
let regions = match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_pred)) => {
|
ty::ClauseKind::Trait(poly_trait_pred) => {
|
||||||
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_trait_pred))
|
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_trait_pred))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(poly_proj_pred)) => {
|
ty::ClauseKind::Projection(poly_proj_pred) => {
|
||||||
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_proj_pred))
|
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_proj_pred))
|
||||||
}
|
}
|
||||||
_ => return FxHashSet::default(),
|
_ => return FxHashSet::default(),
|
||||||
|
@ -449,9 +449,7 @@ where
|
||||||
.filter(|p| {
|
.filter(|p| {
|
||||||
!orig_bounds.contains(p)
|
!orig_bounds.contains(p)
|
||||||
|| match p.kind().skip_binder() {
|
|| match p.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
ty::ClauseKind::Trait(pred) => pred.def_id() == sized_trait,
|
||||||
pred.def_id() == sized_trait
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -326,36 +326,24 @@ fn clean_where_predicate<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clean_predicate<'tcx>(
|
pub(crate) fn clean_predicate<'tcx>(
|
||||||
predicate: ty::Predicate<'tcx>,
|
predicate: ty::Clause<'tcx>,
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
) -> Option<WherePredicate> {
|
) -> Option<WherePredicate> {
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx),
|
||||||
clean_poly_trait_predicate(bound_predicate.rebind(pred), cx)
|
ty::ClauseKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred),
|
||||||
}
|
ty::ClauseKind::TypeOutlives(pred) => {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(pred)) => {
|
|
||||||
clean_region_outlives_predicate(pred)
|
|
||||||
}
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(pred)) => {
|
|
||||||
clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)
|
clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
|
ty::ClauseKind::Projection(pred) => {
|
||||||
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
|
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
|
||||||
}
|
}
|
||||||
// FIXME(generic_const_exprs): should this do something?
|
// FIXME(generic_const_exprs): should this do something?
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => None,
|
ty::ClauseKind::ConstEvaluatable(..)
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) => None,
|
| ty::ClauseKind::WellFormed(..)
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => None,
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
|
| ty::ClauseKind::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateKind::Subtype(..)
|
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::Coerce(..)
|
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,19 +793,17 @@ fn clean_ty_generics<'tcx>(
|
||||||
let param_idx = (|| {
|
let param_idx = (|| {
|
||||||
let bound_p = p.kind();
|
let bound_p = p.kind();
|
||||||
match bound_p.skip_binder() {
|
match bound_p.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
ty::ClauseKind::Trait(pred) => {
|
||||||
if let ty::Param(param) = pred.self_ty().kind() {
|
if let ty::Param(param) = pred.self_ty().kind() {
|
||||||
return Some(param.index);
|
return Some(param.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
||||||
ty::OutlivesPredicate(ty, _reg),
|
|
||||||
)) => {
|
|
||||||
if let ty::Param(param) = ty.kind() {
|
if let ty::Param(param) = ty.kind() {
|
||||||
return Some(param.index);
|
return Some(param.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(p)) => {
|
ty::ClauseKind::Projection(p) => {
|
||||||
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
|
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
|
||||||
projection = Some(bound_p.rebind(p));
|
projection = Some(bound_p.rebind(p));
|
||||||
return Some(param.index);
|
return Some(param.index);
|
||||||
|
@ -1354,10 +1340,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||||
|
|
||||||
let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
|
let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
|
||||||
if let ty::TraitContainer = assoc_item.container {
|
if let ty::TraitContainer = assoc_item.container {
|
||||||
let bounds = tcx
|
let bounds =
|
||||||
.explicit_item_bounds(assoc_item.def_id)
|
tcx.explicit_item_bounds(assoc_item.def_id).subst_identity_iter_copied();
|
||||||
.subst_identity_iter_copied()
|
|
||||||
.map(|(c, s)| (c.as_predicate(), s));
|
|
||||||
predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
|
predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
|
||||||
}
|
}
|
||||||
let mut generics = clean_ty_generics(
|
let mut generics = clean_ty_generics(
|
||||||
|
|
|
@ -128,9 +128,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId)
|
||||||
.predicates
|
.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(pred, _)| {
|
.filter_map(|(pred, _)| {
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
|
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() {
|
||||||
pred.kind().skip_binder()
|
|
||||||
{
|
|
||||||
if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None }
|
if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None }
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -27,7 +27,7 @@ use rustc_middle::mir::{Rvalue, StatementKind};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, BoundVariableKind, ClauseKind, EarlyBinder, FnSig, GenericArgKind, List, ParamEnv, ParamTy,
|
self, Binder, BoundVariableKind, ClauseKind, EarlyBinder, FnSig, GenericArgKind, List, ParamEnv, ParamTy,
|
||||||
PredicateKind, ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults,
|
ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults,
|
||||||
};
|
};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{symbol::sym, Span, Symbol};
|
use rustc_span::{symbol::sym, Span, Symbol};
|
||||||
|
@ -1133,7 +1133,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||||
let projection_predicates = predicates
|
let projection_predicates = predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|predicate| {
|
.filter_map(|predicate| {
|
||||||
if let PredicateKind::Clause(ClauseKind::Projection(projection_predicate)) = predicate.kind().skip_binder() {
|
if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
|
||||||
Some(projection_predicate)
|
Some(projection_predicate)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1147,7 +1147,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||||
if predicates
|
if predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|predicate| {
|
.filter_map(|predicate| {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(trait_predicate)) = predicate.kind().skip_binder()
|
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||||
&& trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
|
&& trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
|
||||||
{
|
{
|
||||||
Some(trait_predicate.trait_ref.def_id)
|
Some(trait_predicate.trait_ref.def_id)
|
||||||
|
@ -1209,7 +1209,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
predicates.iter().all(|predicate| {
|
predicates.iter().all(|predicate| {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(trait_predicate)) = predicate.kind().skip_binder()
|
if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||||
&& cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
|
&& cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
|
||||||
&& let ty::Param(param_ty) = trait_predicate.self_ty().kind()
|
&& let ty::Param(param_ty) = trait_predicate.self_ty().kind()
|
||||||
&& let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack()
|
&& let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack()
|
||||||
|
|
|
@ -14,8 +14,8 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::traits::Reveal;
|
use rustc_middle::traits::Reveal;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, BoundConstness, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind,
|
self, BoundConstness, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv,
|
||||||
TraitPredicate, Ty, TyCtxt,
|
ToPredicate, TraitPredicate, Ty, TyCtxt,
|
||||||
};
|
};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
|
@ -503,7 +503,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
|
||||||
|
|
||||||
let ty_predicates = tcx.predicates_of(did).predicates;
|
let ty_predicates = tcx.predicates_of(did).predicates;
|
||||||
for (p, _) in ty_predicates {
|
for (p, _) in ty_predicates {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(p)) = p.kind().skip_binder()
|
if let ClauseKind::Trait(p) = p.kind().skip_binder()
|
||||||
&& p.trait_ref.def_id == eq_trait_id
|
&& p.trait_ref.def_id == eq_trait_id
|
||||||
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
|
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
|
||||||
&& p.constness == BoundConstness::NotConst
|
&& p.constness == BoundConstness::NotConst
|
||||||
|
@ -514,13 +514,13 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamEnv::new(
|
ParamEnv::new(
|
||||||
tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
|
tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
|
||||||
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
|
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
|
||||||
tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
|
ClauseKind::Trait(TraitPredicate {
|
||||||
trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
|
trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
|
||||||
constness: BoundConstness::NotConst,
|
constness: BoundConstness::NotConst,
|
||||||
polarity: ImplPolarity::Positive,
|
polarity: ImplPolarity::Positive,
|
||||||
}))))
|
}).to_predicate(tcx)
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
Reveal::UserFacing,
|
Reveal::UserFacing,
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_hir::{
|
||||||
};
|
};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, PredicateKind, Ty};
|
use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ fn check_collect_into_intoiterator<'tcx>(
|
||||||
.caller_bounds()
|
.caller_bounds()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(t)) = p.kind().skip_binder()
|
if let ClauseKind::Trait(t) = p.kind().skip_binder()
|
||||||
&& cx.tcx.is_diagnostic_item(sym::IntoIterator,t.trait_ref.def_id) {
|
&& cx.tcx.is_diagnostic_item(sym::IntoIterator,t.trait_ref.def_id) {
|
||||||
Some(t.self_ty())
|
Some(t.self_ty())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use rustc_lint::LateContext;
|
||||||
use rustc_middle::mir::Mutability;
|
use rustc_middle::mir::Mutability;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
||||||
use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
|
use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, ProjectionPredicate, TraitPredicate, Ty};
|
||||||
use rustc_span::{sym, Symbol};
|
use rustc_span::{sym, Symbol};
|
||||||
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
|
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
|
||||||
|
|
||||||
|
@ -345,12 +345,12 @@ fn get_input_traits_and_projections<'tcx>(
|
||||||
let mut projection_predicates = Vec::new();
|
let mut projection_predicates = Vec::new();
|
||||||
for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() {
|
for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() {
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
PredicateKind::Clause(ClauseKind::Trait(trait_predicate)) => {
|
ClauseKind::Trait(trait_predicate) => {
|
||||||
if trait_predicate.trait_ref.self_ty() == input {
|
if trait_predicate.trait_ref.self_ty() == input {
|
||||||
trait_predicates.push(trait_predicate);
|
trait_predicates.push(trait_predicate);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PredicateKind::Clause(ClauseKind::Projection(projection_predicate)) => {
|
ClauseKind::Projection(projection_predicate) => {
|
||||||
if projection_predicate.projection_ty.self_ty() == input {
|
if projection_predicate.projection_ty.self_ty() == input {
|
||||||
projection_predicates.push(projection_predicate);
|
projection_predicates.push(projection_predicate);
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||||
|
|
||||||
let mut trait_predicates = cx.tcx.param_env(callee_def_id)
|
let mut trait_predicates = cx.tcx.param_env(callee_def_id)
|
||||||
.caller_bounds().iter().filter(|predicate| {
|
.caller_bounds().iter().filter(|predicate| {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(trait_predicate))
|
if let ClauseKind::Trait(trait_predicate)
|
||||||
= predicate.kind().skip_binder()
|
= predicate.kind().skip_binder()
|
||||||
&& trait_predicate.trait_ref.self_ty() == *param_ty
|
&& trait_predicate.trait_ref.self_ty() == *param_ty
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
||||||
.filter_map(|pred| {
|
.filter_map(|pred| {
|
||||||
// Note that we do not want to deal with qualified predicates here.
|
// Note that we do not want to deal with qualified predicates here.
|
||||||
match pred.kind().no_bound_vars() {
|
match pred.kind().no_bound_vars() {
|
||||||
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))) if pred.def_id() != sized_trait => {
|
Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => {
|
||||||
Some(pred)
|
Some(pred)
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{Closure, Expr, ExprKind, StmtKind};
|
use rustc_hir::{Closure, Expr, ExprKind, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::{ClauseKind, GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
|
use rustc_middle::ty::{ClauseKind, GenericPredicates, ProjectionPredicate, TraitPredicate};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::{sym, BytePos, Span};
|
use rustc_span::{sym, BytePos, Span};
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ fn get_trait_predicates_for_trait_id<'tcx>(
|
||||||
let mut preds = Vec::new();
|
let mut preds = Vec::new();
|
||||||
for (pred, _) in generics.predicates {
|
for (pred, _) in generics.predicates {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let PredicateKind::Clause(ClauseKind::Trait(poly_trait_pred)) = pred.kind().skip_binder();
|
if let ClauseKind::Trait(poly_trait_pred) = pred.kind().skip_binder();
|
||||||
let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred));
|
let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred));
|
||||||
if let Some(trait_def_id) = trait_id;
|
if let Some(trait_def_id) = trait_id;
|
||||||
if trait_def_id == trait_pred.trait_ref.def_id;
|
if trait_def_id == trait_pred.trait_ref.def_id;
|
||||||
|
@ -63,7 +63,7 @@ fn get_projection_pred<'tcx>(
|
||||||
trait_pred: TraitPredicate<'tcx>,
|
trait_pred: TraitPredicate<'tcx>,
|
||||||
) -> Option<ProjectionPredicate<'tcx>> {
|
) -> Option<ProjectionPredicate<'tcx>> {
|
||||||
generics.predicates.iter().find_map(|(proj_pred, _)| {
|
generics.predicates.iter().find_map(|(proj_pred, _)| {
|
||||||
if let ty::PredicateKind::Clause(ClauseKind::Projection(pred)) = proj_pred.kind().skip_binder() {
|
if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() {
|
||||||
let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred));
|
let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred));
|
||||||
if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs {
|
if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs {
|
||||||
return Some(projection_pred);
|
return Some(projection_pred);
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||||
use rustc_hir::{def_id::DefId, Block, Expr, ExprKind, QPath, UnOp};
|
use rustc_hir::{def_id::DefId, Block, Expr, ExprKind, QPath, UnOp};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::ty::{self, PredicateKind};
|
use rustc_middle::ty;
|
||||||
use rustc_span::{sym, Symbol};
|
use rustc_span::{sym, Symbol};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
@ -73,7 +73,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
|
||||||
.flat_map(|v| v.fields.iter())
|
.flat_map(|v| v.fields.iter())
|
||||||
.any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_)))
|
.any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_)))
|
||||||
&& all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() {
|
&& all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() {
|
||||||
PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,
|
ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,
|
||||||
_ => true,
|
_ => true,
|
||||||
})
|
})
|
||||||
&& subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))
|
&& subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))
|
||||||
|
|
|
@ -21,35 +21,6 @@ type McfResult = Result<(), (Span, Cow<'static, str>)>;
|
||||||
|
|
||||||
pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult {
|
pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult {
|
||||||
let def_id = body.source.def_id();
|
let def_id = body.source.def_id();
|
||||||
let mut current = def_id;
|
|
||||||
loop {
|
|
||||||
let predicates = tcx.predicates_of(current);
|
|
||||||
for (predicate, _) in predicates.predicates {
|
|
||||||
match predicate.kind().skip_binder() {
|
|
||||||
ty::PredicateKind::Clause(
|
|
||||||
ty::ClauseKind::RegionOutlives(_)
|
|
||||||
| ty::ClauseKind::TypeOutlives(_)
|
|
||||||
| ty::ClauseKind::Projection(_)
|
|
||||||
| ty::ClauseKind::Trait(..)
|
|
||||||
| ty::ClauseKind::ConstArgHasType(..),
|
|
||||||
)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
|
||||||
ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"),
|
|
||||||
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {predicate:#?}"),
|
|
||||||
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"),
|
|
||||||
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"),
|
|
||||||
ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"),
|
|
||||||
ty::PredicateKind::Ambiguous => panic!("ambiguous predicate on function: {predicate:#?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match predicates.parent {
|
|
||||||
Some(parent) => current = parent,
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for local in &body.local_decls {
|
for local in &body.local_decls {
|
||||||
check_ty(tcx, local.ty, local.source_info.span)?;
|
check_ty(tcx, local.ty, local.source_info.span)?;
|
||||||
|
|
|
@ -17,7 +17,7 @@ use rustc_lint::LateContext;
|
||||||
use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
use rustc_middle::mir::interpret::{ConstValue, Scalar};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv,
|
self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv,
|
||||||
Predicate, PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||||
TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr,
|
TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{GenericArg, GenericArgKind};
|
use rustc_middle::ty::{GenericArg, GenericArgKind};
|
||||||
|
@ -563,7 +563,7 @@ fn is_uninit_value_valid_for_ty_fallback<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an iterator over all predicates which apply to the given item.
|
/// Gets an iterator over all predicates which apply to the given item.
|
||||||
pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator<Item = &(Predicate<'_>, Span)> {
|
pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator<Item = &(ty::Clause<'_>, Span)> {
|
||||||
let mut next_id = Some(id);
|
let mut next_id = Some(id);
|
||||||
iter::from_fn(move || {
|
iter::from_fn(move || {
|
||||||
next_id.take().map(|id| {
|
next_id.take().map(|id| {
|
||||||
|
@ -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(
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds(
|
||||||
cx,
|
cx,
|
||||||
ty,
|
ty,
|
||||||
cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs).map(|c| c.as_predicate()),
|
cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs),
|
||||||
cx.tcx.opt_parent(def_id),
|
cx.tcx.opt_parent(def_id),
|
||||||
),
|
),
|
||||||
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
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>(
|
fn sig_from_bounds<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
predicates: impl IntoIterator<Item = Predicate<'tcx>>,
|
predicates: impl IntoIterator<Item = ty::Clause<'tcx>>,
|
||||||
predicates_id: Option<DefId>,
|
predicates_id: Option<DefId>,
|
||||||
) -> Option<ExprFnSig<'tcx>> {
|
) -> Option<ExprFnSig<'tcx>> {
|
||||||
let mut inputs = None;
|
let mut inputs = None;
|
||||||
|
@ -707,7 +707,7 @@ fn sig_from_bounds<'tcx>(
|
||||||
|
|
||||||
for pred in predicates {
|
for pred in predicates {
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
PredicateKind::Clause(ty::ClauseKind::Trait(p))
|
ty::ClauseKind::Trait(p)
|
||||||
if (lang_items.fn_trait() == Some(p.def_id())
|
if (lang_items.fn_trait() == Some(p.def_id())
|
||||||
|| lang_items.fn_mut_trait() == Some(p.def_id())
|
|| lang_items.fn_mut_trait() == Some(p.def_id())
|
||||||
|| lang_items.fn_once_trait() == Some(p.def_id()))
|
|| lang_items.fn_once_trait() == Some(p.def_id()))
|
||||||
|
@ -720,7 +720,7 @@ fn sig_from_bounds<'tcx>(
|
||||||
}
|
}
|
||||||
inputs = Some(i);
|
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() && p.projection_ty.self_ty() == ty =>
|
if Some(p.projection_ty.def_id) == lang_items.fn_once_output() && p.projection_ty.self_ty() == ty =>
|
||||||
{
|
{
|
||||||
if output.is_some() {
|
if output.is_some() {
|
||||||
|
@ -937,7 +937,7 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the type is a type parameter implementing `FnOnce`, but not `FnMut`.
|
/// Checks if the type is a type parameter implementing `FnOnce`, but not `FnMut`.
|
||||||
pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [Predicate<'_>]) -> bool {
|
pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [ty::Clause<'_>]) -> bool {
|
||||||
let ty::Param(ty) = *ty.kind() else {
|
let ty::Param(ty) = *ty.kind() else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -950,7 +950,7 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc
|
||||||
predicates
|
predicates
|
||||||
.iter()
|
.iter()
|
||||||
.try_fold(false, |found, p| {
|
.try_fold(false, |found, p| {
|
||||||
if let PredicateKind::Clause(ty::ClauseKind::Trait(p)) = p.kind().skip_binder()
|
if let ty::ClauseKind::Trait(p) = p.kind().skip_binder()
|
||||||
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
|
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
|
||||||
&& ty.index == self_ty.index
|
&& ty.index == self_ty.index
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
error: the type `S` is not well-formed
|
error[E0277]: the trait bound `S: Bar` is not satisfied
|
||||||
--> $DIR/recursive_where_clause_on_type.rs:28:11
|
--> $DIR/recursive_where_clause_on_type.rs:14:14
|
||||||
|
|
|
|
||||||
LL | foo::<S>()
|
LL | impl Foo for S {
|
||||||
| ^
|
| ^ the trait `Bar` is not implemented for `S`
|
||||||
|
|
|
||||||
|
note: required by a bound in `Foo`
|
||||||
|
--> $DIR/recursive_where_clause_on_type.rs:10:12
|
||||||
|
|
|
||||||
|
LL | trait Foo: Bar { }
|
||||||
|
| ^^^ required by this bound in `Foo`
|
||||||
|
|
||||||
error: the type `S` is not well-formed
|
error: the type `S` is not well-formed
|
||||||
--> $DIR/recursive_where_clause_on_type.rs:28:5
|
--> $DIR/recursive_where_clause_on_type.rs:14:14
|
||||||
|
|
|
|
||||||
LL | foo::<S>()
|
LL | impl Foo for S {
|
||||||
| ^^^^^^^^
|
| ^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue