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 @@ pub(crate) fn push_const_bound(
&mut self, &mut self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
bound_trait_ref: ty::PolyTraitRef<'tcx>, bound_trait_ref: ty::PolyTraitRef<'tcx>,
host: ty::HostPolarity, constness: ty::BoundConstness,
span: Span, span: Span,
) { ) {
if tcx.is_const_trait(bound_trait_ref.def_id()) { 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 { } else {
tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait"); 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), tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args),
) )
.map(|(trait_ref, _)| { .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, tcx,
cause, cause,
param_env, 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), tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args),
) )
.map(|(trait_ref, _)| { .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, tcx,
cause, cause,
param_env, 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, tcx,
mk_cause(span), mk_cause(span),
param_env, 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), ObligationCauseCode::WellFormed(None),
), ),
wfcx.param_env, 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() { match clause.kind().skip_binder() {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate { ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref: _, trait_ref: _,
host: ty::HostPolarity::Maybe, constness: ty::BoundConstness::Maybe,
}) => {} }) => {}
_ => { _ => {
bug!( bug!(
@ -732,8 +732,8 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
match clause.kind().skip_binder() { match clause.kind().skip_binder() {
ty::ClauseKind::HostEffect(pred) => { ty::ClauseKind::HostEffect(pred) => {
assert_eq!( assert_eq!(
pred.host, pred.constness,
ty::HostPolarity::Maybe, ty::BoundConstness::Maybe,
"expected `~const` predicate when computing `{filter:?}` \ "expected `~const` predicate when computing `{filter:?}` \
implied bounds: {clause:?}", implied bounds: {clause:?}",
); );
@ -943,7 +943,7 @@ pub(super) fn const_conditions<'tcx>(
bounds.push_const_bound( bounds.push_const_bound(
tcx, tcx,
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())), ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())),
ty::HostPolarity::Maybe, ty::BoundConstness::Maybe,
DUMMY_SP, DUMMY_SP,
); );
@ -963,7 +963,7 @@ pub(super) fn const_conditions<'tcx>(
clause.kind().map_bound(|clause| match clause { clause.kind().map_bound(|clause| match clause {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate { ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref, trait_ref,
host: ty::HostPolarity::Maybe, constness: ty::BoundConstness::Maybe,
}) => trait_ref, }) => trait_ref,
_ => bug!("converted {clause:?}"), _ => bug!("converted {clause:?}"),
}), }),
@ -1001,7 +1001,7 @@ pub(super) fn implied_const_bounds<'tcx>(
clause.kind().map_bound(|clause| match clause { clause.kind().map_bound(|clause| match clause {
ty::ClauseKind::HostEffect(ty::HostEffectPredicate { ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref, trait_ref,
host: ty::HostPolarity::Maybe, constness: ty::BoundConstness::Maybe,
}) => trait_ref, }) => trait_ref,
_ => bug!("converted {clause:?}"), _ => bug!("converted {clause:?}"),
}), }),

View File

@ -713,7 +713,7 @@ pub(crate) fn lower_poly_trait_ref(
bounds.push_const_bound( bounds.push_const_bound(
tcx, tcx,
poly_trait_ref, poly_trait_ref,
ty::HostPolarity::Const, ty::BoundConstness::Const,
span, span,
); );
} }
@ -736,7 +736,12 @@ pub(crate) fn lower_poly_trait_ref(
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness {
hir::BoundConstness::Maybe(span) => { hir::BoundConstness::Maybe(span) => {
if polarity == ty::PredicatePolarity::Positive { 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 => {} hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}

View File

@ -853,9 +853,9 @@ pub(super) fn enforce_context_effects(
let host = match self.tcx.hir().body_const_context(self.body_id) { let host = match self.tcx.hir().body_const_context(self.body_id) {
Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => { 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, None => return,
}; };

View File

@ -76,8 +76,8 @@
}; };
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
use crate::ty::{ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs, self, AdtDef, AdtDefData, AdtKind, Binder, BoundConstness, Clause, Clauses, Const, GenericArg,
GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo, GenericArgs, GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo,
ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
TyKind, TyVid, Visibility, TyKind, TyVid, Visibility,
@ -2205,7 +2205,7 @@ fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>} nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
TrivialLiftImpls! { TrivialLiftImpls! {
ImplPolarity, PredicatePolarity, Promoted, HostPolarity, ImplPolarity, PredicatePolarity, Promoted, BoundConstness,
} }
macro_rules! sty_debug_print { macro_rules! sty_debug_print {

View File

@ -267,7 +267,7 @@ fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
} }
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate { ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
trait_ref, trait_ref,
host: _, constness: _,
})) => { })) => {
self.add_args(trait_ref.args); self.add_args(trait_ref.args);
} }

View File

