@@ -183,6 +183,7 @@ struct VisitContext {
183
183
move_maps : MoveMaps
184
184
}
185
185
186
+ #[ deriving( Eq ) ]
186
187
enum UseMode {
187
188
Move , // This value or something owned by it is moved.
188
189
Read // Read no matter what the type.
@@ -335,7 +336,27 @@ impl VisitContext {
335
336
}
336
337
337
338
expr_call( callee, ref args, _) => { // callee(args)
338
- self . use_expr( callee, Read , visitor) ;
339
+ // Figure out whether the called function is consumed.
340
+ let mode = match ty:: get( ty:: expr_ty( self . tcx, callee) ) . sty {
341
+ ty : : ty_closure( ref cty) => {
342
+ match cty. onceness {
343
+ Once => Move ,
344
+ Many => Read ,
345
+ }
346
+ } ,
347
+ ty:: ty_bare_fn( * ) => Read ,
348
+ ref x =>
349
+ self . tcx. sess. span_bug( callee. span,
350
+ fmt ! ( "non-function type in moves for expr_call: %?" , x) ) ,
351
+ } ;
352
+ // Note we're not using consume_expr, which uses type_moves_by_default
353
+ // to determine the mode, for this. The reason is that while stack
354
+ // closures should be noncopyable, they shouldn't move by default;
355
+ // calling a closure should only consume it if it's once.
356
+ if mode == Move {
357
+ self. move_maps. moves_map. insert( callee. id) ;
358
+ }
359
+ self. use_expr( callee, mode, visitor) ;
339
360
self . use_fn_args( callee. id, * args, visitor) ;
340
361
}
341
362
0 commit comments