Merge HostPolarity and BoundConstness

This commit is contained in:
Michael Goulet 2024-10-29 23:42:59 +00:00
parent 298c7462c3
commit 802f3a78a6
16 changed files with 66 additions and 81 deletions

View File

@ -84,11 +84,11 @@ impl<'tcx> Bounds<'tcx> {
&mut self,
tcx: TyCtxt<'tcx>,
bound_trait_ref: ty::PolyTraitRef<'tcx>,
host: ty::HostPolarity,
constness: ty::BoundConstness,
span: Span,
) {
if tcx.is_const_trait(bound_trait_ref.def_id()) {
self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span));
self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, constness), span));
} else {
tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait");
}

View File

@ -218,7 +218,7 @@ fn compare_method_predicate_entailment<'tcx>(
tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args),
)
.map(|(trait_ref, _)| {
trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe)
}),
);
}
@ -272,7 +272,7 @@ fn compare_method_predicate_entailment<'tcx>(
tcx,
cause,
param_env,
const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
const_condition.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
));
}
}
@ -1942,7 +1942,7 @@ fn compare_type_predicate_entailment<'tcx>(
tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args),
)
.map(|(trait_ref, _)| {
trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe)
}),
);
}
@ -1985,7 +1985,7 @@ fn compare_type_predicate_entailment<'tcx>(
tcx,
cause,
param_env,
const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
const_condition.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
));
}
}
@ -2091,7 +2091,7 @@ pub(super) fn check_type_bounds<'tcx>(
tcx,
mk_cause(span),
param_env,
c.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
)
}),
);

View File

@ -1389,7 +1389,7 @@ fn check_impl<'tcx>(
ObligationCauseCode::WellFormed(None),
),
wfcx.param_env,
bound.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
bound.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
))
}
}

View File

@ -716,7 +716,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
match clause.kind().skip_binder() {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref: _,
host: ty::HostPolarity::Maybe,
constness: ty::BoundConstness::Maybe,
}) => {}
_ => {
bug!(
@ -732,8 +732,8 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
match clause.kind().skip_binder() {
ty::ClauseKind::HostEffect(pred) => {
assert_eq!(
pred.host,
ty::HostPolarity::Maybe,
pred.constness,
ty::BoundConstness::Maybe,
"expected `~const` predicate when computing `{filter:?}` \
implied bounds: {clause:?}",
);
@ -943,7 +943,7 @@ pub(super) fn const_conditions<'tcx>(
bounds.push_const_bound(
tcx,
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())),
ty::HostPolarity::Maybe,
ty::BoundConstness::Maybe,
DUMMY_SP,
);
@ -963,7 +963,7 @@ pub(super) fn const_conditions<'tcx>(
clause.kind().map_bound(|clause| match clause {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref,
host: ty::HostPolarity::Maybe,
constness: ty::BoundConstness::Maybe,
}) => trait_ref,
_ => bug!("converted {clause:?}"),
}),
@ -1001,7 +1001,7 @@ pub(super) fn implied_const_bounds<'tcx>(
clause.kind().map_bound(|clause| match clause {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref,
host: ty::HostPolarity::Maybe,
constness: ty::BoundConstness::Maybe,
}) => trait_ref,
_ => bug!("converted {clause:?}"),
}),

View File

@ -713,7 +713,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
bounds.push_const_bound(
tcx,
poly_trait_ref,
ty::HostPolarity::Const,
ty::BoundConstness::Const,
span,
);
}
@ -736,7 +736,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness {
hir::BoundConstness::Maybe(span) => {
if polarity == ty::PredicatePolarity::Positive {
bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span);
bounds.push_const_bound(
tcx,
poly_trait_ref,
ty::BoundConstness::Maybe,
span,
);
}
}
hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}

View File

