forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Consume once fns when calling them (rust-lang#2549).
- Loading branch information
Showing
1 changed file
with
22 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -183,6 +183,7 @@ struct VisitContext { | |
move_maps: MoveMaps | ||
} | ||
|
||
#[deriving(Eq)] | ||
enum UseMode { | ||
Move, // This value or something owned by it is moved. | ||
Read // Read no matter what the type. | ||
|
@@ -335,7 +336,27 @@ impl VisitContext { | |
} | ||
|
||
expr_call(callee, ref args, _) => { // callee(args) | ||
self.use_expr(callee, Read, visitor); | ||
// Figure out whether the called function is consumed. | ||
let mode = match ty::get(ty::expr_ty(self.tcx, callee)).sty { | ||
ty::ty_closure(ref cty) => { | ||
match cty.onceness { | ||
Once => Move, | ||
Many => Read, | ||
} | ||
}, | ||
ty::ty_bare_fn(*) => Read, | ||
ref x => | ||
self.tcx.sess.span_bug(callee.span, | ||
fmt!("non-function type in moves for expr_call: %?", x)), | ||
}; | ||
// Note we're not using consume_expr, which uses type_moves_by_default | ||
// to determine the mode, for this. The reason is that while stack | ||
// closures should be noncopyable, they shouldn't move by default; | ||
// calling a closure should only consume it if it's once. | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
bblum
Author
Owner
|
||
if mode == Move { | ||
self.move_maps.moves_map.insert(callee.id); | ||
} | ||
self.use_expr(callee, mode, visitor); | ||
self.use_fn_args(callee.id, *args, visitor); | ||
} | ||
|
||
|
I don't quite understand this comment.
type_moves_by_default
should be true (and is true, afaik) for once closures. If it were not true, one could copy once closures, which would tend to defeat the purpose of them. So it seems like you could invoke consume if once or use(read) if many, which is how the rest of the code works.