1010use rustc_index:: vec:: Idx ;
1111use rustc_infer:: infer:: LateBoundRegionConversionTime ;
1212use rustc_middle:: mir:: * ;
13- use rustc_middle:: ty:: Ty ;
13+ use rustc_middle:: ty:: { self , Ty } ;
1414use rustc_span:: Span ;
1515
1616use crate :: universal_regions:: UniversalRegions ;
1717
1818use super :: { Locations , TypeChecker } ;
1919
2020impl < ' 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+
2167 #[ instrument( skip( self , body, universal_regions) , level = "debug" ) ]
2268 pub ( super ) fn equate_inputs_and_outputs (
2369 & mut self ,
@@ -31,39 +77,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
3177 debug ! ( ?normalized_output_ty) ;
3278 debug ! ( ?normalized_input_tys) ;
3379
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-
6780 // Equate expected input tys with those in the MIR.
6881 for ( argument_index, & normalized_input_ty) in normalized_input_tys. iter ( ) . enumerate ( ) {
6982 if argument_index + 1 >= body. local_decls . len ( ) {
@@ -86,28 +99,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8699 ) ;
87100 }
88101
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-
111102 debug ! (
112103 "equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}" ,
113104 body. yield_ty( ) ,
@@ -153,29 +144,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
153144 terr
154145 ) ;
155146 } ;
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- }
179147 }
180148
181149 #[ instrument( skip( self ) , level = "debug" ) ]
0 commit comments