Skip to content

Commit 1e74e30

Browse files
committed
Auto merge of #120463 - lcnr:eager-inference-replacement, r=<try>
some trait system cleanups Always eagerly replace projections with infer vars if normalization is ambig. Unsure why we previously didn't do so, wasn't able to find an explanation in #90887. This adds some complexity to the trait system and is afaict unnecessary. The second commit simplifies `pred_known_to_hold_modulo_regions`, afaict the optional `fulfill` isn't necessary anymore. r? types cc `@jackh726`
2 parents fb4bca0 + 2b3867b commit 1e74e30

File tree

4 files changed

+14
-129
lines changed

4 files changed

+14
-129
lines changed

compiler/rustc_trait_selection/src/traits/fulfill.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
312312

313313
if obligation.predicate.has_projections() {
314314
let mut obligations = Vec::new();
315-
let predicate = crate::traits::project::try_normalize_with_depth_to(
315+
let predicate = crate::traits::project::normalize_with_depth_to(
316316
&mut self.selcx,
317317
obligation.param_env,
318318
obligation.cause.clone(),

compiler/rustc_trait_selection/src/traits/mod.rs

+3-47
Original file line numberDiff line numberDiff line change
@@ -118,60 +118,16 @@ pub fn predicates_for_generics<'tcx>(
118118

119119
/// Determines whether the type `ty` is known to meet `bound` and
120120
/// returns true if so. Returns false if `ty` either does not meet
121-
/// `bound` or is not known to meet bound (note that this is
122-
/// conservative towards *no impl*, which is the opposite of the
123-
/// `evaluate` methods).
121+
/// `bound` or is not known to meet bound.
124122
pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
125123
infcx: &InferCtxt<'tcx>,
126124
param_env: ty::ParamEnv<'tcx>,
127125
ty: Ty<'tcx>,
128126
def_id: DefId,
129127
) -> bool {
130128
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
131-
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
132-
}
133-
134-
/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?
135-
///
136-
/// Ping me on zulip if you want to use this method and need help with finding
137-
/// an appropriate replacement.
138-
#[instrument(level = "debug", skip(infcx, param_env, pred), ret)]
139-
fn pred_known_to_hold_modulo_regions<'tcx>(
140-
infcx: &InferCtxt<'tcx>,
141-
param_env: ty::ParamEnv<'tcx>,
142-
pred: impl ToPredicate<'tcx>,
143-
) -> bool {
144-
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, pred);
145-
146-
let result = infcx.evaluate_obligation_no_overflow(&obligation);
147-
debug!(?result);
148-
149-
if result.must_apply_modulo_regions() {
150-
true
151-
} else if result.may_apply() {
152-
// Sometimes obligations are ambiguous because the recursive evaluator
153-
// is not smart enough, so we fall back to fulfillment when we're not certain
154-
// that an obligation holds or not. Even still, we must make sure that
155-
// the we do no inference in the process of checking this obligation.
156-
let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
157-
infcx.probe(|_| {
158-
let ocx = ObligationCtxt::new(infcx);
159-
ocx.register_obligation(obligation);
160-
161-
let errors = ocx.select_all_or_error();
162-
match errors.as_slice() {
163-
// Only known to hold if we did no inference.
164-
[] => infcx.shallow_resolve(goal) == goal,
165-
166-
errors => {
167-
debug!(?errors);
168-
false
169-
}
170-
}
171-
})
172-
} else {
173-
false
174-
}
129+
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, trait_ref);
130+
infcx.predicate_must_hold_modulo_regions(&obligation)
175131
}
176132

177133
#[instrument(level = "debug", skip(tcx, elaborated_env))]

compiler/rustc_trait_selection/src/traits/project.rs

+9-79
Original file line numberDiff line numberDiff line change
@@ -383,32 +383,6 @@ where
383383
result
384384
}
385385

