1
Fork 0

Auto merge of #114134 - fee1-dead-contrib:rm-constness-from-param-env, r=oli-obk

Remove `constness` from `ParamEnv`

This should be replaced by keyword generics/effects. cc #110395

r? `@oli-obk`
This commit is contained in:
bors 2023-07-28 08:53:12 +00:00
commit aafd75a9c5
102 changed files with 423 additions and 1061 deletions

View file

@ -449,14 +449,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution);
}
if !goal.param_env.is_const() {
// `Destruct` is automatically implemented for every type in
// non-const environments.
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} else {
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
Err(NoSolution)
}
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
// `Destruct` is automatically implemented for every type in
// non-const environments.
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
fn consider_builtin_transmute_candidate(

View file

@ -347,14 +347,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
new_env = ty::ParamEnv::new(
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
param_env.reveal(),
param_env.constness(),
);
}
let final_user_env = ty::ParamEnv::new(
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
user_env.reveal(),
user_env.constness(),
);
debug!(
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \

View file

@ -687,9 +687,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
trait_predicate.remap_constness_diag(obligation.param_env);
let predicate_is_const = ty::BoundConstness::ConstIfConst
== trait_predicate.skip_binder().constness;
@ -3108,11 +3107,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
span: Span,
) -> UnsatisfiedConst {
let mut unsatisfied_const = UnsatisfiedConst(false);
if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
if trait_predicate.is_const_if_const() {
let non_const_predicate = trait_ref.without_const();
let non_const_obligation = Obligation {
cause: obligation.cause.clone(),
param_env: obligation.param_env.without_const(),
param_env: obligation.param_env,
predicate: non_const_predicate.to_predicate(self.tcx),
recursion_depth: obligation.recursion_depth,
};

View file

@ -3136,7 +3136,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ObligationCauseCode::ImplDerivedObligation(ref data) => {
let mut parent_trait_pred =
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
parent_trait_pred.remap_constness_diag(param_env);
let parent_def_id = parent_trait_pred.def_id();
let (self_ty, file) =
self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());

View file

@ -328,11 +328,7 @@ pub fn normalize_param_env_or_error<'tcx>(
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
let elaborated_env = ty::ParamEnv::new(
tcx.mk_clauses(&predicates),
unnormalized_env.reveal(),
unnormalized_env.constness(),
);
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
// normalization expects its param-env to be already normalized, which means we have
@ -376,11 +372,8 @@ pub fn normalize_param_env_or_error<'tcx>(
// here. I believe they should not matter, because we are ignoring TypeOutlives param-env
// predicates here anyway. Keeping them here anyway because it seems safer.
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
let outlives_env = ty::ParamEnv::new(
tcx.mk_clauses_from_iter(outlives_env),
unnormalized_env.reveal(),
unnormalized_env.constness(),
);
let outlives_env =
ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal());
let Ok(outlives_predicates) =
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
else {
@ -393,11 +386,7 @@ pub fn normalize_param_env_or_error<'tcx>(
let mut predicates = non_outlives_predicates;
predicates.extend(outlives_predicates);
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
ty::ParamEnv::new(
tcx.mk_clauses(&predicates),
unnormalized_env.reveal(),
unnormalized_env.constness(),
)
ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
}
/// Normalize a type and process all resulting obligations, returning any errors.

View file

@ -761,11 +761,7 @@ fn receiver_is_dispatchable<'tcx>(
let caller_bounds =
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
ty::ParamEnv::new(
tcx.mk_clauses_from_iter(caller_bounds),
param_env.reveal(),
param_env.constness(),
)
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal())
};
// Receiver: DispatchFromDyn<Receiver[Self => U]>

View file

