@@ -32,59 +32,62 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
32
32
decl : & ast:: FnDecl ,
33
33
body : & ast:: Block ,
34
34
expected : Expectation < ' tcx > ) {
35
+ debug ! ( "check_expr_closure(expr={},expected={})" ,
36
+ expr. repr( fcx. tcx( ) ) ,
37
+ expected. repr( fcx. tcx( ) ) ) ;
38
+
35
39
match opt_kind {
36
- None => { // old-school boxed closure
37
- let region = astconv:: opt_ast_region_to_region ( fcx,
38
- fcx. infcx ( ) ,
39
- expr. span ,
40
- & None ) ;
41
- check_boxed_closure ( fcx,
42
- expr,
43
- ty:: RegionTraitStore ( region, ast:: MutMutable ) ,
44
- decl,
45
- body,
46
- expected) ;
40
+ None => {
41
+ // If users didn't specify what sort of closure they want,
42
+ // examine the expected type. For now, if we see explicit
43
+ // evidence than an unboxed closure is desired, we'll use
44
+ // that, otherwise we'll fall back to boxed closures.
45
+ match deduce_unboxed_closure_expectations_from_expectation ( fcx, expected) {
46
+ None => { // doesn't look like an unboxed closure
47
+ let region = astconv:: opt_ast_region_to_region ( fcx,
48
+ fcx. infcx ( ) ,
49
+ expr. span ,
50
+ & None ) ;
51
+ check_boxed_closure ( fcx,
52
+ expr,
53
+ ty:: RegionTraitStore ( region, ast:: MutMutable ) ,
54
+ decl,
55
+ body,
56
+ expected) ;
57
+ }
58
+ Some ( ( sig, kind) ) => {
59
+ check_unboxed_closure ( fcx, expr, kind, decl, body, Some ( sig) ) ;
60
+ }
61
+ }
47
62
}
48
63
49
64
Some ( kind) => {
50
- check_unboxed_closure ( fcx, expr, kind, decl, body, expected)
65
+ let kind = match kind {
66
+ ast:: FnUnboxedClosureKind => ty:: FnUnboxedClosureKind ,
67
+ ast:: FnMutUnboxedClosureKind => ty:: FnMutUnboxedClosureKind ,
68
+ ast:: FnOnceUnboxedClosureKind => ty:: FnOnceUnboxedClosureKind ,
69
+ } ;
70
+
71
+ let expected_sig =
72
+ deduce_unboxed_closure_expectations_from_expectation ( fcx, expected)
73
+ . map ( |t| t. 0 ) ;
74
+
75
+ check_unboxed_closure ( fcx, expr, kind, decl, body, expected_sig) ;
51
76
}
52
77
}
53
78
}
54
79
55
80
fn check_unboxed_closure < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
56
81
expr : & ast:: Expr ,
57
- kind : ast :: UnboxedClosureKind ,
82
+ kind : ty :: UnboxedClosureKind ,
58
83
decl : & ast:: FnDecl ,
59
84
body : & ast:: Block ,
60
- expected : Expectation < ' tcx > ) {
85
+ expected_sig : Option < ty :: FnSig < ' tcx > > ) {
61
86
let expr_def_id = ast_util:: local_def ( expr. id ) ;
62
87
63
- let expected_sig_and_kind = match expected. resolve ( fcx) {
64
- NoExpectation => None ,
65
- ExpectCastableToType ( t) | ExpectHasType ( t) => {
66
- deduce_unboxed_closure_expectations_from_expected_type ( fcx, t)
67
- }
68
- } ;
69
-
70
- let ( expected_sig, expected_kind) = match expected_sig_and_kind {
71
- None => ( None , None ) ,
72
- Some ( ( sig, kind) ) => {
73
- // Avoid accidental capture of bound regions by renaming
74
- // them to fresh names, basically.
75
- let sig =
76
- ty:: replace_late_bound_regions (
77
- fcx. tcx ( ) ,
78
- & sig,
79
- |_, debruijn| fcx. inh . infcx . fresh_bound_region ( debruijn) ) . 0 ;
80
- ( Some ( sig) , Some ( kind) )
81
- }
82
- } ;
83
-
84
- debug ! ( "check_unboxed_closure expected={} expected_sig={} expected_kind={}" ,
85
- expected. repr( fcx. tcx( ) ) ,
86
- expected_sig. repr( fcx. tcx( ) ) ,
87
- expected_kind) ;
88
+ debug ! ( "check_unboxed_closure kind={} expected_sig={}" ,
89
+ kind,
90
+ expected_sig. repr( fcx. tcx( ) ) ) ;
88
91
89
92
let mut fn_ty = astconv:: ty_of_closure (
90
93
fcx,
@@ -130,12 +133,6 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
130
133
// the `unboxed_closures` table.
131
134
fn_ty. sig . inputs = vec ! [ ty:: mk_tup( fcx. tcx( ) , fn_ty. sig. inputs) ] ;
132
135
133
- let kind = match kind {
134
- ast:: FnUnboxedClosureKind => ty:: FnUnboxedClosureKind ,
135
- ast:: FnMutUnboxedClosureKind => ty:: FnMutUnboxedClosureKind ,
136
- ast:: FnOnceUnboxedClosureKind => ty:: FnOnceUnboxedClosureKind ,
137
- } ;
138
-
139
136
debug ! ( "unboxed_closure for {} --> sig={} kind={}" ,
140
137
expr_def_id. repr( fcx. tcx( ) ) ,
141
138
fn_ty. sig. repr( fcx. tcx( ) ) ,
@@ -152,10 +149,23 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
152
149
. insert ( expr_def_id, unboxed_closure) ;
153
150
}
154
151
155
- fn deduce_unboxed_closure_expectations_from_expected_type < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
156
- expected_ty : Ty < ' tcx > )
157
- -> Option < ( ty:: FnSig < ' tcx > ,
158
- ty:: UnboxedClosureKind ) >
152
+ fn deduce_unboxed_closure_expectations_from_expectation < ' a , ' tcx > (
153
+ fcx : & FnCtxt < ' a , ' tcx > ,
154
+ expected : Expectation < ' tcx > )
155
+ -> Option < ( ty:: FnSig < ' tcx > , ty:: UnboxedClosureKind ) >
156
+ {
157
+ match expected. resolve ( fcx) {
158
+ NoExpectation => None ,
159
+ ExpectCastableToType ( t) | ExpectHasType ( t) => {
160
+ deduce_unboxed_closure_expectations_from_expected_type ( fcx, t)
161
+ }
162
+ }
163
+ }
164
+
165
+ fn deduce_unboxed_closure_expectations_from_expected_type < ' a , ' tcx > (
166
+ fcx : & FnCtxt < ' a , ' tcx > ,
167
+ expected_ty : Ty < ' tcx > )
168
+ -> Option < ( ty:: FnSig < ' tcx > , ty:: UnboxedClosureKind ) >
159
169
{
160
170
match expected_ty. sty {
161
171
ty:: ty_trait( ref object_type) => {
0 commit comments