1
Fork 0

Remove constness from TraitPredicate

This commit is contained in:
Deadbeef 2023-07-29 08:20:25 +00:00
parent 7637653b9f
commit 4fec845c3f
90 changed files with 446 additions and 390 deletions

View file

@ -72,7 +72,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
cause: traits::ObligationCause::dummy(),
param_env,
recursion_depth: 0,
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
predicate: ty::Binder::dummy(trait_ref).to_predicate(self.tcx),
};
self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
}

View file

@ -727,7 +727,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.tcx(),
ty::TraitPredicate {
trait_ref: self_trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
},
);

View file

@ -97,7 +97,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
orig_env,
ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: if polarity {
ImplPolarity::Positive
} else {
@ -260,7 +259,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
trait_ref: ty::TraitRef::new(infcx.tcx, trait_did, [ty]),
constness: ty::BoundConstness::NotConst,
// Auto traits are positive
polarity: ty::ImplPolarity::Positive,
}));

View file

@ -97,7 +97,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
cause,
recursion_depth: 0,
param_env,
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx),
});
}

View file

@ -100,7 +100,6 @@ pub trait InferCtxtExt<'tcx> {
&self,
param_env: ty::ParamEnv<'tcx>,
ty: ty::Binder<'tcx, Ty<'tcx>>,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
}
@ -356,7 +355,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
&self,
param_env: ty::ParamEnv<'tcx>,
ty: ty::Binder<'tcx, Ty<'tcx>>,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> {
self.commit_if_ok(|_| {
@ -372,12 +370,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
});
// FIXME(effects)
let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]);
let obligation = Obligation::new(
self.tcx,
ObligationCause::dummy(),
param_env,
ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
ty.rebind(ty::TraitPredicate { trait_ref, polarity }),
);
let ocx = ObligationCtxt::new(self);
ocx.register_obligation(obligation);
@ -689,8 +688,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
let predicate_is_const = ty::BoundConstness::ConstIfConst
== trait_predicate.skip_binder().constness;
// FIXME(effects)
let predicate_is_const = false;
if self.tcx.sess.has_errors().is_some()
&& trait_predicate.references_error()
@ -1909,9 +1908,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
.all_impls(trait_pred.def_id())
.filter_map(|def_id| {
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative
|| !trait_pred
.skip_binder()
.is_constness_satisfied_by(self.tcx.constness(def_id))
|| !self.tcx.is_user_visible_dep(def_id.krate)
{
return None;
@ -2996,7 +2992,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
obligation.param_env,
trait_ref.self_ty(),
trait_predicate.skip_binder().constness,
trait_predicate.skip_binder().polarity,
)
{
@ -3099,14 +3094,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn maybe_add_note_for_unsatisfied_const(
&self,
obligation: &PredicateObligation<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
err: &mut Diagnostic,
span: Span,
_obligation: &PredicateObligation<'tcx>,
_trait_ref: ty::PolyTraitRef<'tcx>,
_trait_predicate: &ty::PolyTraitPredicate<'tcx>,
_err: &mut Diagnostic,
_span: Span,
) -> UnsatisfiedConst {
let mut unsatisfied_const = UnsatisfiedConst(false);
if trait_predicate.is_const_if_const() {
let unsatisfied_const = UnsatisfiedConst(false);
// FIXME(effects)
/* if trait_predicate.is_const_if_const() {
let non_const_predicate = trait_ref.without_const();
let non_const_obligation = Obligation {
cause: obligation.cause.clone(),
@ -3126,7 +3122,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
),
);
}
}
} */
unsatisfied_const
}

View file

@ -133,7 +133,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
def_id: DefId,
) -> bool {
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const())
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
}
/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?

View file

@ -574,7 +574,6 @@ fn virtual_call_violation_for_method<'tcx>(
// implement auto traits if the underlying type does as well.
if let ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref: pred_trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
}) = pred.kind().skip_binder()
&& pred_trait_ref.self_ty() == tcx.types.self_param

