diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-04-30 22:36:41 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-30 22:36:41 +0200 |
| commit | 6423d7507649a324b5b1f6b0d64a2bef1d71397c (patch) | |
| tree | 62ca1e535bca70d5ab862c991499982182aeed3e | |
| parent | 372b15e55e5573e92ba2ff65d4df1821299fe998 (diff) | |
| parent | c31794d6d372e9f5cb575a8ee5618347d3686f89 (diff) | |
| download | rust-6423d7507649a324b5b1f6b0d64a2bef1d71397c.tar.gz rust-6423d7507649a324b5b1f6b0d64a2bef1d71397c.zip | |
Rollup merge of #140468 - BoxyUwU:normalization_confusings2, r=lcnr
Minor tweaks to make some normalization (adjacent) code less confusing r? lcnr sorry for double ping lol
| -rw-r--r-- | compiler/rustc_hir_typeck/src/writeback.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/normalize.rs | 57 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/normalize.rs | 13 |
4 files changed, 56 insertions, 52 deletions
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 807d62562db..4a171a08ef7 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -1,6 +1,12 @@ -// Type resolution: the phase that finds all the types in the AST with -// unresolved type variables and replaces "ty_var" types with their -// generic parameters. +//! During type inference, partially inferred terms are +//! represented using inference variables (ty::Infer). These don't appear in +//! the final [`ty::TypeckResults`] since all of the types should have been +//! inferred once typeck is done. +//! +//! When type inference is running however, having to update the typeck results +//! every time a new type is inferred would be unreasonably slow, so instead all +//! of the replacement happens at the end in [`FnCtxt::resolve_type_vars_in_body`], +//! which creates a new `TypeckResults` which doesn't contain any inference variables. use std::mem; @@ -26,15 +32,6 @@ use crate::FnCtxt; /////////////////////////////////////////////////////////////////////////// // Entry point -// During type inference, partially inferred types are -// represented using Type variables (ty::Infer). These don't appear in -// the final TypeckResults since all of the types should have been -// inferred once typeck is done. -// When type inference is running however, having to update the typeck -// typeck results every time a new type is inferred would be unreasonably slow, -// so instead all of the replacement happens at the end in -// resolve_type_vars_in_body, which creates a new TypeTables which -// doesn't contain any inference types. impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn resolve_type_vars_in_body( &self, @@ -89,14 +86,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -/////////////////////////////////////////////////////////////////////////// -// The Writeback context. This visitor walks the HIR, checking the -// fn-specific typeck results to find references to types or regions. It -// resolves those regions to remove inference variables and writes the -// final result back into the master typeck results in the tcx. Here and -// there, it applies a few ad-hoc checks that were not convenient to -// do elsewhere. - +/// The Writeback context. This visitor walks the HIR, checking the +/// fn-specific typeck results to find inference variables. It resolves +/// those inference variables and writes the final result into the +/// `TypeckResults`. It also applies a few ad-hoc checks that were not +/// convenient to do elsewhere. struct WritebackCx<'cx, 'tcx> { fcx: &'cx FnCtxt<'cx, 'tcx>, @@ -877,7 +871,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(value).as_usize()]; - match solve::deeply_normalize_with_skipped_universes_and_ambiguous_goals( + match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( at, value, universes, ) { Ok((value, goals)) => { diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs index 0c2451a80a7..5a5d16167d2 100644 --- a/compiler/rustc_trait_selection/src/solve.rs +++ b/compiler/rustc_trait_selection/src/solve.rs @@ -11,6 +11,6 @@ pub use fulfill::{FulfillmentCtxt, NextSolverError}; pub(crate) use normalize::deeply_normalize_for_diagnostics; pub use normalize::{ deeply_normalize, deeply_normalize_with_skipped_universes, - deeply_normalize_with_skipped_universes_and_ambiguous_goals, + deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals, }; pub use select::InferCtxtSelectExt; diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5f1e63ab225..d903f94b489 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -45,9 +45,11 @@ where T: TypeFoldable<TyCtxt<'tcx>>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { - let (value, goals) = - deeply_normalize_with_skipped_universes_and_ambiguous_goals(at, value, universes)?; - assert_eq!(goals, vec![]); + let (value, coroutine_goals) = + deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( + at, value, universes, + )?; + assert_eq!(coroutine_goals, vec![]); Ok(value) } @@ -59,9 +61,9 @@ where /// entered before passing `value` to the function. This is currently needed for /// `normalize_erasing_regions`, which skips binders as it walks through a type. /// -/// This returns a set of stalled obligations if the typing mode of the underlying infcx -/// has any stalled coroutine def ids. -pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals<'tcx, T, E>( +/// This returns a set of stalled obligations involving coroutines if the typing mode of +/// the underlying infcx has any stalled coroutine def ids. +pub fn deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals<'tcx, T, E>( at: At<'_, 'tcx>, value: T, universes: Vec<Option<UniverseIndex>>, @@ -71,11 +73,16 @@ where E: FromSolverError<'tcx, NextSolverError<'tcx>>, { let fulfill_cx = FulfillmentCtxt::new(at.infcx); - let mut folder = - NormalizationFolder { at, fulfill_cx, depth: 0, universes, stalled_goals: vec![] }; + let mut folder = NormalizationFolder { + at, + fulfill_cx, + depth: 0, + universes, + stalled_coroutine_goals: vec![], + }; let value = value.try_fold_with(&mut folder)?; let errors = folder.fulfill_cx.select_all_or_error(at.infcx); - if errors.is_empty() { Ok((value, folder.stalled_goals)) } else { Err(errors) } + if errors.is_empty() { Ok((value, folder.stalled_coroutine_goals)) } else { Err(errors) } } struct NormalizationFolder<'me, 'tcx, E> { @@ -83,7 +90,7 @@ struct NormalizationFolder<'me, 'tcx, E> { fulfill_cx: FulfillmentCtxt<'tcx, E>, depth: usize, universes: Vec<Option<UniverseIndex>>, - stalled_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, + stalled_coroutine_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, } impl<'tcx, E> NormalizationFolder<'_, 'tcx, E> @@ -182,7 +189,7 @@ where return Err(errors); } - self.stalled_goals.extend( + self.stalled_coroutine_goals.extend( self.fulfill_cx .drain_stalled_obligations_for_coroutines(self.at.infcx) .into_iter() @@ -298,13 +305,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { let infcx = self.at.infcx; - let result = - infcx.commit_if_ok(|_| { - deeply_normalize_with_skipped_universes_and_ambiguous_goals::< - _, - ScrubbedTraitError<'tcx>, - >(self.at, ty, vec![None; ty.outer_exclusive_binder().as_usize()]) - }); + let result: Result<_, Vec<ScrubbedTraitError<'tcx>>> = infcx.commit_if_ok(|_| { + deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( + self.at, + ty, + vec![None; ty.outer_exclusive_binder().as_usize()], + ) + }); match result { Ok((ty, _)) => ty, Err(_) => ty.super_fold_with(self), @@ -313,13 +320,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { let infcx = self.at.infcx; - let result = - infcx.commit_if_ok(|_| { - deeply_normalize_with_skipped_universes_and_ambiguous_goals::< - _, - ScrubbedTraitError<'tcx>, - >(self.at, ct, vec![None; ct.outer_exclusive_binder().as_usize()]) - }); + let result: Result<_, Vec<ScrubbedTraitError<'tcx>>> = infcx.commit_if_ok(|_| { + deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( + self.at, + ct, + vec![None; ct.outer_exclusive_binder().as_usize()], + ) + }); match result { Ok((ct, _)) => ct, Err(_) => ct.super_fold_with(self), diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index d38ddbc825c..5f0acd46f86 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -260,11 +260,14 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx } ty::Projection if !data.has_escaping_bound_vars() => { - // This branch is *mostly* just an optimization: when we don't - // have escaping bound vars, we don't need to replace them with - // placeholders (see branch below). *Also*, we know that we can - // register an obligation to *later* project, since we know - // there won't be bound vars there. + // When we don't have escaping bound vars we can normalize ambig aliases + // to inference variables (done in `normalize_projection_ty`). This would + // be wrong if there were escaping bound vars as even if we instantiated + // the bound vars with placeholders, we wouldn't be able to map them back + // after normalization succeeded. + // + // Also, as an optimization: when we don't have escaping bound vars, we don't + // need to replace them with placeholders (see branch below). let data = data.fold_with(self); let normalized_ty = project::normalize_projection_ty( self.selcx, |
