@@ -32,59 +32,62 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
3232 decl : & ast:: FnDecl ,
3333 body : & ast:: Block ,
3434 expected : Expectation < ' tcx > ) {
35+ debug ! ( "check_expr_closure(expr={},expected={})" ,
36+ expr. repr( fcx. tcx( ) ) ,
37+ expected. repr( fcx. tcx( ) ) ) ;
38+
3539 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+ }
4762 }
4863
4964 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) ;
5176 }
5277 }
5378}
5479
5580fn check_unboxed_closure < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
5681 expr : & ast:: Expr ,
57- kind : ast :: UnboxedClosureKind ,
82+ kind : ty :: UnboxedClosureKind ,
5883 decl : & ast:: FnDecl ,
5984 body : & ast:: Block ,
60- expected : Expectation < ' tcx > ) {
85+ expected_sig : Option < ty :: FnSig < ' tcx > > ) {
6186 let expr_def_id = ast_util:: local_def ( expr. id ) ;
6287
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( ) ) ) ;
8891
8992 let mut fn_ty = astconv:: ty_of_closure (
9093 fcx,
@@ -130,12 +133,6 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
130133 // the `unboxed_closures` table.
131134 fn_ty. sig . inputs = vec ! [ ty:: mk_tup( fcx. tcx( ) , fn_ty. sig. inputs) ] ;
132135
133- let kind = match kind {
134- ast:: FnUnboxedClosureKind => ty:: FnUnboxedClosureKind ,
135- ast:: FnMutUnboxedClosureKind => ty:: FnMutUnboxedClosureKind ,
136- ast:: FnOnceUnboxedClosureKind => ty:: FnOnceUnboxedClosureKind ,
137- } ;
138-
139136 debug ! ( "unboxed_closure for {} --> sig={} kind={}" ,
140137 expr_def_id. repr( fcx. tcx( ) ) ,
141138 fn_ty. sig. repr( fcx. tcx( ) ) ,
@@ -152,10 +149,23 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
152149 . insert ( expr_def_id, unboxed_closure) ;
153150}
154151
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 ) >
159169{
160170 match expected_ty. sty {
161171 ty:: ty_trait( ref object_type) => {
0 commit comments