View file

@ -1306,7 +1306,7 @@ fn normalize_to_error<'a, 'tcx>(
cause,
recursion_depth: depth,
param_env,
predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
predicate: trait_ref.to_predicate(selcx.tcx()),
};
let tcx = selcx.infcx.tcx;
let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
@ -1867,8 +1867,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
if selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with(
selcx.tcx(),
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty])
.without_const(),
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),
),
) =>
{
@ -2152,8 +2151,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
LangItem::Sized,
obligation.cause.span(),
[self_ty],
)
.without_const();
);
obligations.push(obligation.with(tcx, sized_predicate));
}
(metadata_ty.into(), obligations)

View file

@ -154,9 +154,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.infcx
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
candidates
.vec
.extend(result.into_iter().map(|(idx, constness)| ProjectionCandidate(idx, constness)));
// FIXME(effects) proper constness needed?
candidates.vec.extend(
result.into_iter().map(|idx| ProjectionCandidate(idx, ty::BoundConstness::NotConst)),
);
}
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller

View file

@ -59,7 +59,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ParamCandidate(param) => {
let obligations =
self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
ImplSource::Param(param.skip_binder().constness, obligations)
// FIXME(effects)
ImplSource::Param(ty::BoundConstness::NotConst, obligations)
}
ImplCandidate(impl_def_id) => {
@ -128,14 +129,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
subobligation.set_depth_from_parent(obligation.recursion_depth);
}
if !obligation.predicate.is_const_if_const() {
// normalize nested predicates according to parent predicate's constness.
impl_src = impl_src.map(|mut o| {
o.predicate = o.predicate.without_const(self.tcx());
o
});
}
Ok(impl_src)
}
@ -1305,6 +1298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable
ty::Alias(ty::Projection | ty::Inherent, ..) => {
// FIXME(effects) this needs constness
let predicate = normalize_with_depth_to(
self,
obligation.param_env,
@ -1317,7 +1311,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cause.span,
[nested_ty],
),
constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive,
}),
&mut nested,
@ -1336,6 +1329,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// since it's either not `const Drop` (and we raise an error during selection),
// or it's an ADT (and we need to check for a custom impl during selection)
_ => {
// FIXME(effects) this needs constness
let predicate = self_ty.rebind(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
self.tcx(),
@ -1343,7 +1337,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cause.span,
[nested_ty],
),
constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive,
});

View file

@ -1583,7 +1583,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn match_projection_obligation_against_definition_bounds(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
) -> smallvec::SmallVec<[usize; 2]> {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate =
self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate);
@ -1632,7 +1632,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_ => false,
}
}) {
return Some((idx, pred.constness));
return Some(idx);
}
}
None
@ -1820,7 +1820,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
(ParamCandidate(other), ParamCandidate(victim)) => {
let same_except_bound_vars = other.skip_binder().trait_ref
== victim.skip_binder().trait_ref
&& other.skip_binder().constness == victim.skip_binder().constness
&& other.skip_binder().polarity == victim.skip_binder().polarity
&& !other.skip_binder().trait_ref.has_escaping_bound_vars();
if same_except_bound_vars {
@ -1830,12 +1829,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// probably best characterized as a "hack", since we might prefer to just do our
// best to *not* create essentially duplicate candidates in the first place.
DropVictim::drop_if(other.bound_vars().len() <= victim.bound_vars().len())
} else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref
&& victim.skip_binder().constness == ty::BoundConstness::NotConst
&& other.skip_binder().polarity == victim.skip_binder().polarity
{
// Drop otherwise equivalent non-const candidates in favor of const candidates.
DropVictim::Yes
} else {
DropVictim::No
}

View file

@ -500,16 +500,12 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
let mut pretty_predicates =
Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
for (mut p, _) in predicates {
for (p, _) in predicates {
if let Some(poly_trait_ref) = p.as_trait_clause() {
if Some(poly_trait_ref.def_id()) == sized_trait {
types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder());
continue;
}
if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness {
p = p.without_const(tcx);
}
}
pretty_predicates.push(p.to_string());
}

View file

@ -101,7 +101,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
let tcx = self.tcx;
let trait_ref = item.trait_ref();
let pred = trait_ref.without_const().to_predicate(tcx);
let pred = trait_ref.to_predicate(tcx);
debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
@ -113,9 +113,13 @@ impl<'tcx> TraitAliasExpander<'tcx> {
// Don't recurse if this trait alias is already on the stack for the DFS search.
let anon_pred = anonymize_predicate(tcx, pred);
if item.path.iter().rev().skip(1).any(|&(tr, _)| {
anonymize_predicate(tcx, tr.without_const().to_predicate(tcx)) == anon_pred
}) {
if item
.path
.iter()
.rev()
.skip(1)
.any(|&(tr, _)| anonymize_predicate(tcx, tr.to_predicate(tcx)) == anon_pred)
{
return false;
}

View file

@ -86,7 +86,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
let mut emit_vptr_on_new_entry = false;
let mut visited = PredicateSet::new(tcx);
let predicate = trait_ref.without_const().to_predicate(tcx);
let predicate = trait_ref.to_predicate(tcx);
let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> =
smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))];
visited.insert(predicate);

