1
1
//! Code for the 'normalization' query. This consists of a wrapper
2
2
//! which folds deeply, invoking the underlying
3
- //! `normalize_canonicalized_projection_ty ` query when it encounters projections.
3
+ //! `normalize_canonicalized_projection ` query when it encounters projections.
4
4
5
5
use rustc_data_structures:: sso:: SsoHashMap ;
6
6
use rustc_data_structures:: stack:: ensure_sufficient_stack;
7
+ use rustc_hir:: def:: DefKind ;
7
8
use rustc_infer:: traits:: PredicateObligations ;
8
9
use rustc_macros:: extension;
9
10
pub use rustc_middle:: traits:: query:: NormalizationResult ;
@@ -253,7 +254,9 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
253
254
}
254
255
}
255
256
256
- ty:: Projection | ty:: Inherent | ty:: Free => self . try_fold_free_or_assoc ( ty, kind, data) ?,
257
+ ty:: Projection | ty:: Inherent | ty:: Free => self
258
+ . try_fold_free_or_assoc ( ty:: AliasTerm :: new ( self . cx ( ) , data. def_id , data. args ) ) ?
259
+ . expect_type ( ) ,
257
260
} ;
258
261
259
262
self . cache . insert ( ty, res) ;
@@ -268,12 +271,22 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
268
271
return Ok ( constant) ;
269
272
}
270
273
271
- let constant = crate :: traits:: with_replaced_escaping_bound_vars (
272
- self . infcx ,
273
- & mut self . universes ,
274
- constant,
275
- |constant| crate :: traits:: evaluate_const ( & self . infcx , constant, self . param_env ) ,
276
- ) ;
274
+ let uv = match constant. kind ( ) {
275
+ ty:: ConstKind :: Unevaluated ( uv) => uv,
276
+ _ => return constant. try_super_fold_with ( self ) ,
277
+ } ;
278
+
279
+ let constant = match self . cx ( ) . def_kind ( uv. def ) {
280
+ DefKind :: AnonConst => crate :: traits:: with_replaced_escaping_bound_vars (
281
+ self . infcx ,
282
+ & mut self . universes ,
283
+ constant,
284
+ |constant| crate :: traits:: evaluate_const ( & self . infcx , constant, self . param_env ) ,
285
+ ) ,
286
+ _ => self
287
+ . try_fold_free_or_assoc ( ty:: AliasTerm :: new ( self . cx ( ) , uv. def , uv. args ) ) ?
288
+ . expect_const ( ) ,
289
+ } ;
277
290
debug ! ( ?constant, ?self . param_env) ;
278
291
constant. try_super_fold_with ( self )
279
292
}
@@ -294,39 +307,45 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
294
307
impl < ' a , ' tcx > QueryNormalizer < ' a , ' tcx > {
295
308
fn try_fold_free_or_assoc (
296
309
& mut self ,
297
- ty : Ty < ' tcx > ,
298
- kind : ty:: AliasTyKind ,
299
- data : ty:: AliasTy < ' tcx > ,
300
- ) -> Result < Ty < ' tcx > , NoSolution > {
310
+ term : ty:: AliasTerm < ' tcx > ,
311
+ ) -> Result < ty:: Term < ' tcx > , NoSolution > {
301
312
let infcx = self . infcx ;
302
313
let tcx = infcx. tcx ;
303
314
// Just an optimization: When we don't have escaping bound vars,
304
315
// 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) ) )
316
+ let ( term , maps) = if term . has_escaping_bound_vars ( ) {
317
+ let ( term , mapped_regions, mapped_types, mapped_consts) =
318
+ BoundVarReplacer :: replace_bound_vars ( infcx, & mut self . universes , term ) ;
319
+ ( term , Some ( ( mapped_regions, mapped_types, mapped_consts) ) )
309
320
} else {
310
- ( data , None )
321
+ ( term , None )
311
322
} ;
312
- let data = data . try_fold_with ( self ) ?;
323
+ let term = term . try_fold_with ( self ) ?;
313
324
314
325
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 ) ;
326
+ let c_term = infcx. canonicalize_query ( self . param_env . and ( term ) , & mut orig_values) ;
327
+ debug ! ( "QueryNormalizer: c_term = {:#?}" , c_term ) ;
317
328
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" ) ,
329
+ let result = match term. kind ( tcx) {
330
+ ty:: AliasTermKind :: ProjectionTy | ty:: AliasTermKind :: ProjectionConst => {
331
+ tcx. normalize_canonicalized_projection ( c_term)
332
+ }
333
+ ty:: AliasTermKind :: FreeTy | ty:: AliasTermKind :: FreeConst => {
334
+ tcx. normalize_canonicalized_free_alias ( c_term)
335
+ }
336
+ ty:: AliasTermKind :: InherentTy | ty:: AliasTermKind :: InherentConst => {
337
+ tcx. normalize_canonicalized_inherent_projection ( c_term)
338
+ }
339
+ kind @ ( ty:: AliasTermKind :: OpaqueTy | ty:: AliasTermKind :: UnevaluatedConst ) => {
340
+ unreachable ! ( "did not expect {kind:?} due to match arm above" )
341
+ }
323
342
} ?;
324
343
// We don't expect ambiguity.
325
344
if !result. value . is_proven ( ) {
326
345
// Rustdoc normalizes possibly not well-formed types, so only
327
346
// treat this as a bug if we're not in rustdoc.
328
347
if !tcx. sess . opts . actually_rustdoc {
329
- tcx. dcx ( ) . delayed_bug ( format ! ( "unexpected ambiguity: {c_data :?} {result:?}" ) ) ;
348
+ tcx. dcx ( ) . delayed_bug ( format ! ( "unexpected ambiguity: {c_term :?} {result:?}" ) ) ;
330
349
}
331
350
return Err ( NoSolution ) ;
332
351
}
@@ -347,16 +366,19 @@ impl<'a, 'tcx> QueryNormalizer<'a, 'tcx> {
347
366
mapped_types,
348
367
mapped_consts,
349
368
& self . universes ,
350
- result. normalized_ty ,
369
+ result. normalized_term ,
351
370
)
352
371
} else {
353
- result. normalized_ty
372
+ result. normalized_term
354
373
} ;
355
- // `tcx.normalize_canonicalized_projection_ty ` may normalize to a type that
374
+ // `tcx.normalize_canonicalized_projection ` may normalize to a type that
356
375
// still has unevaluated consts, so keep normalizing here if that's the case.
357
376
// Similarly, `tcx.normalize_canonicalized_free_alias` will only unwrap one layer
358
377
// 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 ) {
378
+ if res != term. to_term ( tcx)
379
+ && ( res. as_type ( ) . map_or ( false , |t| t. has_type_flags ( ty:: TypeFlags :: HAS_CT_PROJECTION ) )
380
+ || term. kind ( tcx) == ty:: AliasTermKind :: FreeTy )
381
+ {
360
382
res. try_fold_with ( self )
361
383
} else {
362
384
Ok ( res)
0 commit comments