Skip to content

Commit ec28f47

Browse files
committed
Auto merge of rust-lang#120463 - lcnr:eager-inference-replacement, r=jackh726,compiler-errors
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 rust-lang#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 80deabd + 2ccd78d commit ec28f47

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
@@ -119,60 +119,16 @@ pub fn predicates_for_generics<'tcx>(
119119

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

178134
#[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)