View file

@ -348,11 +348,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}
// if the trait predicate is not const, the wf obligations should not be const as well.
let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.args)
} else {
self.nominal_obligations(trait_ref.def_id, trait_ref.args)
};
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.args);
debug!("compute_trait_pred obligations {:?}", obligations);
let param_env = self.param_env;
@ -445,8 +441,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// `i32: Clone`
// `i32: Copy`
// ]
// Projection types do not require const predicates.
let obligations = self.nominal_obligations_without_const(data.def_id, data.args);
let obligations = self.nominal_obligations(data.def_id, data.args);
self.out.extend(obligations);
self.compute_projection_args(data.args);
@ -472,8 +467,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
self.recursion_depth,
&mut self.out,
);
// Inherent projection types do not require const predicates.
let obligations = self.nominal_obligations_without_const(data.def_id, args);
let obligations = self.nominal_obligations(data.def_id, args);
self.out.extend(obligations);
}
@ -516,7 +510,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
cause,
self.recursion_depth,
self.param_env,
ty::Binder::dummy(trait_ref).without_const(),
ty::Binder::dummy(trait_ref),
));
}
}
@ -667,7 +661,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}
ty::FnDef(did, args) => {
let obligations = self.nominal_obligations_without_const(did, args);
let obligations = self.nominal_obligations(did, args);
self.out.extend(obligations);
}
@ -822,11 +816,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}
#[instrument(level = "debug", skip(self))]
fn nominal_obligations_inner(
fn nominal_obligations(
&mut self,
def_id: DefId,
args: GenericArgsRef<'tcx>,
remap_constness: bool,
) -> Vec<traits::PredicateObligation<'tcx>> {
let predicates = self.tcx().predicates_of(def_id);
let mut origins = vec![def_id; predicates.predicates.len()];
@ -841,16 +834,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
debug_assert_eq!(predicates.predicates.len(), origins.len());
iter::zip(predicates, origins.into_iter().rev())
.map(|((mut pred, span), origin_def_id)| {
.map(|((pred, span), origin_def_id)| {
let code = if span.is_dummy() {
traits::ItemObligation(origin_def_id)
} else {
traits::BindingObligation(origin_def_id, span)
};
let cause = self.cause(code);
if remap_constness {
pred = pred.without_const(self.tcx());
}
traits::Obligation::with_depth(
self.tcx(),
cause,
@ -863,22 +853,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
.collect()
}
fn nominal_obligations(
&mut self,
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
self.nominal_obligations_inner(def_id, args, false)
}
fn nominal_obligations_without_const(
&mut self,
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
self.nominal_obligations_inner(def_id, args, true)
}
fn from_object_ty(
&mut self,
ty: Ty<'tcx>,