@ -1959,7 +1959,7 @@ fn pretty_print_bound_constness(
ty::BoundConstness::Const => { ty::BoundConstness::Const => {
p!("const "); p!("const ");
} }
ty::BoundConstness::ConstIfConst => { ty::BoundConstness::Maybe => {
p!("~const "); p!("~const ");
} }
} }
@ -3076,9 +3076,9 @@ macro_rules! define_print_and_forward_display {
} }
ty::HostEffectPredicate<'tcx> { ty::HostEffectPredicate<'tcx> {
let constness = match self.host { let constness = match self.constness {
ty::HostPolarity::Const => { "const" } ty::BoundConstness::Const => { "const" }
ty::HostPolarity::Maybe => { "~const" } ty::BoundConstness::Maybe => { "~const" }
}; };
p!(print(self.trait_ref.self_ty()), ": {constness} "); p!(print(self.trait_ref.self_ty()), ": {constness} ");
p!(print(self.trait_ref.print_trait_sugared())) p!(print(self.trait_ref.print_trait_sugared()))

View File

@ -44,7 +44,7 @@ fn probe_and_match_goal_against_assumption(
) -> Result<Candidate<I>, NoSolution> { ) -> Result<Candidate<I>, NoSolution> {
if let Some(host_clause) = assumption.as_host_effect_clause() { if let Some(host_clause) = assumption.as_host_effect_clause() {
if host_clause.def_id() == goal.predicate.def_id() 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( if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
goal.predicate.trait_ref.args, goal.predicate.trait_ref.args,
@ -91,7 +91,7 @@ fn consider_additional_alias_assumptions(
cx, cx,
cx.implied_const_bounds(alias_ty.def_id) cx.implied_const_bounds(alias_ty.def_id)
.iter_instantiated(cx, alias_ty.args) .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( candidates.extend(Self::probe_and_match_goal_against_assumption(
ecx, ecx,
@ -107,7 +107,7 @@ fn consider_additional_alias_assumptions(
.map(|trait_ref| { .map(|trait_ref| {
goal.with( goal.with(
cx, 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 @@ fn consider_impl_candidate(
.const_conditions(impl_def_id) .const_conditions(impl_def_id)
.iter_instantiated(cx, impl_args) .iter_instantiated(cx, impl_args)
.map(|bound_trait_ref| { .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); ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);

View File

@ -139,7 +139,7 @@ fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> V::Result {
} }
ty::ClauseKind::HostEffect(pred) => { ty::ClauseKind::HostEffect(pred) => {
try_visit!(self.visit_trait(pred.trait_ref)); try_visit!(self.visit_trait(pred.trait_ref));
pred.host.visit_with(self) pred.constness.visit_with(self)
} }
ty::ClauseKind::Projection(ty::ProjectionPredicate { ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_term: projection_ty, projection_term: projection_ty,

View File

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

View File

@ -47,7 +47,7 @@ fn match_candidate<'tcx>(
obligation: &HostEffectObligation<'tcx>, obligation: &HostEffectObligation<'tcx>,
candidate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>, candidate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, NoSolution> { ) -> 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); return Err(NoSolution);
} }
@ -135,7 +135,8 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
.map(|(trait_ref, _)| { .map(|(trait_ref, _)| {
obligation.with( obligation.with(
tcx, 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) { if tcx.is_conditionally_const(def_id) {
predicates.extend( predicates.extend(
tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map( 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 @@ fn elaborate(&mut self, elaboratable: &O) {
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
elaboratable.child( elaboratable.child(
trait_ref 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)), .instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
) )
}), }),

View File

@ -112,9 +112,9 @@ pub fn def_id(&self) -> I::DefId {
self.skip_binder().def_id 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| { self.map_bound(|trait_ref| {
ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host }) ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, constness })
}) })
.upcast(cx) .upcast(cx)
} }
@ -757,7 +757,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub struct HostEffectPredicate<I: Interner> { pub struct HostEffectPredicate<I: Interner> {
pub trait_ref: ty::TraitRef<I>, pub trait_ref: ty::TraitRef<I>,
pub host: HostPolarity, pub constness: BoundConstness,
} }
impl<I: Interner> HostEffectPredicate<I> { impl<I: Interner> HostEffectPredicate<I> {
@ -785,28 +785,8 @@ pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
} }
#[inline] #[inline]
pub fn host(self) -> HostPolarity { pub fn constness(self) -> BoundConstness {
self.skip_binder().host self.skip_binder().constness
}
}
#[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,
}
} }
} }
@ -831,8 +811,8 @@ pub struct CoercePredicate<I: Interner> {
pub b: I::Ty, pub b: I::Ty,
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext, TyEncodable, TyDecodable))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum BoundConstness { pub enum BoundConstness {
/// `Type: const Trait` /// `Type: const Trait`
/// ///
@ -841,14 +821,22 @@ pub enum BoundConstness {
/// `Type: ~const Trait` /// `Type: ~const Trait`
/// ///
/// Requires resolving to const only when we are in a const context. /// Requires resolving to const only when we are in a const context.
ConstIfConst, Maybe,
} }
impl BoundConstness { 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 { pub fn as_str(self) -> &'static str {
match self { match self {
Self::Const => "const", 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 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Const => f.write_str("const"), 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)
}
}