10
10
use rustc_index:: vec:: Idx ;
11
11
use rustc_infer:: infer:: LateBoundRegionConversionTime ;
12
12
use rustc_middle:: mir:: * ;
13
- use rustc_middle:: ty:: Ty ;
13
+ use rustc_middle:: ty:: { self , Ty } ;
14
14
use rustc_span:: Span ;
15
15
16
16
use crate :: universal_regions:: UniversalRegions ;
17
17
18
18
use super :: { Locations , TypeChecker } ;
19
19
20
20
impl < ' a , ' tcx > TypeChecker < ' a , ' tcx > {
21
+ /// Check explicit closure signature annotation,
22
+ /// e.g., `|x: FxHashMap<_, &'static u32>| ...`.
23
+ #[ instrument( skip( self , body) , level = "debug" ) ]
24
+ pub ( super ) fn check_signature_annotation ( & mut self , body : & Body < ' tcx > ) {
25
+ let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
26
+ if !self . tcx ( ) . is_closure ( mir_def_id. to_def_id ( ) ) {
27
+ return ;
28
+ }
29
+ let Some ( user_provided_poly_sig) =
30
+ self . tcx ( ) . typeck ( mir_def_id) . user_provided_sigs . get ( & mir_def_id)
31
+ else {
32
+ return ;
33
+ } ;
34
+
35
+ // Instantiate the canonicalized variables from user-provided signature
36
+ // (e.g., the `_` in the code above) with fresh variables.
37
+ // Then replace the bound items in the fn sig with fresh variables,
38
+ // so that they represent the view from "inside" the closure.
39
+ let user_provided_sig = self
40
+ . instantiate_canonical_with_fresh_inference_vars ( body. span , & user_provided_poly_sig) ;
41
+ let user_provided_sig = self . infcx . replace_bound_vars_with_fresh_vars (
42
+ body. span ,
43
+ LateBoundRegionConversionTime :: FnCall ,
44
+ user_provided_sig,
45
+ ) ;
46
+
47
+ for ( & user_ty, arg_decl) in user_provided_sig. inputs ( ) . iter ( ) . zip (
48
+ // In MIR, closure args begin with an implicit `self`. Skip it!
49
+ body. args_iter ( ) . skip ( 1 ) . map ( |local| & body. local_decls [ local] ) ,
50
+ ) {
51
+ self . ascribe_user_type_skip_wf (
52
+ arg_decl. ty ,
53
+ ty:: UserType :: Ty ( user_ty) ,
54
+ arg_decl. source_info . span ,
55
+ ) ;
56
+ }
57
+
58
+ // If the user explicitly annotated the output type, enforce it.
59
+ let output_decl = & body. local_decls [ RETURN_PLACE ] ;
60
+ self . ascribe_user_type_skip_wf (
61
+ output_decl. ty ,
62
+ ty:: UserType :: Ty ( user_provided_sig. output ( ) ) ,
63
+ output_decl. source_info . span ,
64
+ ) ;
65
+ }
66
+
21
67
#[ instrument( skip( self , body, universal_regions) , level = "debug" ) ]
22
68
pub ( super ) fn equate_inputs_and_outputs (
23
69
& mut self ,
@@ -31,39 +77,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
31
77
debug ! ( ?normalized_output_ty) ;
32
78
debug ! ( ?normalized_input_tys) ;
33
79
34
- let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
35
-
36
- // If the user explicitly annotated the input types, extract
37
- // those.
38
- //
39
- // e.g., `|x: FxHashMap<_, &'static u32>| ...`
40
- let user_provided_sig = if !self . tcx ( ) . is_closure ( mir_def_id. to_def_id ( ) ) {
41
- None
42
- } else {
43
- let typeck_results = self . tcx ( ) . typeck ( mir_def_id) ;
44
-
45
- typeck_results. user_provided_sigs . get ( & mir_def_id) . map ( |user_provided_poly_sig| {
46
- // Instantiate the canonicalized variables from
47
- // user-provided signature (e.g., the `_` in the code
48
- // above) with fresh variables.
49
- let poly_sig = self . instantiate_canonical_with_fresh_inference_vars (
50
- body. span ,
51
- & user_provided_poly_sig,
52
- ) ;
53
-
54
- // Replace the bound items in the fn sig with fresh
55
- // variables, so that they represent the view from
56
- // "inside" the closure.
57
- self . infcx . replace_bound_vars_with_fresh_vars (
58
- body. span ,
59
- LateBoundRegionConversionTime :: FnCall ,
60
- poly_sig,
61
- )
62
- } )
63
- } ;
64
-
65
- debug ! ( ?normalized_input_tys, ?body. local_decls) ;
66
-
67
80
// Equate expected input tys with those in the MIR.
68
81
for ( argument_index, & normalized_input_ty) in normalized_input_tys. iter ( ) . enumerate ( ) {
69
82
if argument_index + 1 >= body. local_decls . len ( ) {
@@ -86,28 +99,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
86
99
) ;
87
100
}
88
101
89
- if let Some ( user_provided_sig) = user_provided_sig {
90
- for ( argument_index, & user_provided_input_ty) in
91
- user_provided_sig. inputs ( ) . iter ( ) . enumerate ( )
92
- {
93
- // In MIR, closures begin an implicit `self`, so
94
- // argument N is stored in local N+2.
95
- let local = Local :: new ( argument_index + 2 ) ;
96
- let mir_input_ty = body. local_decls [ local] . ty ;
97
- let mir_input_span = body. local_decls [ local] . source_info . span ;
98
-
99
- // If the user explicitly annotated the input types, enforce those.
100
- let user_provided_input_ty =
101
- self . normalize ( user_provided_input_ty, Locations :: All ( mir_input_span) ) ;
102
-
103
- self . equate_normalized_input_or_output (
104
- user_provided_input_ty,
105
- mir_input_ty,
106
- mir_input_span,
107
- ) ;
108
- }
109
- }
110
-
111
102
debug ! (
112
103
"equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}" ,
113
104
body. yield_ty( ) ,
@@ -153,29 +144,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
153
144
terr
154
145
) ;
155
146
} ;
156
-
157
- // If the user explicitly annotated the output types, enforce those.
158
- // Note that this only happens for closures.
159
- if let Some ( user_provided_sig) = user_provided_sig {
160
- let user_provided_output_ty = user_provided_sig. output ( ) ;
161
- let user_provided_output_ty =
162
- self . normalize ( user_provided_output_ty, Locations :: All ( output_span) ) ;
163
- if let Err ( err) = self . eq_types (
164
- user_provided_output_ty,
165
- mir_output_ty,
166
- Locations :: All ( output_span) ,
167
- ConstraintCategory :: BoringNoLocation ,
168
- ) {
169
- span_mirbug ! (
170
- self ,
171
- Location :: START ,
172
- "equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`" ,
173
- mir_output_ty,
174
- user_provided_output_ty,
175
- err
176
- ) ;
177
- }
178
- }
179
147
}
180
148
181
149
#[ instrument( skip( self ) , level = "debug" ) ]
0 commit comments