@ -1,5 +1,4 @@
use rustc_infer::traits::{TraitEngine, TraitEngineExt};
use rustc_middle::ty;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::InferCtxt;
@ -66,17 +65,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
) -> Result<EvaluationResult, OverflowError> {
let mut _orig_values = OriginalQueryValues::default();
let param_env = match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
// we ignore the value set to it.
let mut _constness = pred.constness;
obligation
.param_env
.with_constness(_constness.and(obligation.param_env.constness()))
}
// constness has no effect on the given predicate.
_ => obligation.param_env.without_const(),
};
let param_env = obligation.param_env;
if self.next_trait_solver() {
self.probe(|snapshot| {

View file

@ -82,7 +82,6 @@ fn relate_mir_and_user_args<'tcx>(
def_id: DefId,
user_args: UserArgs<'tcx>,
) -> Result<(), NoSolution> {
let param_env = param_env.without_const();
let UserArgs { user_self_ty, args } = user_args;
let tcx = ocx.infcx.tcx;
let cause = ObligationCause::dummy_with_span(span);

View file

@ -839,7 +839,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) {
// If the predicate is `~const Destruct` in a non-const environment, we don't actually need
// to check anything. We'll short-circuit checking any obligations in confirmation, too.
if !obligation.is_const() {
// FIXME(effects)
if true {
candidates.vec.push(ConstDestructCandidate(None));
return;
}

View file

@ -13,8 +13,8 @@ use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{BuiltinImplSource, SelectionOutputTypeParameterMismatch};
use rustc_middle::ty::{
self, Binder, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt,
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
TraitPredicate, Ty, TyCtxt, TypeVisitableExt,
};
use rustc_span::def_id::DefId;
@ -647,7 +647,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_fn_pointer_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
is_const: bool,
// FIXME(effects)
_is_const: bool,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
debug!(?obligation, "confirm_fn_pointer_candidate");
@ -674,16 +675,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
let cause = obligation.derived_cause(BuiltinDerivedObligation);
if obligation.is_const() && !is_const {
// function is a trait method
if let ty::FnDef(def_id, args) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
let trait_ref = TraitRef::from_method(tcx, trait_id, *args);
let poly_trait_pred = Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred);
nested.push(obligation);
}
}
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
let output_ty = normalize_with_depth_to(
@ -1211,7 +1202,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
impl_def_id: Option<DefId>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
if !obligation.is_const() {
// FIXME(effects)
if true {
return Ok(vec![]);
}

View file

@ -1000,13 +1000,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
let stack = self.push_stack(previous_stack, &obligation);
let mut fresh_trait_pred = stack.fresh_trait_pred;
let mut param_env = obligation.param_env;
fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| {
pred.remap_constness(&mut param_env);
pred
});
let fresh_trait_pred = stack.fresh_trait_pred;
let param_env = obligation.param_env;
debug!(?fresh_trait_pred);
@ -1386,8 +1381,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
(result, dep_node)
}
/// filter_impls filters constant trait obligations and candidates that have a positive impl
/// for a negative goal and a negative impl for a positive goal
/// filter_impls filters candidates that have a positive impl for a negative
/// goal and a negative impl for a positive goal
#[instrument(level = "debug", skip(self, candidates))]
fn filter_impls(
&mut self,
@ -1399,42 +1394,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut result = Vec::with_capacity(candidates.len());
for candidate in candidates {
// Respect const trait obligations
if obligation.is_const() {
match candidate {
// const impl
ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
// const param
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
// const projection
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
// auto trait impl
| AutoImplCandidate
// generator / future, this will raise error in other places
// or ignore error with const_async_blocks feature
| GeneratorCandidate
| FutureCandidate
// FnDef where the function is const
| FnPointerCandidate { is_const: true }
| ConstDestructCandidate(_)
| ClosureCandidate { is_const: true } => {}
FnPointerCandidate { is_const: false } => {
if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
// Trait methods are not seen as const unless the trait is implemented as const.
// We do not filter that out in here, but nested obligations will be needed to confirm this.
} else {
continue
}
}
_ => {
// reject all other types of candidates
continue;
}
}
}
if let ImplCandidate(def_id) = candidate {
if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
|| obligation.polarity() == tcx.impl_polarity(def_id)
@ -1528,7 +1487,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn check_candidate_cache(
&mut self,
mut param_env: ty::ParamEnv<'tcx>,
param_env: ty::ParamEnv<'tcx>,
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
// Neither the global nor local cache is aware of intercrate
@ -1539,8 +1498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return None;
}
let tcx = self.tcx();
let mut pred = cache_fresh_trait_pred.skip_binder();
pred.remap_constness(&mut param_env);
let pred = cache_fresh_trait_pred.skip_binder();
if self.can_use_global_caches(param_env) {
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
@ -1586,15 +1544,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
#[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")]
fn insert_candidate_cache(
&mut self,
mut param_env: ty::ParamEnv<'tcx>,
param_env: ty::ParamEnv<'tcx>,
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
dep_node: DepNodeIndex,
candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
) {
let tcx = self.tcx();
let mut pred = cache_fresh_trait_pred.skip_binder();
pred.remap_constness(&mut param_env);
let pred = cache_fresh_trait_pred.skip_binder();
if !self.can_cache_candidate(&candidate) {
debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");