@ -853,9 +853,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let host = match self.tcx.hir().body_const_context(self.body_id) {
Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {
ty::HostPolarity::Const
ty::BoundConstness::Const
}
Some(hir::ConstContext::ConstFn) => ty::HostPolarity::Maybe,
Some(hir::ConstContext::ConstFn) => ty::BoundConstness::Maybe,
None => return,
};

View File

@ -76,8 +76,8 @@ 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, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo,
self, AdtDef, AdtDefData, AdtKind, Binder, BoundConstness, 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,
@ -2205,7 +2205,7 @@ macro_rules! nop_slice_lift {
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
TrivialLiftImpls! {
ImplPolarity, PredicatePolarity, Promoted, HostPolarity,
ImplPolarity, PredicatePolarity, Promoted, BoundConstness,
}
macro_rules! sty_debug_print {

View File

@ -267,7 +267,7 @@ impl FlagComputation {
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref,
host: _,
constness: _,
})) => {
self.add_args(trait_ref.args);
}

View File

@ -1959,7 +1959,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
ty::BoundConstness::Const => {
p!("const ");
}
ty::BoundConstness::ConstIfConst => {
ty::BoundConstness::Maybe => {
p!("~const ");
}
}
@ -3076,9 +3076,9 @@ define_print! {
}
ty::HostEffectPredicate<'tcx> {
let constness = match self.host {
ty::HostPolarity::Const => { "const" }
ty::HostPolarity::Maybe => { "~const" }
let constness = match self.constness {
ty::BoundConstness::Const => { "const" }
ty::BoundConstness::Maybe => { "~const" }
};
p!(print(self.trait_ref.self_ty()), ": {constness} ");
p!(print(self.trait_ref.print_trait_sugared()))

View File

@ -44,7 +44,7 @@ where
) -> Result<Candidate<I>, NoSolution> {
if let Some(host_clause) = assumption.as_host_effect_clause() {
if host_clause.def_id() == goal.predicate.def_id()
&& host_clause.host().satisfies(goal.predicate.host)
&& host_clause.constness().satisfies(goal.predicate.constness)
{
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args,
@ -91,7 +91,7 @@ where
cx,
cx.implied_const_bounds(alias_ty.def_id)
.iter_instantiated(cx, alias_ty.args)
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.host)),
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
) {
candidates.extend(Self::probe_and_match_goal_against_assumption(
ecx,
@ -107,7 +107,7 @@ where
.map(|trait_ref| {
goal.with(
cx,
trait_ref.to_host_effect_clause(cx, goal.predicate.host),
trait_ref.to_host_effect_clause(cx, goal.predicate.constness),
)
}),
);
@ -163,7 +163,10 @@ where
.const_conditions(impl_def_id)
.iter_instantiated(cx, impl_args)
.map(|bound_trait_ref| {
goal.with(cx, bound_trait_ref.to_host_effect_clause(cx, goal.predicate.host))
goal.with(
cx,
bound_trait_ref.to_host_effect_clause(cx, goal.predicate.constness),
)
});
ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);

View File

@ -139,7 +139,7 @@ where
}
ty::ClauseKind::HostEffect(pred) => {
try_visit!(self.visit_trait(pred.trait_ref));
pred.host.visit_with(self)
pred.constness.visit_with(self)
}
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_term: projection_ty,

View File

