Skip to content

Commit 5b0c8ac

Browse files
author
Jorge Aparicio
committed
typeck: boxed closures can't capture by value
closes #19141 closes #20193 closes #20228
1 parent c43efee commit 5b0c8ac

File tree

7 files changed

+96
-3
lines changed

7 files changed

+96
-3
lines changed

src/librustc_typeck/check/closure.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ use middle::ty::{mod, Ty};
1919
use rscope::RegionScope;
2020
use syntax::abi;
2121
use syntax::ast;
22+
use syntax::ast::CaptureClause::*;
2223
use syntax::ast_util;
2324
use util::ppaux::Repr;
2425

2526
pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2627
expr: &ast::Expr,
28+
capture: ast::CaptureClause,
2729
opt_kind: Option<ast::UnboxedClosureKind>,
2830
decl: &ast::FnDecl,
2931
body: &ast::Block,
@@ -48,12 +50,24 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
4850
fcx.infcx(),
4951
expr.span,
5052
&None);
53+
5154
check_boxed_closure(fcx,
5255
expr,
5356
ty::RegionTraitStore(region, ast::MutMutable),
5457
decl,
5558
body,
5659
expected);
60+
61+
match capture {
62+
CaptureByValue => {
63+
fcx.ccx.tcx.sess.span_err(
64+
expr.span,
65+
"boxed closures can't capture by value, \
66+
if you want to use an unboxed closure, \
67+
explicitly annotate its kind: e.g. `move |:|`");
68+
},
69+
CaptureByRef => {}
70+
}
5771
}
5872
Some((sig, kind)) => {
5973
check_unboxed_closure(fcx, expr, kind, decl, body, Some(sig));

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,8 +3958,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
39583958
ast::ExprMatch(ref discrim, ref arms, match_src) => {
39593959
_match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected, match_src);
39603960
}
3961-
ast::ExprClosure(_, opt_kind, ref decl, ref body) => {
3962-
closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected);
3961+
ast::ExprClosure(capture, opt_kind, ref decl, ref body) => {
3962+
closure::check_expr_closure(fcx, expr, capture, opt_kind, &**decl, &**body, expected);
39633963
}
39643964
ast::ExprBlock(ref b) => {
39653965
check_block_with_expected(fcx, &**b, expected);

src/test/compile-fail/borrowck-move-by-capture.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
pub fn main() {
1212
let bar = box 3;
1313
let _g = || {
14-
let _h = move|| -> int { *bar }; //~ ERROR cannot move out of captured outer variable
14+
let _h = move |:| -> int { *bar }; //~ ERROR cannot move out of captured outer variable
1515
};
1616
}

src/test/compile-fail/issue-19141.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let n = 0u;
13+
14+
let f = move || n += 1; //~error boxed closures can't capture by value
15+
}

src/test/compile-fail/issue-20193.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn foo(t: &mut int){
12+
println!("{}", t);
13+
}
14+
15+
fn main() {
16+
let test = 10;
17+
18+
let h = move || { //~error boxed closures can't capture by value
19+
let mut r = &mut test.clone();
20+
foo(r);
21+
};
22+
23+
h();
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct S;
12+
13+
impl S {
14+
fn foo(&self) {
15+
let _ = move || { self }; //~error boxed closures can't capture by value
16+
}
17+
}
18+
19+
fn main() {
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct S;
12+
13+
impl S {
14+
fn foo(&self) {
15+
let _ = move || { self.foo() }; //~error boxed closures can't capture by value
16+
}
17+
}
18+
19+
fn main() {
20+
}

0 commit comments

Comments
 (0)