@@ -27,6 +27,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
2727use rustc_errors:: ErrorGuaranteed ;
2828use rustc_hir:: def:: DefKind ;
2929use rustc_hir:: lang_items:: LangItem ;
30+ use rustc_hir:: OpaqueTyOrigin ;
3031use rustc_infer:: infer:: at:: At ;
3132use rustc_infer:: infer:: resolve:: OpportunisticRegionResolver ;
3233use rustc_infer:: infer:: DefineOpaqueTypes ;
@@ -318,17 +319,6 @@ fn project_and_unify_type<'cx, 'tcx>(
318319 } ;
319320 debug ! ( ?normalized, ?obligations, "project_and_unify_type result" ) ;
320321 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) ;
332322
333323 // Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait`
334324 match infcx. at ( & obligation. cause , obligation. param_env ) . eq (
@@ -409,25 +399,6 @@ where
409399 result
410400}
411401
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-
431402struct AssocTypeNormalizer < ' a , ' b , ' tcx > {
432403 selcx : & ' a mut SelectionContext < ' b , ' tcx > ,
433404 param_env : ty:: ParamEnv < ' tcx > ,
@@ -488,11 +459,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
488459 "Normalizing {value:?} without wrapping in a `Binder`"
489460 ) ;
490461
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 ) }
496463 }
497464}
498465
@@ -512,7 +479,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
512479 }
513480
514481 fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
515- if !needs_normalization ( & ty , self . param_env . reveal ( ) ) {
482+ if !ty . has_projections ( ) {
516483 return ty;
517484 }
518485
@@ -548,7 +515,36 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
548515 ty:: Opaque => {
549516 // Only normalize `impl Trait` outside of type inference, usually in codegen.
550517 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+ }
552548
553549 Reveal :: All => {
554550 let recursion_limit = self . interner ( ) . recursion_limit ( ) ;
@@ -752,9 +748,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
752748 #[ instrument( skip( self ) , level = "debug" ) ]
753749 fn fold_const ( & mut self , constant : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
754750 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 ( ) {
758752 constant
759753 } else {
760754 let constant = constant. super_fold_with ( self ) ;
@@ -770,11 +764,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
770764
771765 #[ inline]
772766 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 }
778768 }
779769}
780770
0 commit comments