@@ -27,6 +27,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
27
27
use rustc_errors:: ErrorGuaranteed ;
28
28
use rustc_hir:: def:: DefKind ;
29
29
use rustc_hir:: lang_items:: LangItem ;
30
+ use rustc_hir:: OpaqueTyOrigin ;
30
31
use rustc_infer:: infer:: at:: At ;
31
32
use rustc_infer:: infer:: resolve:: OpportunisticRegionResolver ;
32
33
use rustc_infer:: infer:: DefineOpaqueTypes ;
@@ -318,17 +319,6 @@ fn project_and_unify_type<'cx, 'tcx>(
318
319
} ;
319
320
debug ! ( ?normalized, ?obligations, "project_and_unify_type result" ) ;
320
321
let actual = obligation. predicate . term ;
321
- // For an example where this is necessary see tests/ui/impl-trait/nested-return-type2.rs
322
- // This allows users to omit re-mentioning all bounds on an associated type and just use an
323
- // `impl Trait` for the assoc type to add more bounds.
324
- let InferOk { value : actual, obligations : new } =
325
- selcx. infcx . replace_opaque_types_with_inference_vars (
326
- actual,
327
- obligation. cause . body_id ,
328
- obligation. cause . span ,
329
- obligation. param_env ,
330
- ) ;
331
- obligations. extend ( new) ;
332
322
333
323
// Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait`
334
324
match infcx. at ( & obligation. cause , obligation. param_env ) . eq (
@@ -409,25 +399,6 @@ where
409
399
result
410
400
}
411
401
412
- pub ( crate ) fn needs_normalization < ' tcx , T : TypeVisitable < TyCtxt < ' tcx > > > (
413
- value : & T ,
414
- reveal : Reveal ,
415
- ) -> bool {
416
- match reveal {
417
- Reveal :: UserFacing => value. has_type_flags (
418
- ty:: TypeFlags :: HAS_TY_PROJECTION
419
- | ty:: TypeFlags :: HAS_TY_INHERENT
420
- | ty:: TypeFlags :: HAS_CT_PROJECTION ,
421
- ) ,
422
- Reveal :: All => value. has_type_flags (
423
- ty:: TypeFlags :: HAS_TY_PROJECTION
424
- | ty:: TypeFlags :: HAS_TY_INHERENT
425
- | ty:: TypeFlags :: HAS_TY_OPAQUE
426
- | ty:: TypeFlags :: HAS_CT_PROJECTION ,
427
- ) ,
428
- }
429
- }
430
-
431
402
struct AssocTypeNormalizer < ' a , ' b , ' tcx > {
432
403
selcx : & ' a mut SelectionContext < ' b , ' tcx > ,
433
404
param_env : ty:: ParamEnv < ' tcx > ,
@@ -488,11 +459,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
488
459
"Normalizing {value:?} without wrapping in a `Binder`"
489
460
) ;
490
461
491
- if !needs_normalization ( & value, self . param_env . reveal ( ) ) {
492
- value
493
- } else {
494
- value. fold_with ( self )
495
- }
462
+ if !value. has_projections ( ) { value } else { value. fold_with ( self ) }
496
463
}
497
464
}
498
465
@@ -512,7 +479,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
512
479
}
513
480
514
481
fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
515
- if !needs_normalization ( & ty , self . param_env . reveal ( ) ) {
482
+ if !ty . has_projections ( ) {
516
483
return ty;
517
484
}
518
485
@@ -548,7 +515,36 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
548
515
ty:: Opaque => {
549
516
// Only normalize `impl Trait` outside of type inference, usually in codegen.
550
517
match self . param_env . reveal ( ) {
551
- Reveal :: UserFacing => ty. super_fold_with ( self ) ,
518
+ Reveal :: UserFacing => {
519
+ if !data. has_escaping_bound_vars ( )
520
+ && let Some ( def_id) = data. def_id . as_local ( )
521
+ && let Some (
522
+ OpaqueTyOrigin :: TyAlias { in_assoc_ty : true }
523
+ | OpaqueTyOrigin :: AsyncFn ( _)
524
+ | OpaqueTyOrigin :: FnReturn ( _) ,
525
+ ) = self . selcx . infcx . opaque_type_origin ( def_id)
526
+ {
527
+ let infer = self . selcx . infcx . next_ty_var ( TypeVariableOrigin {
528
+ kind : TypeVariableOriginKind :: OpaqueTypeInference ( data. def_id ) ,
529
+ span : self . cause . span ,
530
+ } ) ;
531
+ let InferOk { value : ( ) , obligations } = self
532
+ . selcx
533
+ . infcx
534
+ . register_hidden_type (
535
+ ty:: OpaqueTypeKey { def_id, args : data. args } ,
536
+ self . cause . clone ( ) ,
537
+ self . param_env ,
538
+ infer,
539
+ true ,
540
+ )
541
+ . expect ( "uwu" ) ;
542
+ self . obligations . extend ( obligations) ;
543
+ self . selcx . infcx . resolve_vars_if_possible ( infer)
544
+ } else {
545
+ ty. super_fold_with ( self )
546
+ }
547
+ }
552
548
553
549
Reveal :: All => {
554
550
let recursion_limit = self . interner ( ) . recursion_limit ( ) ;
@@ -752,9 +748,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
752
748
#[ instrument( skip( self ) , level = "debug" ) ]
753
749
fn fold_const ( & mut self , constant : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
754
750
let tcx = self . selcx . tcx ( ) ;
755
- if tcx. features ( ) . generic_const_exprs
756
- || !needs_normalization ( & constant, self . param_env . reveal ( ) )
757
- {
751
+ if tcx. features ( ) . generic_const_exprs || !constant. has_projections ( ) {
758
752
constant
759
753
} else {
760
754
let constant = constant. super_fold_with ( self ) ;
@@ -770,11 +764,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
770
764
771
765
#[ inline]
772
766
fn fold_predicate ( & mut self , p : ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
773
- if p. allow_normalization ( ) && needs_normalization ( & p, self . param_env . reveal ( ) ) {
774
- p. super_fold_with ( self )
775
- } else {
776
- p
777
- }
767
+ if p. allow_normalization ( ) && p. has_projections ( ) { p. super_fold_with ( self ) } else { p }
778
768
}
779
769
}
780
770
0 commit comments