@@ -183,6 +183,7 @@ struct VisitContext {
183183 move_maps : MoveMaps
184184}
185185
186+ #[ deriving( Eq ) ]
186187enum UseMode {
187188 Move , // This value or something owned by it is moved.
188189 Read // Read no matter what the type.
@@ -335,7 +336,27 @@ impl VisitContext {
335336 }
336337
337338 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) ;
339360 self . use_fn_args( callee. id, * args, visitor) ;
340361 }
341362
0 commit comments