Skip to content

Commit b9ec8c2

Browse files
authored
Rollup merge of rust-lang#140468 - BoxyUwU:normalization_confusings2, r=lcnr
Minor tweaks to make some normalization (adjacent) code less confusing r? lcnr sorry for double ping lol
2 parents d575a3c + c31794d commit b9ec8c2

File tree

4 files changed

+56
-52
lines changed

4 files changed

+56
-52
lines changed

compiler/rustc_hir_typeck/src/writeback.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
// Type resolution: the phase that finds all the types in the AST with
2-
// unresolved type variables and replaces "ty_var" types with their
3-
// generic parameters.
1+
//! During type inference, partially inferred terms are
2+
//! represented using inference variables (ty::Infer). These don't appear in
3+
//! the final [`ty::TypeckResults`] since all of the types should have been
4+
//! inferred once typeck is done.
5+
//!
6+
//! When type inference is running however, having to update the typeck results
7+
//! every time a new type is inferred would be unreasonably slow, so instead all
8+
//! of the replacement happens at the end in [`FnCtxt::resolve_type_vars_in_body`],
9+
//! which creates a new `TypeckResults` which doesn't contain any inference variables.
410
511
use std::mem;
612

@@ -27,15 +33,6 @@ use crate::FnCtxt;
2733
///////////////////////////////////////////////////////////////////////////
2834
// Entry point
2935

30-
// During type inference, partially inferred types are
31-
// represented using Type variables (ty::Infer). These don't appear in
32-
// the final TypeckResults since all of the types should have been
33-
// inferred once typeck is done.
34-
// When type inference is running however, having to update the typeck
35-
// typeck results every time a new type is inferred would be unreasonably slow,
36-
// so instead all of the replacement happens at the end in
37-
// resolve_type_vars_in_body, which creates a new TypeTables which
38-
// doesn't contain any inference types.
3936
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4037
pub(crate) fn resolve_type_vars_in_body(
4138
&self,
@@ -90,14 +87,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9087
}
9188
}
9289

