about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-08-31 22:37:05 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-10-01 15:22:57 +0300
commitc01e0502e7f993520e516b3a77ab7f459e21456d (patch)
treec0e30381b2f5981a5a07efa9903b3c11ab4b027d
parent78edd4f3a0c614c8deab030351ece9baade848cc (diff)
downloadrust-c01e0502e7f993520e516b3a77ab7f459e21456d.tar.gz
rust-c01e0502e7f993520e516b3a77ab7f459e21456d.zip
check upvars in closures that are in statics
Fixes #27890
Fixes #28099
Fixes #28113
-rw-r--r--src/librustc_typeck/check/mod.rs7
-rw-r--r--src/librustc_typeck/check/upvar.rs14
-rw-r--r--src/test/compile-fail/borrowck-in-static.rs22
-rw-r--r--src/test/compile-fail/issue-28113.rs15
-rw-r--r--src/test/run-pass/issue-27890.rs16
5 files changed, 73 insertions, 1 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e62f5b82e7a..4069cbb170c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4124,8 +4124,13 @@ fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     check_expr_with_hint(fcx, e, declty);
     demand::coerce(fcx, e.span, declty, e);
-    fcx.select_all_obligations_or_error();
+
+    fcx.select_all_obligations_and_apply_defaults();
+    upvar::closure_analyze_const(&fcx, e);
+    fcx.select_obligations_where_possible();
     fcx.check_casts();
+    fcx.select_all_obligations_or_error();
+
     regionck::regionck_expr(fcx, e);
     writeback::resolve_type_vars_in_expr(fcx, e);
 }
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index f9f711a1a63..10d7c4620e7 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -73,6 +73,20 @@ pub fn closure_analyze_fn(fcx: &FnCtxt,
     assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty());
 }
 
+pub fn closure_analyze_const(fcx: &FnCtxt,
+                             body: &hir::Expr)
+{
+    let mut seed = SeedBorrowKind::new(fcx);
+    seed.visit_expr(body);
+    let closures_with_inferred_kinds = seed.closures_with_inferred_kinds;
+
+    let mut adjust = AdjustBorrowKind::new(fcx, &closures_with_inferred_kinds);
+    adjust.visit_expr(body);
+
+    // it's our job to process these.
+    assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty());
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // SEED BORROW KIND
 
diff --git a/src/test/compile-fail/borrowck-in-static.rs b/src/test/compile-fail/borrowck-in-static.rs
new file mode 100644
index 00000000000..16b0e8638de
--- /dev/null
+++ b/src/test/compile-fail/borrowck-in-static.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// check that borrowck looks inside consts/statics
+
+static FN : &'static (Fn() -> (Box<Fn()->Box<i32>>) + Sync) = &|| {
+    let x = Box::new(0);
+    Box::new(|| x) //~ ERROR cannot move out of captured outer variable
+};
+
+fn main() {
+    let f = (FN)();
+    f();
+    f();
+}
diff --git a/src/test/compile-fail/issue-28113.rs b/src/test/compile-fail/issue-28113.rs
new file mode 100644
index 00000000000..c5c4fb07017
--- /dev/null
+++ b/src/test/compile-fail/issue-28113.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const X: u8 =
+    || -> u8 { 5 }() //~ ERROR function calls in constants are limited
+;
+
+fn main() {}
diff --git a/src/test/run-pass/issue-27890.rs b/src/test/run-pass/issue-27890.rs
new file mode 100644
index 00000000000..a33882a8331
--- /dev/null
+++ b/src/test/run-pass/issue-27890.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static PLUS_ONE: &'static (Fn(i32) -> i32 + Sync) = (&|x: i32| { x + 1 })
+    as &'static (Fn(i32) -> i32 + Sync);
+
+fn main() {
+    assert_eq!(PLUS_ONE(2), 3);
+}