@@ -253,76 +253,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
253253 }
254254 }
255255
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) ?,
326257 } ;
327258
328259 self . cache . insert ( ty, res) ;
@@ -359,3 +290,76 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
359290 }
360291 }
361292}
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