386-
#[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
387-
pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>(
388-
selcx: &'a mut SelectionContext<'b, 'tcx>,
389-
param_env: ty::ParamEnv<'tcx>,
390-
cause: ObligationCause<'tcx>,
391-
depth: usize,
392-
value: T,
393-
obligations: &mut Vec<PredicateObligation<'tcx>>,
394-
) -> T
395-
where
396-
T: TypeFoldable<TyCtxt<'tcx>>,
397-
{
398-
debug!(obligations.len = obligations.len());
399-
let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement(
400-
selcx,
401-
param_env,
402-
cause,
403-
depth,
404-
obligations,
405-
);
406-
let result = ensure_sufficient_stack(|| normalizer.fold(value));
407-
debug!(?result, obligations.len = normalizer.obligations.len());
408-
debug!(?normalizer.obligations,);
409-
result
410-
}
411-
412386
pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
413387
value: &T,
414388
reveal: Reveal,
@@ -435,10 +409,6 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> {
435409
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
436410
depth: usize,
437411
universes: Vec<Option<ty::UniverseIndex>>,
438-
/// If true, when a projection is unable to be completed, an inference
439-
/// variable will be created and an obligation registered to project to that
440-
/// inference variable. Also, constants will be eagerly evaluated.
441-
eager_inference_replacement: bool,
442412
}
443413

444414
impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
@@ -450,33 +420,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
450420
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
451421
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
452422
debug_assert!(!selcx.infcx.next_trait_solver());
453-
AssocTypeNormalizer {
454-
selcx,
455-
param_env,
456-
cause,
457-
obligations,
458-
depth,
459-
universes: vec![],
460-
eager_inference_replacement: true,
461-
}
462-
}
463-
464-
fn new_without_eager_inference_replacement(
465-
selcx: &'a mut SelectionContext<'b, 'tcx>,
466-
param_env: ty::ParamEnv<'tcx>,
467-
cause: ObligationCause<'tcx>,
468-
depth: usize,
469-
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
470-
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
471-
AssocTypeNormalizer {
472-
selcx,
473-
param_env,
474-
cause,
475-
obligations,
476-
depth,
477-
universes: vec![],
478-
eager_inference_replacement: false,
479-
}
423+
AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] }
480424
}
481425

482426
fn fold<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
@@ -579,28 +523,14 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
579523
// register an obligation to *later* project, since we know
580524
// there won't be bound vars there.
581525
let data = data.fold_with(self);
582-
let normalized_ty = if self.eager_inference_replacement {
583-
normalize_projection_type(
584-
self.selcx,
585-
self.param_env,
586-
data,
587-
self.cause.clone(),
588-
self.depth,
589-
self.obligations,
590-
)
591-
} else {
592-
opt_normalize_projection_type(
593-
self.selcx,
594-
self.param_env,
595-
data,
596-
self.cause.clone(),
597-
self.depth,
598-
self.obligations,
599-
)
600-
.ok()
601-
.flatten()
602-
.unwrap_or_else(|| ty.super_fold_with(self).into())
603-
};
526+
let normalized_ty = normalize_projection_type(
527+
self.selcx,
528+
self.param_env,
529+
data,
530+
self.cause.clone(),
531+
self.depth,
532+
self.obligations,
533+
);
604534
debug!(
605535
?self.depth,
606536
?ty,

compiler/rustc_trait_selection/src/traits/select/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use super::{
2222
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
2323
use crate::solve::InferCtxtSelectExt;
2424
use crate::traits::error_reporting::TypeErrCtxtExt;
25-
use crate::traits::project::try_normalize_with_depth_to;
2625
use crate::traits::project::ProjectAndUnifyResult;
2726
use crate::traits::project::ProjectionCacheKeyExt;
2827
use crate::traits::ProjectionCacheKey;
@@ -1069,7 +1068,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10691068
&& fresh_trait_pred.is_global()
10701069
{
10711070
let mut nested_obligations = Vec::new();
1072-
let predicate = try_normalize_with_depth_to(
1071+
let predicate = normalize_with_depth_to(
10731072
this,
10741073
param_env,
10751074
obligation.cause.clone(),

0 commit comments

Comments
 (0)