93-
///////////////////////////////////////////////////////////////////////////
94-
// The Writeback context. This visitor walks the HIR, checking the
95-
// fn-specific typeck results to find references to types or regions. It
96-
// resolves those regions to remove inference variables and writes the
97-
// final result back into the master typeck results in the tcx. Here and
98-
// there, it applies a few ad-hoc checks that were not convenient to
99-
// do elsewhere.
100-
90+
/// The Writeback context. This visitor walks the HIR, checking the
91+
/// fn-specific typeck results to find inference variables. It resolves
92+
/// those inference variables and writes the final result into the
93+
/// `TypeckResults`. It also applies a few ad-hoc checks that were not
94+
/// convenient to do elsewhere.
10195
struct WritebackCx<'cx, 'tcx> {
10296
fcx: &'cx FnCtxt<'cx, 'tcx>,
10397

@@ -897,7 +891,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
897891
let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
898892
let at = self.fcx.at(&cause, self.fcx.param_env);
899893
let universes = vec![None; outer_exclusive_binder(value).as_usize()];
900-
match solve::deeply_normalize_with_skipped_universes_and_ambiguous_goals(
894+
match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
901895
at, value, universes,
902896
) {
903897
Ok((value, goals)) => {

compiler/rustc_trait_selection/src/solve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ pub use fulfill::{FulfillmentCtxt, NextSolverError};
1111
pub(crate) use normalize::deeply_normalize_for_diagnostics;
1212
pub use normalize::{
1313
deeply_normalize, deeply_normalize_with_skipped_universes,
14-
deeply_normalize_with_skipped_universes_and_ambiguous_goals,
14+
deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals,
1515
};
1616
pub use select::InferCtxtSelectExt;

compiler/rustc_trait_selection/src/solve/normalize.rs

+32-25
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ where
4545
T: TypeFoldable<TyCtxt<'tcx>>,
4646
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
4747
{
48-
let (value, goals) =
49-
deeply_normalize_with_skipped_universes_and_ambiguous_goals(at, value, universes)?;
50-
assert_eq!(goals, vec![]);
48+
let (value, coroutine_goals) =
49+
deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
50+
at, value, universes,
51+
)?;
52+
assert_eq!(coroutine_goals, vec![]);
5153

5254
Ok(value)
5355
}
@@ -59,9 +61,9 @@ where
5961
/// entered before passing `value` to the function. This is currently needed for
6062
/// `normalize_erasing_regions`, which skips binders as it walks through a type.
6163
///
62-
/// This returns a set of stalled obligations if the typing mode of the underlying infcx
63-
/// has any stalled coroutine def ids.
64-
pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals<'tcx, T, E>(
64+
/// This returns a set of stalled obligations involving coroutines if the typing mode of
65+
/// the underlying infcx has any stalled coroutine def ids.
66+
pub fn deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals<'tcx, T, E>(
6567
at: At<'_, 'tcx>,
6668
value: T,
6769
universes: Vec<Option<UniverseIndex>>,
@@ -71,19 +73,24 @@ where
7173
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
7274
{
7375
let fulfill_cx = FulfillmentCtxt::new(at.infcx);
74-
let mut folder =
75-
NormalizationFolder { at, fulfill_cx, depth: 0, universes, stalled_goals: vec![] };
76+
let mut folder = NormalizationFolder {
77+
at,
78+
fulfill_cx,
79+
depth: 0,
80+
universes,
81+
stalled_coroutine_goals: vec![],
82+
};
7683
let value = value.try_fold_with(&mut folder)?;
7784
let errors = folder.fulfill_cx.select_all_or_error(at.infcx);
78-
if errors.is_empty() { Ok((value, folder.stalled_goals)) } else { Err(errors) }
85+
if errors.is_empty() { Ok((value, folder.stalled_coroutine_goals)) } else { Err(errors) }
7986
}
8087

8188
struct NormalizationFolder<'me, 'tcx, E> {
8289
at: At<'me, 'tcx>,
8390
fulfill_cx: FulfillmentCtxt<'tcx, E>,
8491
depth: usize,
8592
universes: Vec<Option<UniverseIndex>>,
86-
stalled_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
93+
stalled_coroutine_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
8794
}
8895

8996
impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
@@ -182,7 +189,7 @@ where
182189
return Err(errors);
183190
}
184191

185-
self.stalled_goals.extend(
192+
self.stalled_coroutine_goals.extend(
186193
self.fulfill_cx
187194
.drain_stalled_obligations_for_coroutines(self.at.infcx)
188195
.into_iter()
@@ -298,13 +305,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
298305

299306
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
300307
let infcx = self.at.infcx;
301-
let result =
302-
infcx.commit_if_ok(|_| {
303-
deeply_normalize_with_skipped_universes_and_ambiguous_goals::<
304-
_,
305-
ScrubbedTraitError<'tcx>,
306-
>(self.at, ty, vec![None; ty.outer_exclusive_binder().as_usize()])
307-
});
308+
let result: Result<_, Vec<ScrubbedTraitError<'tcx>>> = infcx.commit_if_ok(|_| {
309+
deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
310+
self.at,
311+
ty,
312+
vec![None; ty.outer_exclusive_binder().as_usize()],
313+
)
314+
});
308315
match result {
309316
Ok((ty, _)) => ty,
310317
Err(_) => ty.super_fold_with(self),
@@ -313,13 +320,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
313320

314321
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
315322
let infcx = self.at.infcx;
316-
let result =
317-
infcx.commit_if_ok(|_| {
318-
deeply_normalize_with_skipped_universes_and_ambiguous_goals::<
319-
_,
320-
ScrubbedTraitError<'tcx>,
321-
>(self.at, ct, vec![None; ct.outer_exclusive_binder().as_usize()])
322-
});
323+
let result: Result<_, Vec<ScrubbedTraitError<'tcx>>> = infcx.commit_if_ok(|_| {
324+
deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
325+
self.at,
326+
ct,
327+
vec![None; ct.outer_exclusive_binder().as_usize()],
328+
)
329+
});
323330
match result {
324331
Ok((ct, _)) => ct,
325332
Err(_) => ct.super_fold_with(self),

compiler/rustc_trait_selection/src/traits/normalize.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,14 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
260260
}
261261

262262
ty::Projection if !data.has_escaping_bound_vars() => {
263-
// This branch is *mostly* just an optimization: when we don't
264-
// have escaping bound vars, we don't need to replace them with
265-
// placeholders (see branch below). *Also*, we know that we can
266-
// register an obligation to *later* project, since we know
267-
// there won't be bound vars there.
263+
// When we don't have escaping bound vars we can normalize ambig aliases
264+
// to inference variables (done in `normalize_projection_ty`). This would
265+
// be wrong if there were escaping bound vars as even if we instantiated
266+
// the bound vars with placeholders, we wouldn't be able to map them back
267+
// after normalization succeeded.
268+
//
269+
// Also, as an optimization: when we don't have escaping bound vars, we don't
270+
// need to replace them with placeholders (see branch below).
268271
let data = data.fold_with(self);
269272
let normalized_ty = project::normalize_projection_ty(
270273
self.selcx,

0 commit comments

Comments
 (0)