specialization: use clause
This commit is contained in:
parent
a4f6770d83
commit
aac29a0fc3
1 changed files with 23 additions and 37 deletions
|
@ -376,9 +376,9 @@ fn check_predicates<'tcx>(
|
||||||
let always_applicable_traits = impl1_predicates
|
let always_applicable_traits = impl1_predicates
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|(clause, _span)| {
|
.filter(|&(clause, _span)| {
|
||||||
matches!(
|
matches!(
|
||||||
trait_predicate_kind(tcx, clause.as_predicate()),
|
trait_specialization_kind(tcx, clause),
|
||||||
Some(TraitSpecializationKind::AlwaysApplicable)
|
Some(TraitSpecializationKind::AlwaysApplicable)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -402,7 +402,7 @@ fn check_predicates<'tcx>(
|
||||||
.iter()
|
.iter()
|
||||||
.any(|pred2| trait_predicates_eq(tcx, clause.as_predicate(), *pred2, span))
|
.any(|pred2| trait_predicates_eq(tcx, clause.as_predicate(), *pred2, span))
|
||||||
{
|
{
|
||||||
check_specialization_on(tcx, clause.as_predicate(), span)
|
check_specialization_on(tcx, clause, span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,19 +441,16 @@ fn trait_predicates_eq<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(tcx))]
|
#[instrument(level = "debug", skip(tcx))]
|
||||||
fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
|
fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, clause: ty::Clause<'tcx>, span: Span) {
|
||||||
match predicate.kind().skip_binder() {
|
match clause.kind().skip_binder() {
|
||||||
// Global predicates are either always true or always false, so we
|
// Global predicates are either always true or always false, so we
|
||||||
// are fine to specialize on.
|
// are fine to specialize on.
|
||||||
_ if predicate.is_global() => (),
|
_ if clause.is_global() => (),
|
||||||
// We allow specializing on explicitly marked traits with no associated
|
// We allow specializing on explicitly marked traits with no associated
|
||||||
// items.
|
// items.
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
|
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
||||||
trait_ref,
|
|
||||||
polarity: _,
|
|
||||||
})) => {
|
|
||||||
if !matches!(
|
if !matches!(
|
||||||
trait_predicate_kind(tcx, predicate),
|
trait_specialization_kind(tcx, clause),
|
||||||
Some(TraitSpecializationKind::Marker)
|
Some(TraitSpecializationKind::Marker)
|
||||||
) {
|
) {
|
||||||
tcx.sess
|
tcx.sess
|
||||||
|
@ -467,10 +464,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
|
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
||||||
projection_ty,
|
|
||||||
term,
|
|
||||||
})) => {
|
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
span,
|
span,
|
||||||
|
@ -478,7 +472,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => {
|
ty::ClauseKind::ConstArgHasType(..) => {
|
||||||
// FIXME(min_specialization), FIXME(const_generics):
|
// FIXME(min_specialization), FIXME(const_generics):
|
||||||
// It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure
|
// It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure
|
||||||
// about the actual rules that would be sound. Can't just always error here because otherwise
|
// about the actual rules that would be sound. Can't just always error here because otherwise
|
||||||
|
@ -490,33 +484,25 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.struct_span_err(span, format!("cannot specialize on predicate `{predicate}`"))
|
.struct_span_err(span, format!("cannot specialize on predicate `{clause}`"))
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_predicate_kind<'tcx>(
|
fn trait_specialization_kind<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicate: ty::Predicate<'tcx>,
|
clause: ty::Clause<'tcx>,
|
||||||
) -> Option<TraitSpecializationKind> {
|
) -> Option<TraitSpecializationKind> {
|
||||||
match predicate.kind().skip_binder() {
|
match clause.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
|
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
||||||
trait_ref,
|
Some(tcx.trait_def(trait_ref.def_id).specialization_kind)
|
||||||
polarity: _,
|
}
|
||||||
})) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
|
| ty::ClauseKind::TypeOutlives(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(_))
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::ClauseKind::ConstEvaluatable(..) => None,
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
|
|
||||||
| ty::PredicateKind::Subtype(_)
|
|
||||||
| ty::PredicateKind::Coerce(_)
|
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
|
||||||
| ty::PredicateKind::Ambiguous => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue