@@ -253,76 +253,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
253
253
}
254
254
}
255
255
256
- ty:: Projection | ty:: Inherent | ty:: Free => {
257
- // See note in `rustc_trait_selection::traits::project`
258
-
259
- let infcx = self . infcx ;
260
- let tcx = infcx. tcx ;
261
- // Just an optimization: When we don't have escaping bound vars,
262
- // we don't need to replace them with placeholders.
263
- let ( data, maps) = if data. has_escaping_bound_vars ( ) {
264
- let ( data, mapped_regions, mapped_types, mapped_consts) =
265
- BoundVarReplacer :: replace_bound_vars ( infcx, & mut self . universes , data) ;
266
- ( data, Some ( ( mapped_regions, mapped_types, mapped_consts) ) )
267
- } else {
268
- ( data, None )
269
- } ;
270
- let data = data. try_fold_with ( self ) ?;
271
-
272
- let mut orig_values = OriginalQueryValues :: default ( ) ;
273
- let c_data = infcx. canonicalize_query ( self . param_env . and ( data) , & mut orig_values) ;
274
- debug ! ( "QueryNormalizer: c_data = {:#?}" , c_data) ;
275
- debug ! ( "QueryNormalizer: orig_values = {:#?}" , orig_values) ;
276
- let result = match kind {
277
- ty:: Projection => tcx. normalize_canonicalized_projection_ty ( c_data) ,
278
- ty:: Free => tcx. normalize_canonicalized_free_alias ( c_data) ,
279
- ty:: Inherent => tcx. normalize_canonicalized_inherent_projection_ty ( c_data) ,
280
- kind => unreachable ! ( "did not expect {kind:?} due to match arm above" ) ,
281
- } ?;
282
- // We don't expect ambiguity.
283
- if !result. value . is_proven ( ) {
284
- // Rustdoc normalizes possibly not well-formed types, so only
285
- // treat this as a bug if we're not in rustdoc.
286
- if !tcx. sess . opts . actually_rustdoc {
287
- tcx. dcx ( )
288
- . delayed_bug ( format ! ( "unexpected ambiguity: {c_data:?} {result:?}" ) ) ;
289
- }
290
- return Err ( NoSolution ) ;
291
- }
292
- let InferOk { value : result, obligations } = infcx
293
- . instantiate_query_response_and_region_obligations (
294
- self . cause ,
295
- self . param_env ,
296
- & orig_values,
297
- result,
298
- ) ?;
299
- debug ! ( "QueryNormalizer: result = {:#?}" , result) ;
300
- debug ! ( "QueryNormalizer: obligations = {:#?}" , obligations) ;
301
- self . obligations . extend ( obligations) ;
302
- let res = if let Some ( ( mapped_regions, mapped_types, mapped_consts) ) = maps {
303
- PlaceholderReplacer :: replace_placeholders (
304
- infcx,
305
- mapped_regions,
306
- mapped_types,
307
- mapped_consts,
308
- & self . universes ,
309
- result. normalized_ty ,
310
- )
311
- } else {
312
- result. normalized_ty
313
- } ;
314
- // `tcx.normalize_canonicalized_projection_ty` may normalize to a type that
315
- // still has unevaluated consts, so keep normalizing here if that's the case.
316
- // Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer
317
- // of type and we need to continue folding it to reveal the TAIT behind it.
318
- if res != ty
319
- && ( res. has_type_flags ( ty:: TypeFlags :: HAS_CT_PROJECTION ) || kind == ty:: Free )
320
- {
321
- res. try_fold_with ( self ) ?
322
- } else {
323
- res
324
- }
325
- }
256
+ ty:: Projection | ty:: Inherent | ty:: Free => self . try_fold_free_or_assoc ( ty, kind, data) ?,
326
257
} ;
327
258
328
259
self . cache . insert ( ty, res) ;
@@ -359,3 +290,76 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
359
290
}
360
291
}
361
292
}
293
+
294
+ impl < ' a , ' tcx > QueryNormalizer < ' a , ' tcx > {
295
+ fn try_fold_free_or_assoc (
296
+ & mut self ,
297
+ ty : Ty < ' tcx > ,
298
+ kind : ty:: AliasTyKind ,
299
+ data : ty:: AliasTy < ' tcx > ,
300
+ ) -> Result < Ty < ' tcx > , NoSolution > {
301
+ let infcx = self . infcx ;
302
+ let tcx = infcx. tcx ;
303
+ // Just an optimization: When we don't have escaping bound vars,
304
+ // we don't need to replace them with placeholders.
305
+ let ( data, maps) = if data. has_escaping_bound_vars ( ) {
306
+ let ( data, mapped_regions, mapped_types, mapped_consts) =
307
+ BoundVarReplacer :: replace_bound_vars ( infcx, & mut self . universes , data) ;
308
+ ( data, Some ( ( mapped_regions, mapped_types, mapped_consts) ) )
309
+ } else {
310
+ ( data, None )
311
+ } ;
312
+ let data = data. try_fold_with ( self ) ?;
313
+
314
+ let mut orig_values = OriginalQueryValues :: default ( ) ;
315
+ let c_data = infcx. canonicalize_query ( self . param_env . and ( data) , & mut orig_values) ;
316
+ debug ! ( "QueryNormalizer: c_data = {:#?}" , c_data) ;
317
+ debug ! ( "QueryNormalizer: orig_values = {:#?}" , orig_values) ;
318
+ let result = match kind {
319
+ ty:: Projection => tcx. normalize_canonicalized_projection_ty ( c_data) ,
320
+ ty:: Free => tcx. normalize_canonicalized_free_alias ( c_data) ,
321
+ ty:: Inherent => tcx. normalize_canonicalized_inherent_projection_ty ( c_data) ,
322
+ kind => unreachable ! ( "did not expect {kind:?} due to match arm above" ) ,
323
+ } ?;
324
+ // We don't expect ambiguity.
325
+ if !result. value . is_proven ( ) {
326
+ // Rustdoc normalizes possibly not well-formed types, so only
327
+ // treat this as a bug if we're not in rustdoc.
328
+ if !tcx. sess . opts . actually_rustdoc {
329
+ tcx. dcx ( ) . delayed_bug ( format ! ( "unexpected ambiguity: {c_data:?} {result:?}" ) ) ;
330
+ }
331
+ return Err ( NoSolution ) ;
332
+ }
333
+ let InferOk { value : result, obligations } = infcx
334
+ . instantiate_query_response_and_region_obligations (
335
+ self . cause ,
336
+ self . param_env ,
337
+ & orig_values,
338
+ result,
339
+ ) ?;
340
+ debug ! ( "QueryNormalizer: result = {:#?}" , result) ;
341
+ debug ! ( "QueryNormalizer: obligations = {:#?}" , obligations) ;
342
+ self . obligations . extend ( obligations) ;
343
+ let res = if let Some ( ( mapped_regions, mapped_types, mapped_consts) ) = maps {
344
+ PlaceholderReplacer :: replace_placeholders (
345
+ infcx,
346
+ mapped_regions,
347
+ mapped_types,
348
+ mapped_consts,
349
+ & self . universes ,
350
+ result. normalized_ty ,
351
+ )
352
+ } else {
353
+ result. normalized_ty
354
+ } ;
355
+ // `tcx.normalize_canonicalized_projection_ty` may normalize to a type that
356
+ // still has unevaluated consts, so keep normalizing here if that's the case.
357
+ // Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer
358
+ // of type and we need to continue folding it to reveal the TAIT behind it.
359
+ if res != ty && ( res. has_type_flags ( ty:: TypeFlags :: HAS_CT_PROJECTION ) || kind == ty:: Free ) {
360
+ res. try_fold_with ( self )
361
+ } else {
362
+ Ok ( res)
363
+ }
364
+ }
365
+ }
0 commit comments