Implement const effect predicate in new solver
This commit is contained in:
parent
a16d491054
commit
cde29b9ec9
127 changed files with 1702 additions and 1170 deletions
|
@ -370,6 +370,7 @@ tcx_lifetime! {
|
|||
rustc_middle::ty::FnSig,
|
||||
rustc_middle::ty::GenericArg,
|
||||
rustc_middle::ty::GenericPredicates,
|
||||
rustc_middle::ty::ConstConditions,
|
||||
rustc_middle::ty::inhabitedness::InhabitedPredicate,
|
||||
rustc_middle::ty::Instance,
|
||||
rustc_middle::ty::InstanceKind,
|
||||
|
|
|
@ -683,6 +683,24 @@ rustc_queries! {
|
|||
}
|
||||
}
|
||||
|
||||
query const_conditions(
|
||||
key: DefId
|
||||
) -> ty::ConstConditions<'tcx> {
|
||||
desc { |tcx| "computing the conditions for `{}` to be considered const",
|
||||
tcx.def_path_str(key)
|
||||
}
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
query implied_const_bounds(
|
||||
key: DefId
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
||||
tcx.def_path_str(key)
|
||||
}
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
/// To avoid cycles within the predicates of a single item we compute
|
||||
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
||||
query type_param_predicates(
|
||||
|
|
|
@ -386,6 +386,17 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Claus
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
||||
for [(ty::PolyTraitRef<'tcx>, Span)]
|
||||
{
|
||||
fn decode(decoder: &mut D) -> &'tcx Self {
|
||||
decoder
|
||||
.interner()
|
||||
.arena
|
||||
.alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
||||
for ty::List<ty::BoundVariableKind>
|
||||
{
|
||||
|
|
|
@ -78,10 +78,10 @@ use crate::traits::solve::{
|
|||
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
|
||||
use crate::ty::{
|
||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
|
||||
GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst,
|
||||
ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
|
||||
PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
||||
Visibility,
|
||||
GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo,
|
||||
ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate,
|
||||
PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
|
||||
TyKind, TyVid, Visibility,
|
||||
};
|
||||
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
|
@ -383,6 +383,28 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
||||
}
|
||||
|
||||
fn is_const_impl(self, def_id: DefId) -> bool {
|
||||
self.constness(def_id) == hir::Constness::Const
|
||||
}
|
||||
|
||||
fn const_conditions(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
|
||||
)
|
||||
}
|
||||
|
||||
fn implied_const_bounds(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||
)
|
||||
}
|
||||
|
||||
fn has_target_features(self, def_id: DefId) -> bool {
|
||||
!self.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||
}
|
||||
|
@ -2189,7 +2211,7 @@ macro_rules! nop_slice_lift {
|
|||
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
|
||||
|
||||
TrivialLiftImpls! {
|
||||
ImplPolarity, PredicatePolarity, Promoted
|
||||
ImplPolarity, PredicatePolarity, Promoted, HostPolarity,
|
||||
}
|
||||
|
||||
macro_rules! sty_debug_print {
|
||||
|
|
|
@ -265,6 +265,12 @@ impl FlagComputation {
|
|||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
|
||||
self.add_args(trait_pred.trait_ref.args);
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||
trait_ref,
|
||||
host: _,
|
||||
})) => {
|
||||
self.add_args(trait_ref.args);
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
||||
a,
|
||||
b,
|
||||
|
|
|
@ -422,3 +422,73 @@ impl<'tcx> GenericPredicates<'tcx> {
|
|||
instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
|
||||
}
|
||||
}
|
||||
|
||||
/// `~const` bounds for a given item. This is represented using a struct much like
|
||||
/// `GenericPredicates`, where you can either choose to only instantiate the "own"
|
||||
/// bounds or all of the bounds including those from the parent. This distinction
|
||||
/// is necessary for code like `compare_method_predicate_entailment`.
|
||||
#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct ConstConditions<'tcx> {
|
||||
pub parent: Option<DefId>,
|
||||
pub predicates: &'tcx [(ty::PolyTraitRef<'tcx>, Span)],
|
||||
}
|
||||
|
||||
impl<'tcx> ConstConditions<'tcx> {
|
||||
pub fn instantiate(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
|
||||
let mut instantiated = vec![];
|
||||
self.instantiate_into(tcx, &mut instantiated, args);
|
||||
instantiated
|
||||
}
|
||||
|
||||
pub fn instantiate_own(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
||||
{
|
||||
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
|
||||
}
|
||||
|
||||
pub fn instantiate_own_identity(
|
||||
self,
|
||||
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
||||
{
|
||||
EarlyBinder::bind(self.predicates).iter_identity_copied()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, tcx))]
|
||||
fn instantiate_into(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) {
|
||||
if let Some(def_id) = self.parent {
|
||||
tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args);
|
||||
}
|
||||
instantiated.extend(
|
||||
self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
|
||||
let mut instantiated = vec![];
|
||||
self.instantiate_identity_into(tcx, &mut instantiated);
|
||||
instantiated
|
||||
}
|
||||
|
||||
fn instantiate_identity_into(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
|
||||
) {
|
||||
if let Some(def_id) = self.parent {
|
||||
tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated);
|
||||
}
|
||||
instantiated.extend(self.predicates.iter().copied());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,13 @@ pub use self::parameterized::ParameterizedOverTcx;
|
|||
pub use self::pattern::{Pattern, PatternKind};
|
||||
pub use self::predicate::{
|
||||
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
|
||||
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo,
|
||||
OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
|
||||
PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
|
||||
PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
|
||||
PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
|
||||
TraitPredicate, TraitRef, TypeOutlivesPredicate,
|
||||
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
|
||||
HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
|
||||
PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
|
||||
PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
|
||||
PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
|
||||
RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef,
|
||||
TypeOutlivesPredicate,
|
||||
};
|
||||
pub use self::region::BoundRegionKind::*;
|
||||
pub use self::region::{
|
||||
|
|
|
@ -132,6 +132,7 @@ parameterized_over_tcx! {
|
|||
ty::Ty,
|
||||
ty::FnSig,
|
||||
ty::GenericPredicates,
|
||||
ty::ConstConditions,
|
||||
ty::TraitRef,
|
||||
ty::Const,
|
||||
ty::Predicate,
|
||||
|
|
|
@ -19,6 +19,7 @@ pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
|
|||
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
|
||||
pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
|
||||
pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
|
||||
pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate<TyCtxt<'tcx>>;
|
||||
pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
|
||||
pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
|
||||
pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
|
||||
|
@ -143,6 +144,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||
| PredicateKind::AliasRelate(..)
|
||||
| PredicateKind::NormalizesTo(..) => false,
|
||||
PredicateKind::Clause(ClauseKind::Trait(_))
|
||||
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
|
||||
| PredicateKind::Clause(ClauseKind::TypeOutlives(_))
|
||||
| PredicateKind::Clause(ClauseKind::Projection(_))
|
||||
|
@ -644,6 +646,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||
match predicate.skip_binder() {
|
||||
PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
|
||||
PredicateKind::Clause(ClauseKind::Projection(..))
|
||||
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
||||
| PredicateKind::NormalizesTo(..)
|
||||
| PredicateKind::AliasRelate(..)
|
||||
|
@ -664,6 +667,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||
match predicate.skip_binder() {
|
||||
PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
|
||||
PredicateKind::Clause(ClauseKind::Trait(..))
|
||||
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
||||
| PredicateKind::NormalizesTo(..)
|
||||
| PredicateKind::AliasRelate(..)
|
||||
|
|
|
@ -3075,6 +3075,15 @@ define_print! {
|
|||
p!(print(self.trait_ref.print_trait_sugared()))
|
||||
}
|
||||
|
||||
ty::HostEffectPredicate<'tcx> {
|
||||
let constness = match self.host {
|
||||
ty::HostPolarity::Const => { "const" }
|
||||
ty::HostPolarity::Maybe => { "~const" }
|
||||
};
|
||||
p!(print(self.trait_ref.self_ty()), ": {constness} ");
|
||||
p!(print(self.trait_ref.print_trait_sugared()))
|
||||
}
|
||||
|
||||
ty::TypeAndMut<'tcx> {
|
||||
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
|
||||
}
|
||||
|
@ -3087,6 +3096,7 @@ define_print! {
|
|||
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue