1
Fork 0

Auto merge of #133242 - lcnr:questionable-uwu, r=compiler-errors,BoxyUwU

finish `Reveal` removal

After #133212 changed the `TypingMode` to be the only source of truth, this entirely rips out `Reveal`.

cc #132279

r? `@compiler-errors`
This commit is contained in:
bors 2024-11-23 18:01:21 +00:00
commit 386a7c7ae2
82 changed files with 344 additions and 529 deletions

View file

@ -204,7 +204,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
// and the obligation is monomorphic, otherwise passes such as
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
match self.typing_mode_unchecked() {
match self.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { .. } => false,
TypingMode::PostAnalysis => {
let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref);

View file

@ -318,13 +318,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
new_env = ty::ParamEnv::new(
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
param_env.reveal(),
);
}
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(),
);
debug!(
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \

View file

@ -707,7 +707,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())
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds))
};
// Receiver: DispatchFromDyn<Receiver[Self => U]>

View file

@ -20,7 +20,7 @@ pub fn evaluate_host_effect_obligation<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
if matches!(selcx.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) {
if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) {
span_bug!(
obligation.cause.span,
"should not select host obligation in old solver in intercrate mode"

View file

@ -771,8 +771,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
stalled_on: &mut Vec<TyOrConstInferVar>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let infcx = self.selcx.infcx;
if obligation.predicate.is_global()
&& !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
{
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.
@ -827,8 +826,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let tcx = self.selcx.tcx();
let infcx = self.selcx.infcx;
if obligation.predicate.is_global()
&& !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
{
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.

View file

@ -423,7 +423,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());
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates));
if !elaborated_env.has_aliases() {
return elaborated_env;
}
@ -470,8 +470,7 @@ 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());
let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env));
let Ok(outlives_predicates) =
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
else {
@ -484,7 +483,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())
ty::ParamEnv::new(tcx.mk_clauses(&predicates))
}
#[derive(Debug)]
@ -604,15 +603,15 @@ pub fn try_evaluate_const<'tcx>(
};
let uv = ty::UnevaluatedConst::new(uv.def, args);
// It's not *technically* correct to be revealing opaque types here as we could still be
// before borrowchecking. However, CTFE itself uses `Reveal::All` unconditionally even during
// typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a result we
// always use a revealed env when resolving the instance to evaluate.
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
// during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
// As a result we always use a revealed env when resolving the instance to evaluate.
//
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
// instead of having this logic here
let typing_env =
tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx);
tcx.erase_regions(infcx.typing_env(param_env)).with_post_analysis_normalized(tcx);
let erased_uv = tcx.erase_regions(uv);
use rustc_middle::mir::interpret::ErrorHandled;

View file