@ -545,10 +545,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
polarity: ty::PredicatePolarity::Positive,
}),
None,
Some(match predicate.host {
ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst,
ty::HostPolarity::Const => ty::BoundConstness::Const,
}),
Some(predicate.constness),
None,
String::new(),
);
@ -2238,18 +2235,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
(None, _) => Some(cannot_do_this),
// suggested using default post message
(
Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst),
Some(ty::BoundConstness::Const | ty::BoundConstness::Maybe),
Some(AppendConstMessage::Default),
) => Some(format!("{cannot_do_this} in const contexts")),
// overridden post message
(
Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst),
Some(ty::BoundConstness::Const | ty::BoundConstness::Maybe),
Some(AppendConstMessage::Custom(custom_msg, _)),
) => Some(format!("{cannot_do_this}{custom_msg}")),
// fallback to generic message
(Some(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst), None) => {
None
}
(Some(ty::BoundConstness::Const | ty::BoundConstness::Maybe), None) => None,
}
})
.unwrap_or_else(|| {

View File

@ -47,7 +47,7 @@ fn match_candidate<'tcx>(
obligation: &HostEffectObligation<'tcx>,
candidate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, NoSolution> {
if !candidate.skip_binder().host.satisfies(obligation.predicate.host) {
if !candidate.skip_binder().constness.satisfies(obligation.predicate.constness) {
return Err(NoSolution);
}
@ -135,7 +135,8 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
.map(|(trait_ref, _)| {
obligation.with(
tcx,
trait_ref.to_host_effect_clause(tcx, obligation.predicate.host),
trait_ref
.to_host_effect_clause(tcx, obligation.predicate.constness),
)
}),
);

View File

@ -155,7 +155,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
if tcx.is_conditionally_const(def_id) {
predicates.extend(
tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map(
|(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
|(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
),
);
}

View File

@ -160,7 +160,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
elaboratable.child(
trait_ref
.to_host_effect_clause(cx, data.host)
.to_host_effect_clause(cx, data.constness)
.instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
)
}),

View File

@ -112,9 +112,9 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
self.skip_binder().def_id
}
pub fn to_host_effect_clause(self, cx: I, host: HostPolarity) -> I::Clause {
pub fn to_host_effect_clause(self, cx: I, constness: BoundConstness) -> I::Clause {
self.map_bound(|trait_ref| {
ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host })
ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
})
.upcast(cx)
}
@ -757,7 +757,7 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub struct HostEffectPredicate<I: Interner> {
pub trait_ref: ty::TraitRef<I>,
pub host: HostPolarity,
pub constness: BoundConstness,
}
impl<I: Interner> HostEffectPredicate<I> {
@ -785,28 +785,8 @@ impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
}
#[inline]
pub fn host(self) -> HostPolarity {
self.skip_binder().host
}
}
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum HostPolarity {
/// May be called in const environments if the callee is const.
Maybe,
/// Always allowed to be called in const environments.
Const,
}
impl HostPolarity {
pub fn satisfies(self, goal: HostPolarity) -> bool {
match (self, goal) {
(HostPolarity::Const, HostPolarity::Const | HostPolarity::Maybe) => true,
(HostPolarity::Maybe, HostPolarity::Maybe) => true,
(HostPolarity::Maybe, HostPolarity::Const) => false,
}
pub fn constness(self) -> BoundConstness {
self.skip_binder().constness
}
}
@ -831,8 +811,8 @@ pub struct CoercePredicate<I: Interner> {
pub b: I::Ty,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext, TyEncodable, TyDecodable))]
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum BoundConstness {
/// `Type: const Trait`
///
@ -841,14 +821,22 @@ pub enum BoundConstness {
/// `Type: ~const Trait`
///
/// Requires resolving to const only when we are in a const context.
ConstIfConst,
Maybe,
}
impl BoundConstness {
pub fn satisfies(self, goal: BoundConstness) -> bool {
match (self, goal) {
(BoundConstness::Const, BoundConstness::Const | BoundConstness::Maybe) => true,
(BoundConstness::Maybe, BoundConstness::Maybe) => true,
(BoundConstness::Maybe, BoundConstness::Const) => false,
}
}
pub fn as_str(self) -> &'static str {
match self {
Self::Const => "const",
Self::ConstIfConst => "~const",
Self::Maybe => "~const",
}
}
}
@ -857,14 +845,7 @@ impl fmt::Display for BoundConstness {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Const => f.write_str("const"),
Self::ConstIfConst => f.write_str("~const"),
Self::Maybe => f.write_str("~const"),
}
}
}
impl<I> Lift<I> for BoundConstness {
type Lifted = BoundConstness;
fn lift_to_interner(self, _: I) -> Option<Self::Lifted> {
Some(self)
}
}