1
- use crate :: infer:: InferCtxtExt as _;
2
1
use crate :: traits:: { self , ObligationCause , PredicateObligation } ;
3
2
use rustc_data_structures:: fx:: FxHashMap ;
4
3
use rustc_data_structures:: sync:: Lrc ;
@@ -863,7 +862,6 @@ struct Instantiator<'a, 'tcx> {
863
862
}
864
863
865
864
impl < ' a , ' tcx > Instantiator < ' a , ' tcx > {
866
- #[ instrument( level = "debug" , skip( self ) ) ]
867
865
fn instantiate_opaque_types_in_map < T : TypeFoldable < ' tcx > > ( & mut self , value : T ) -> T {
868
866
let tcx = self . infcx . tcx ;
869
867
value. fold_with ( & mut BottomUpFolder {
@@ -954,6 +952,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
954
952
} )
955
953
}
956
954
955
+ #[ instrument( skip( self ) , level = "debug" ) ]
957
956
fn fold_opaque_ty (
958
957
& mut self ,
959
958
ty : Ty < ' tcx > ,
@@ -964,25 +963,18 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
964
963
let tcx = infcx. tcx ;
965
964
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
966
965
967
- debug ! ( "instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})" , def_id, substs) ;
968
-
969
966
// Use the same type variable if the exact same opaque type appears more
970
967
// than once in the return type (e.g., if it's passed to a type alias).
971
968
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 ( ) ) ;
973
970
return opaque_defn. concrete_ty ;
974
971
}
972
+
975
973
let ty_var = infcx. next_ty_var ( TypeVariableOrigin {
976
974
kind : TypeVariableOriginKind :: TypeInference ,
977
975
span : self . value_span ,
978
976
} ) ;
979
977
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
-
986
978
// Ideally, we'd get the span where *this specific `ty` came
987
979
// from*, but right now we just use the span from the overall
988
980
// value being folded. In simple cases like `-> impl Foo`,
@@ -999,43 +991,40 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
999
991
infcx. opaque_types_vars . insert ( ty_var, ty) ;
1000
992
}
1001
993
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( ) ) ;
1012
995
1013
996
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) ;
1025
997
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) ;
1027
1021
1028
- for predicate in & bounds {
1029
1022
if let ty:: PredicateKind :: Projection ( projection) = predicate. kind ( ) . skip_binder ( ) {
1030
1023
if projection. ty . references_error ( ) {
1031
1024
// No point on adding these obligations since there's a type error involved.
1032
- return ;
1025
+ return tcx . ty_error ( ) ;
1033
1026
}
1034
1027
}
1035
- }
1036
-
1037
- self . obligations . reserve ( bounds. len ( ) ) ;
1038
- for predicate in bounds {
1039
1028
// Change the predicate to refer to the type variable,
1040
1029
// which will be the concrete type instead of the opaque type.
1041
1030
// This also instantiates nested instances of `impl Trait`.
@@ -1045,9 +1034,11 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
1045
1034
traits:: ObligationCause :: new ( self . value_span , self . body_id , traits:: OpaqueType ) ;
1046
1035
1047
1036
// Require that the predicate holds for the concrete type.
1048
- debug ! ( "instantiate_opaque_types: predicate={:?}" , predicate) ;
1037
+ debug ! ( ? predicate) ;
1049
1038
self . obligations . push ( traits:: Obligation :: new ( cause, self . param_env , predicate) ) ;
1050
1039
}
1040
+
1041
+ ty_var
1051
1042
}
1052
1043
}
1053
1044
0 commit comments