@@ -410,14 +410,22 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
410410 }
411411
412412 fn fold_region ( & mut self , r : I :: Region ) -> I :: Region {
413+ // We canonicalize free regions from the input into placeholder regions so that
414+ // region constraints created in nested contexts can be propagated back to the
415+ // caller, instead of unifying them.
416+ // See the following Zulip discussion for details:
417+ // https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/A.20question.20on.20.23251/near/579240238
413418 let kind = match r. kind ( ) {
414419 ty:: ReBound ( ..) => return r,
415420
416421 // We don't canonicalize `ReStatic` in the `param_env` as we use it
417422 // when checking whether a `ParamEnv` candidate is global.
418423 ty:: ReStatic => match self . canonicalize_mode {
419424 CanonicalizeMode :: Input ( CanonicalizeInputKind :: Predicate ) => {
420- CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT )
425+ CanonicalVarKind :: PlaceholderRegion ( ty:: PlaceholderRegion :: new_anon (
426+ ty:: UniverseIndex :: ROOT ,
427+ self . variables . len ( ) . into ( ) ,
428+ ) )
421429 }
422430 CanonicalizeMode :: Input ( CanonicalizeInputKind :: ParamEnv )
423431 | CanonicalizeMode :: Response { .. } => return r,
@@ -431,24 +439,41 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
431439 // `ReErased`. We may be able to short-circuit registering region
432440 // obligations if we encounter a `ReErased` on one side, for example.
433441 ty:: ReErased | ty:: ReError ( _) => match self . canonicalize_mode {
434- CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
442+ CanonicalizeMode :: Input ( _) => {
443+ CanonicalVarKind :: PlaceholderRegion ( ty:: PlaceholderRegion :: new_anon (
444+ ty:: UniverseIndex :: ROOT ,
445+ self . variables . len ( ) . into ( ) ,
446+ ) )
447+ }
435448 CanonicalizeMode :: Response { .. } => return r,
436449 } ,
437450
438451 ty:: ReEarlyParam ( _) | ty:: ReLateParam ( _) => match self . canonicalize_mode {
439- CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
452+ CanonicalizeMode :: Input ( _) => {
453+ CanonicalVarKind :: PlaceholderRegion ( ty:: PlaceholderRegion :: new_anon (
454+ ty:: UniverseIndex :: ROOT ,
455+ self . variables . len ( ) . into ( ) ,
456+ ) )
457+ }
440458 CanonicalizeMode :: Response { .. } => {
441459 panic ! ( "unexpected region in response: {r:?}" )
442460 }
443461 } ,
444462
445463 ty:: RePlaceholder ( placeholder) => match self . canonicalize_mode {
446- // We canonicalize placeholder regions as existentials in query inputs.
447- CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
464+ CanonicalizeMode :: Input ( _) => {
465+ CanonicalVarKind :: PlaceholderRegion ( ty:: PlaceholderRegion :: new_anon (
466+ ty:: UniverseIndex :: ROOT ,
467+ self . variables . len ( ) . into ( ) ,
468+ ) )
469+ }
448470 CanonicalizeMode :: Response { max_input_universe } => {
449471 // If we have a placeholder region inside of a query, it must be from
450- // a new universe.
451- if max_input_universe. can_name ( placeholder. universe ( ) ) {
472+ // a new universe, unless from the root universe, which is used for
473+ // canonicalization of any free region from the input.
474+ if placeholder. universe ( ) != ty:: UniverseIndex :: ROOT
475+ && max_input_universe. can_name ( placeholder. universe ( ) )
476+ {
452477 panic ! ( "new placeholder in universe {max_input_universe:?}: {r:?}" ) ;
453478 }
454479 CanonicalVarKind :: PlaceholderRegion ( placeholder)
@@ -462,7 +487,12 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
462487 "region vid should have been resolved fully before canonicalization"
463488 ) ;
464489 match self . canonicalize_mode {
465- CanonicalizeMode :: Input ( _) => CanonicalVarKind :: Region ( ty:: UniverseIndex :: ROOT ) ,
490+ CanonicalizeMode :: Input ( _) => {
491+ CanonicalVarKind :: PlaceholderRegion ( ty:: PlaceholderRegion :: new_anon (
492+ ty:: UniverseIndex :: ROOT ,
493+ self . variables . len ( ) . into ( ) ,
494+ ) )
495+ }
466496 CanonicalizeMode :: Response { .. } => {
467497 CanonicalVarKind :: Region ( self . delegate . universe_of_lt ( vid) . unwrap ( ) )
468498 }
0 commit comments