1- use crate :: infer:: InferCtxtExt as _;
21use crate :: traits:: { self , ObligationCause , PredicateObligation } ;
32use rustc_data_structures:: fx:: FxHashMap ;
43use rustc_data_structures:: sync:: Lrc ;
@@ -863,7 +862,6 @@ struct Instantiator<'a, 'tcx> {
863862}
864863
865864impl < ' a , ' tcx > Instantiator < ' a , ' tcx > {
866- #[ instrument( level = "debug" , skip( self ) ) ]
867865 fn instantiate_opaque_types_in_map < T : TypeFoldable < ' tcx > > ( & mut self , value : T ) -> T {
868866 let tcx = self . infcx . tcx ;
869867 value. fold_with ( & mut BottomUpFolder {
@@ -954,6 +952,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
954952 } )
955953 }
956954
955+ #[ instrument( skip( self ) , level = "debug" ) ]
957956 fn fold_opaque_ty (
958957 & mut self ,
959958 ty : Ty < ' tcx > ,
@@ -964,25 +963,18 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
964963 let tcx = infcx. tcx ;
965964 let OpaqueTypeKey { def_id, substs } = opaque_type_key;
966965
967- debug ! ( "instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})" , def_id, substs) ;
968-
969966 // Use the same type variable if the exact same opaque type appears more
970967 // than once in the return type (e.g., if it's passed to a type alias).
971968 if let Some ( opaque_defn) = infcx. inner . borrow ( ) . opaque_types . get ( & opaque_type_key) {
972- debug ! ( "instantiate_opaque_types: returning concrete ty {:?}" , opaque_defn. concrete_ty) ;
969+ debug ! ( "re-using cached concrete type {:?}" , opaque_defn. concrete_ty. kind ( ) ) ;
973970 return opaque_defn. concrete_ty ;
974971 }
972+
975973 let ty_var = infcx. next_ty_var ( TypeVariableOrigin {
976974 kind : TypeVariableOriginKind :: TypeInference ,
977975 span : self . value_span ,
978976 } ) ;
979977
980- // Make sure that we are in fact defining the *entire* type
981- // (e.g., `type Foo<T: Bound> = impl Bar;` needs to be
982- // defined by a function like `fn foo<T: Bound>() -> Foo<T>`).
983- debug ! ( "instantiate_opaque_types: param_env={:#?}" , self . param_env, ) ;
984- debug ! ( "instantiate_opaque_types: generics={:#?}" , tcx. generics_of( def_id) , ) ;
985-
986978 // Ideally, we'd get the span where *this specific `ty` came
987979 // from*, but right now we just use the span from the overall
988980 // value being folded. In simple cases like `-> impl Foo`,
@@ -999,43 +991,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
999991 infcx. opaque_types_vars . insert ( ty_var, ty) ;
1000992 }
1001993
1002- debug ! ( "instantiate_opaque_types: ty_var={:?}" , ty_var) ;
1003- self . compute_opaque_type_obligations ( opaque_type_key) ;
1004-
1005- ty_var
1006- }
1007-
1008- fn compute_opaque_type_obligations ( & mut self , opaque_type_key : OpaqueTypeKey < ' tcx > ) {
1009- let infcx = self . infcx ;
1010- let tcx = infcx. tcx ;
1011- let OpaqueTypeKey { def_id, substs } = opaque_type_key;
994+ debug ! ( "generated new type inference var {:?}" , ty_var. kind( ) ) ;
1012995
1013996 let item_bounds = tcx. explicit_item_bounds ( def_id) ;
1014- debug ! ( "instantiate_opaque_types: bounds={:#?}" , item_bounds) ;
1015- let bounds: Vec < _ > =
1016- item_bounds. iter ( ) . map ( |( bound, _) | bound. subst ( tcx, substs) ) . collect ( ) ;
1017-
1018- let param_env = tcx. param_env ( def_id) ;
1019- let InferOk { value : bounds, obligations } = infcx. partially_normalize_associated_types_in (
1020- ObligationCause :: misc ( self . value_span , self . body_id ) ,
1021- param_env,
1022- bounds,
1023- ) ;
1024- self . obligations . extend ( obligations) ;
1025997
1026- debug ! ( "instantiate_opaque_types: bounds={:?}" , bounds) ;
998+ self . obligations . reserve ( item_bounds. len ( ) ) ;
999+ for ( predicate, _) in item_bounds {
1000+ debug ! ( ?predicate) ;
1001+ let predicate = predicate. subst ( tcx, substs) ;
1002+ debug ! ( ?predicate) ;
1003+
1004+ // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
1005+ let predicate = predicate. fold_with ( & mut BottomUpFolder {
1006+ tcx,
1007+ ty_op : |ty| match ty. kind ( ) {
1008+ ty:: Projection ( projection_ty) => infcx. infer_projection (
1009+ self . param_env ,
1010+ * projection_ty,
1011+ ObligationCause :: misc ( self . value_span , self . body_id ) ,
1012+ 0 ,
1013+ & mut self . obligations ,
1014+ ) ,
1015+ _ => ty,
1016+ } ,
1017+ lt_op : |lt| lt,
1018+ ct_op : |ct| ct,
1019+ } ) ;
1020+ debug ! ( ?predicate) ;
10271021
1028- for predicate in & bounds {
10291022 if let ty:: PredicateKind :: Projection ( projection) = predicate. kind ( ) . skip_binder ( ) {
10301023 if projection. ty . references_error ( ) {
10311024 // No point on adding these obligations since there's a type error involved.
1032- return ;
1025+ return tcx . ty_error ( ) ;
10331026 }
10341027 }
1035- }
1036-
1037- self . obligations . reserve ( bounds. len ( ) ) ;
1038- for predicate in bounds {
10391028 // Change the predicate to refer to the type variable,
10401029 // which will be the concrete type instead of the opaque type.
10411030 // This also instantiates nested instances of `impl Trait`.
@@ -1045,9 +1034,11 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
10451034 traits:: ObligationCause :: new ( self . value_span , self . body_id , traits:: OpaqueType ) ;
10461035
10471036 // Require that the predicate holds for the concrete type.
1048- debug ! ( "instantiate_opaque_types: predicate={:?}" , predicate) ;
1037+ debug ! ( ? predicate) ;
10491038 self . obligations . push ( traits:: Obligation :: new ( cause, self . param_env , predicate) ) ;
10501039 }
1040+
1041+ ty_var
10511042 }
10521043}
10531044
0 commit comments