Skip to content

Explicitly don't normalize param-env in new solver #122403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
@@ -221,7 +221,10 @@ fn compare_method_predicate_entailment<'tcx>(
// The key step here is to update the caller_bounds's predicates to be
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
let param_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)),
Reveal::UserFacing,
);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);

let infcx = &tcx.infer_ctxt().build();
@@ -485,7 +488,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
.into_iter()
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
.map(|(clause, _)| clause);
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
let param_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds)),
Reveal::UserFacing,
);
let param_env = traits::normalize_param_env_or_error(
tcx,
param_env,
@@ -1776,7 +1782,10 @@ fn compare_const_predicate_entailment<'tcx>(
.map(|(predicate, _)| predicate),
);

let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
let param_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)),
Reveal::UserFacing,
);
let param_env = traits::normalize_param_env_or_error(
tcx,
param_env,
@@ -1915,7 +1924,10 @@ fn compare_type_predicate_entailment<'tcx>(

let impl_ty_span = tcx.def_span(impl_ty_def_id);
let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
let param_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(util::elaborate(tcx, hybrid_preds.predicates)),
Reveal::UserFacing,
);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
@@ -2224,7 +2236,7 @@ fn param_env_with_gat_bounds<'tcx>(
};
}

ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), Reveal::UserFacing)
}

fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
Original file line number Diff line number Diff line change
@@ -123,7 +123,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
.into_iter()
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args))
.map(|(clause, _)| clause);
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
let param_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(elaborate(tcx, hybrid_preds)),
Reveal::UserFacing,
);
let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy());

let ref infcx = tcx.infer_ctxt().build();
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -605,9 +605,8 @@ fn augment_param_env<'tcx>(
let bounds = tcx.mk_clauses_from_iter(
param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
);
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
// i.e. traits::normalize_param_env_or_error
ty::ParamEnv::new(bounds, param_env.reveal())

ty::ParamEnv::from_elaborated_clauses(bounds, param_env.reveal())
}

/// We use the following trait as an example throughout this function.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
@@ -323,7 +323,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> {
fn decode(d: &mut D) -> Self {
let caller_bounds = Decodable::decode(d);
let reveal = Decodable::decode(d);
ty::ParamEnv::new(caller_bounds, reveal)
ty::ParamEnv::from_elaborated_clauses(caller_bounds, reveal)
}
}

14 changes: 10 additions & 4 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -1037,7 +1037,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(ParamEnv::new(
Ok(ParamEnv::from_elaborated_clauses(
self.caller_bounds().try_fold_with(folder)?,
self.reveal().try_fold_with(folder)?,
))
@@ -1076,7 +1076,7 @@ impl<'tcx> ParamEnv<'tcx> {
/// are revealed. This is suitable for monomorphized, post-typeck
/// environments like codegen or doing optimizations.
///
/// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
/// N.B., if you want to have predicates in scope, use `ParamEnv::from_elaborated_clauses`,
/// or invoke `param_env.with_reveal_all()`.
#[inline]
pub fn reveal_all() -> Self {
@@ -1085,7 +1085,10 @@ impl<'tcx> ParamEnv<'tcx> {

/// Construct a trait environment with the given set of predicates.
#[inline]
pub fn new(caller_bounds: &'tcx List<Clause<'tcx>>, reveal: Reveal) -> Self {
pub fn from_elaborated_clauses(
caller_bounds: &'tcx List<Clause<'tcx>>,
reveal: Reveal,
) -> Self {
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
}

@@ -1108,7 +1111,10 @@ impl<'tcx> ParamEnv<'tcx> {
return self;
}

ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
ParamEnv::from_elaborated_clauses(
tcx.reveal_opaque_types_in_bounds(self.caller_bounds()),
Reveal::All,
)
}

/// Returns this same environment but with no caller bounds.
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
@@ -340,13 +340,13 @@ impl<'tcx> AutoTraitFinder<'tcx> {

let normalized_preds =
elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
new_env = ty::ParamEnv::new(
new_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
param_env.reveal(),
);
}

let final_user_env = ty::ParamEnv::new(
let final_user_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
user_env.reveal(),
);
30 changes: 18 additions & 12 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -207,6 +207,10 @@ pub fn normalize_param_env_or_error<'tcx>(
unnormalized_env: ty::ParamEnv<'tcx>,
cause: ObligationCause<'tcx>,
) -> ty::ParamEnv<'tcx> {
if tcx.next_trait_solver_globally() {
return unnormalized_env;
}

// I'm not wild about reporting errors here; I'd prefer to
// have the errors get reported at a defined place (e.g.,
// during typeck). Instead I have all parameter
@@ -221,9 +225,10 @@ pub fn normalize_param_env_or_error<'tcx>(
// parameter environments once for every fn as it goes,
// and errors will get reported then; so outside of type inference we
// can be sure that no errors should occur.
let mut predicates: Vec<_> = util::elaborate(
tcx,
unnormalized_env.caller_bounds().into_iter().map(|predicate| {
let mut predicates: Vec<_> = unnormalized_env
.caller_bounds()
.into_iter()
.map(|predicate| {
if tcx.features().generic_const_exprs {
return predicate;
}
@@ -280,13 +285,14 @@ pub fn normalize_param_env_or_error<'tcx>(
//
// FIXME(-Znext-solver): remove this hack since we have deferred projection equality
predicate.fold_with(&mut ConstNormalizer(tcx))
}),
)
.collect();
})
.collect();

debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);

let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
let reveal = unnormalized_env.reveal();
let eager_evaluated_env =
ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), 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
@@ -317,11 +323,11 @@ pub fn normalize_param_env_or_error<'tcx>(
predicates, outlives_predicates
);
let Ok(non_outlives_predicates) =
do_normalize_predicates(tcx, cause.clone(), elaborated_env, predicates)
do_normalize_predicates(tcx, cause.clone(), eager_evaluated_env, predicates)
else {
// An unnormalized env is better than nothing.
debug!("normalize_param_env_or_error: errored resolving non-outlives predicates");
return elaborated_env;
return eager_evaluated_env;
};

debug!("normalize_param_env_or_error: non-outlives predicates={:?}", non_outlives_predicates);
@@ -331,20 +337,20 @@ pub fn normalize_param_env_or_error<'tcx>(
// 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());
ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses_from_iter(outlives_env), reveal);
let Ok(outlives_predicates) =
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
else {
// An unnormalized env is better than nothing.
debug!("normalize_param_env_or_error: errored resolving outlives predicates");
return elaborated_env;
return eager_evaluated_env;
};
debug!("normalize_param_env_or_error: outlives predicates={:?}", outlives_predicates);

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())
ty::ParamEnv::from_elaborated_clauses(tcx.mk_clauses(&predicates), reveal)
}

/// Normalize a type and process all resulting obligations, returning any errors.
5 changes: 4 additions & 1 deletion compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
@@ -767,7 +767,10 @@ 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())
ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(caller_bounds),
param_env.reveal(),
)
};

// Receiver: DispatchFromDyn<Receiver[Self => U]>
6 changes: 4 additions & 2 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -146,8 +146,10 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {

let local_did = def_id.as_local();

let unnormalized_env =
ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing);
let unnormalized_env = ty::ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(traits::elaborate(tcx, predicates)),
traits::Reveal::UserFacing,
);

let body_id = local_did.unwrap_or(CRATE_DEF_ID);
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/derive.rs
Original file line number Diff line number Diff line change
@@ -497,7 +497,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
}
}

ParamEnv::new(
ParamEnv::from_elaborated_clauses(
tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
ClauseKind::Trait(TraitPredicate {