@@ -11,7 +11,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
11
11
use rustc_infer:: infer:: { InferOk , InferResult } ;
12
12
use rustc_middle:: ty:: fold:: TypeFoldable ;
13
13
use rustc_middle:: ty:: subst:: InternalSubsts ;
14
- use rustc_middle:: ty:: { self , GenericParamDefKind , Ty } ;
14
+ use rustc_middle:: ty:: { self , Ty } ;
15
15
use rustc_span:: source_map:: Span ;
16
16
use rustc_target:: spec:: abi:: Abi ;
17
17
use rustc_trait_selection:: traits:: error_reporting:: ArgKind ;
@@ -76,60 +76,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
76
76
let generator_types =
77
77
check_fn ( self , self . param_env , liberated_sig, decl, expr. hir_id , body, gen) . 1 ;
78
78
79
- let base_substs = InternalSubsts :: identity_for_item (
79
+ let parent_substs = InternalSubsts :: identity_for_item (
80
80
self . tcx ,
81
81
self . tcx . closure_base_def_id ( expr_def_id. to_def_id ( ) ) ,
82
82
) ;
83
- // HACK(eddyb) this hardcodes indices into substs but it should rely on
84
- // `ClosureSubsts` and `GeneratorSubsts` providing constructors, instead.
85
- // That would also remove the need for most of the inference variables,
86
- // as they immediately unified with the actual type below, including
87
- // the `InferCtxt::closure_sig` and `ClosureSubsts::sig_ty` methods.
88
- let tupled_upvars_idx = base_substs. len ( ) + if generator_types. is_some ( ) { 4 } else { 2 } ;
89
- let substs =
90
- base_substs. extend_to ( self . tcx , expr_def_id. to_def_id ( ) , |param, _| match param. kind {
91
- GenericParamDefKind :: Lifetime => span_bug ! ( expr. span, "closure has lifetime param" ) ,
92
- GenericParamDefKind :: Type { .. } => if param. index as usize == tupled_upvars_idx {
93
- self . tcx . mk_tup ( self . tcx . upvars_mentioned ( expr_def_id) . iter ( ) . flat_map (
94
- |upvars| {
95
- upvars. iter ( ) . map ( |( & var_hir_id, _) | {
96
- // Create type variables (for now) to represent the transformed
97
- // types of upvars. These will be unified during the upvar
98
- // inference phase (`upvar.rs`).
99
- self . infcx . next_ty_var ( TypeVariableOrigin {
100
- // FIXME(eddyb) distinguish upvar inference variables from the rest.
101
- kind : TypeVariableOriginKind :: ClosureSynthetic ,
102
- span : self . tcx . hir ( ) . span ( var_hir_id) ,
103
- } )
104
- } )
105
- } ,
106
- ) )
107
- } else {
108
- // Create type variables (for now) to represent the various
109
- // pieces of information kept in `{Closure,Generic}Substs`.
110
- // They will either be unified below, or later during the upvar
111
- // inference phase (`upvar.rs`)
83
+
84
+ let tupled_upvars_ty =
85
+ self . tcx . mk_tup ( self . tcx . upvars_mentioned ( expr_def_id) . iter ( ) . flat_map ( |upvars| {
86
+ upvars. iter ( ) . map ( |( & var_hir_id, _) | {
87
+ // Create type variables (for now) to represent the transformed
88
+ // types of upvars. These will be unified during the upvar
89
+ // inference phase (`upvar.rs`).
112
90
self . infcx . next_ty_var ( TypeVariableOrigin {
91
+ // FIXME(eddyb) distinguish upvar inference variables from the rest.
113
92
kind : TypeVariableOriginKind :: ClosureSynthetic ,
114
- span : expr . span ,
93
+ span : self . tcx . hir ( ) . span ( var_hir_id ) ,
115
94
} )
116
- }
117
- . into ( ) ,
118
- GenericParamDefKind :: Const => span_bug ! ( expr. span, "closure has const param" ) ,
119
- } ) ;
95
+ } )
96
+ } ) ) ;
97
+
120
98
if let Some ( GeneratorTypes { resume_ty, yield_ty, interior, movability } ) = generator_types
121
99
{
122
- let generator_substs = substs. as_generator ( ) ;
123
- self . demand_eqtype ( expr. span , resume_ty, generator_substs. resume_ty ( ) ) ;
124
- self . demand_eqtype ( expr. span , yield_ty, generator_substs. yield_ty ( ) ) ;
125
- self . demand_eqtype ( expr. span , liberated_sig. output ( ) , generator_substs. return_ty ( ) ) ;
126
- self . demand_eqtype ( expr. span , interior, generator_substs. witness ( ) ) ;
127
-
128
- // HACK(eddyb) this forces the types equated above into `substs` but
129
- // it should rely on `GeneratorSubsts` providing a constructor, instead.
130
- let substs = self . resolve_vars_if_possible ( & substs) ;
100
+ let generator_substs = ty:: GeneratorSubsts :: new (
101
+ self . tcx ,
102
+ ty:: GeneratorSubstsParts {
103
+ parent_substs,
104
+ resume_ty,
105
+ yield_ty,
106
+ return_ty : liberated_sig. output ( ) ,
107
+ witness : interior,
108
+ tupled_upvars_ty,
109
+ } ,
110
+ ) ;
131
111
132
- return self . tcx . mk_generator ( expr_def_id. to_def_id ( ) , substs, movability) ;
112
+ return self . tcx . mk_generator (
113
+ expr_def_id. to_def_id ( ) ,
114
+ generator_substs. substs ,
115
+ movability,
116
+ ) ;
133
117
}
134
118
135
119
// Tuple up the arguments and insert the resulting function type into
@@ -149,18 +133,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149
133
expr_def_id, sig, opt_kind
150
134
) ;
151
135
152
- let sig_fn_ptr_ty = self . tcx . mk_fn_ptr ( sig ) ;
153
- self . demand_eqtype ( expr . span , sig_fn_ptr_ty , substs . as_closure ( ) . sig_as_fn_ptr_ty ( ) ) ;
136
+ let closure_kind_ty = match opt_kind {
137
+ Some ( kind ) => kind . to_ty ( self . tcx ) ,
154
138
155
- if let Some ( kind) = opt_kind {
156
- self . demand_eqtype ( expr. span , kind. to_ty ( self . tcx ) , substs. as_closure ( ) . kind_ty ( ) ) ;
157
- }
139
+ // Create a type variable (for now) to represent the closure kind.
140
+ // It will be unified during the upvar inference phase (`upvar.rs`)
141
+ None => self . infcx . next_ty_var ( TypeVariableOrigin {
142
+ // FIXME(eddyb) distinguish closure kind inference variables from the rest.
143
+ kind : TypeVariableOriginKind :: ClosureSynthetic ,
144
+ span : expr. span ,
145
+ } ) ,
146
+ } ;
158
147
159
- // HACK(eddyb) this forces the types equated above into `substs` but
160
- // it should rely on `ClosureSubsts` providing a constructor, instead.
161
- let substs = self . resolve_vars_if_possible ( & substs) ;
148
+ let closure_substs = ty:: ClosureSubsts :: new (
149
+ self . tcx ,
150
+ ty:: ClosureSubstsParts {
151
+ parent_substs,
152
+ closure_kind_ty,
153
+ closure_sig_as_fn_ptr_ty : self . tcx . mk_fn_ptr ( sig) ,
154
+ tupled_upvars_ty,
155
+ } ,
156
+ ) ;
162
157
163
- let closure_type = self . tcx . mk_closure ( expr_def_id. to_def_id ( ) , substs) ;
158
+ let closure_type = self . tcx . mk_closure ( expr_def_id. to_def_id ( ) , closure_substs . substs ) ;
164
159
165
160
debug ! ( "check_closure: expr.hir_id={:?} closure_type={:?}" , expr. hir_id, closure_type) ;
166
161
0 commit comments