@ -111,14 +111,13 @@ where
pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
infcx: &InferCtxt<'tcx>,
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
value: &T,
) -> bool {
let mut flags = ty::TypeFlags::HAS_ALIAS;
// Opaques are treated as rigid with `Reveal::UserFacing`,
// Opaques are treated as rigid outside of `TypingMode::PostAnalysis`,
// so we can ignore those.
match infcx.typing_mode(param_env_for_debug_assertion) {
match infcx.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
}
@ -158,11 +157,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
"Normalizing {value:?} without wrapping in a `Binder`"
);
if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
value
} else {
value.fold_with(self)
}
if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) }
}
}
@ -182,7 +177,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
if !needs_normalization(self.selcx.infcx, &ty) {
return ty;
}
@ -217,7 +212,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
match kind {
ty::Opaque => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.selcx.infcx.typing_mode(self.param_env) {
match self.selcx.infcx.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
ty.super_fold_with(self)
}
@ -407,8 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
#[instrument(skip(self), level = "debug")]
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
let tcx = self.selcx.tcx();
if tcx.features().generic_const_exprs()
|| !needs_normalization(self.selcx.infcx, self.param_env, &constant)
if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant)
{
constant
} else {
@ -426,7 +420,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
#[inline]
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) {
p.super_fold_with(self)
} else {
p

View file

@ -10,7 +10,6 @@ use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
pub use rustc_middle::traits::Reveal;
use rustc_middle::traits::select::OverflowError;
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
@ -975,7 +974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// and the obligation is monomorphic, otherwise passes such as
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
match selcx.infcx.typing_mode(obligation.param_env) {
match selcx.infcx.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { .. } => {
debug!(
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),

View file

@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}
}
if !needs_normalization(self.infcx, self.param_env, &value) {
if !needs_normalization(self.infcx, &value) {
return Ok(Normalized { value, obligations: PredicateObligations::new() });
}
@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
if !needs_normalization(self.infcx, self.param_env, &ty) {
if !needs_normalization(self.infcx, &ty) {
return Ok(ty);
}
@ -215,7 +215,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
let res = match kind {
ty::Opaque => {
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.infcx.typing_mode(self.param_env) {
match self.infcx.typing_mode() {
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
ty.try_super_fold_with(self)?
}
@ -334,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
&mut self,
constant: ty::Const<'tcx>,
) -> Result<ty::Const<'tcx>, Self::Error> {
if !needs_normalization(self.infcx, self.param_env, &constant) {
if !needs_normalization(self.infcx, &constant) {
return Ok(constant);
}
@ -353,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
&mut self,
p: ty::Predicate<'tcx>,
) -> Result<ty::Predicate<'tcx>, Self::Error> {
if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
if p.allow_normalization() && needs_normalization(self.infcx, &p) {
p.try_super_fold_with(self)
} else {
Ok(p)

View file

@ -760,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
//
// Note that this is only sound as projection candidates of opaque types
// are always applicable for auto traits.
} else if let TypingMode::Coherence =
self.infcx.typing_mode(obligation.param_env)
{
} else if let TypingMode::Coherence = self.infcx.typing_mode() {
// We do not emit auto trait candidates for opaque types in coherence.
// Doing so can result in weird dependency cycles.
candidates.ambiguous = true;
@ -905,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
//
// FIXME(@lcnr): This should probably only trigger during analysis,
// disabling candidates during codegen is also questionable.
if let TypingMode::Coherence = self.infcx.typing_mode(param_env) {
if let TypingMode::Coherence = self.infcx.typing_mode() {
return None;
}

View file

@ -222,7 +222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// Enables tracking of intercrate ambiguity causes. See
/// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
assert!(self.intercrate_ambiguity_causes.is_none());
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
@ -234,7 +234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn take_intercrate_ambiguity_causes(
&mut self,
) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>> {
assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
self.intercrate_ambiguity_causes.take().unwrap_or_default()
}
@ -1027,7 +1027,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
previous_stack: TraitObligationStackList<'o, 'tcx>,
mut obligation: PolyTraitObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
if !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
if !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
&& obligation.is_global()
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param())
{
@ -1310,13 +1310,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> Option<EvaluationResult> {
let tcx = self.tcx();
let infcx = self.infcx;
let tcx = infcx.tcx;
if self.can_use_global_caches(param_env, trait_pred) {
if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
return Some(res);
let key = (infcx.typing_env(param_env), trait_pred);
if let Some(res) = tcx.evaluation_cache.get(&key, tcx) {
Some(res)
} else {
debug_assert_eq!(infcx.evaluation_cache.get(&(param_env, trait_pred), tcx), None);
None
}
} else {
self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
}
self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
}
fn insert_evaluation_cache(
@ -1332,18 +1338,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return;
}
if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() {
let infcx = self.infcx;
let tcx = infcx.tcx;
if self.can_use_global_caches(param_env, trait_pred) {
debug!(?trait_pred, ?result, "insert_evaluation_cache global");
// This may overwrite the cache with the same value
// FIXME: Due to #50507 this overwrites the different values
// This should be changed to use HashMapExt::insert_same
// when that is fixed
self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
tcx.evaluation_cache.insert(
(infcx.typing_env(param_env), trait_pred),
dep_node,
result,
);
return;
} else {
debug!(?trait_pred, ?result, "insert_evaluation_cache local");
self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
}
debug!(?trait_pred, ?result, "insert_evaluation_cache");
self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
}
fn check_recursion_depth<T>(
@ -1459,7 +1468,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
let obligation = &stack.obligation;
match self.infcx.typing_mode(obligation.param_env) {
match self.infcx.typing_mode() {
TypingMode::Coherence => {}
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Ok(()),
}
@ -1485,11 +1494,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If there are any inference variables in the `ParamEnv`, then we
// always use a cache local to this particular scope. Otherwise, we
// switch to a global cache.
if param_env.has_infer() {
if param_env.has_infer() || pred.has_infer() {
return false;
}
match self.infcx.typing_mode(param_env) {
match self.infcx.typing_mode() {
// Avoid using the global cache during coherence and just rely
// on the local cache. It is really just a simplification to
// avoid us having to fear that coherence results "pollute"
@ -1522,15 +1531,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
let tcx = self.tcx();
let infcx = self.infcx;
let tcx = infcx.tcx;
let pred = cache_fresh_trait_pred.skip_binder();
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
return Some(res);
if let Some(res) = tcx.selection_cache.get(&(infcx.typing_env(param_env), pred), tcx) {
Some(res)
} else {
debug_assert_eq!(infcx.selection_cache.get(&(param_env, pred), tcx), None);
None
}
} else {
infcx.selection_cache.get(&(param_env, pred), tcx)
}
self.infcx.selection_cache.get(&(param_env, pred), tcx)
}
/// Determines whether can we safely cache the result
@ -1567,7 +1581,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
dep_node: DepNodeIndex,
candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
) {
let tcx = self.tcx();
let infcx = self.infcx;
let tcx = infcx.tcx;
let pred = cache_fresh_trait_pred.skip_binder();
if !self.can_cache_candidate(&candidate) {
@ -1578,10 +1593,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if self.can_use_global_caches(param_env, cache_fresh_trait_pred) {
if let Err(Overflow(OverflowError::Canonical)) = candidate {
// Don't cache overflow globally; we only produce this in certain modes.
} else if !pred.has_infer() && !candidate.has_infer() {
} else {
debug!(?pred, ?candidate, "insert_candidate_cache global");
debug_assert!(!candidate.has_infer());
// This may overwrite the cache with the same value.
tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
tcx.selection_cache.insert(
(infcx.typing_env(param_env), pred),
dep_node,
candidate,
);
return;
}
}
@ -2518,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested_obligations.extend(obligations);
if impl_trait_header.polarity == ty::ImplPolarity::Reservation
&& !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
{
debug!("reservation impls only apply in intercrate mode");
return Err(());