提交 f60a7c47 编写于 作者: N Niko Matsakis

Fix regionck to consider bounds on a proc when capturing variables

上级 b5165321
......@@ -1534,6 +1534,12 @@ fn adjust_borrow_kind_for_assignment_lhs(rcx: &Rcx,
fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx,
cmt: mc::cmt) {
/*!
* Indicates that `cmt` is being directly mutated (e.g., assigned
* to). If cmt contains any by-ref upvars, this implies that
* those upvars must be borrowed using an `&mut` borow.
*/
let mut cmt = cmt;
loop {
debug!("adjust_upvar_borrow_kind_for_mut(cmt={})",
......
......@@ -583,6 +583,19 @@ fn report_concrete_failure(&self,
sub,
"");
}
infer::ProcCapture(span, id) => {
self.tcx.sess.span_err(
span,
format!("captured variable `{}` must be 'static \
to be captured in a proc",
ty::local_var_name_str(self.tcx, id).get())
.as_slice());
note_and_explain_region(
self.tcx,
"captured variable is only valid for ",
sup,
"");
}
infer::IndexSlice(span) => {
self.tcx.sess.span_err(span,
"index of slice outside its lifetime");
......@@ -1423,11 +1436,11 @@ fn report_inference_failure(&self,
bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
}
infer::EarlyBoundRegion(_, name) => {
format!(" for lifetime parameter `{}",
format!(" for lifetime parameter `{}`",
token::get_name(name).get())
}
infer::BoundRegionInCoherence(name) => {
format!(" for lifetime parameter `{} in coherence check",
format!(" for lifetime parameter `{}` in coherence check",
token::get_name(name).get())
}
infer::UpvarRegion(ref upvar_id, _) => {
......@@ -1528,6 +1541,15 @@ fn note_region_origin(&self, origin: &SubregionOrigin) {
self.tcx,
id).get().to_string()).as_slice());
}
infer::ProcCapture(span, id) => {
self.tcx.sess.span_note(
span,
format!("...so that captured variable `{}` \
is 'static",
ty::local_var_name_str(
self.tcx,
id).get()).as_slice());
}
infer::IndexSlice(span) => {
self.tcx.sess.span_note(
span,
......@@ -1571,8 +1593,8 @@ fn note_region_origin(&self, origin: &SubregionOrigin) {
infer::AutoBorrow(span) => {
self.tcx.sess.span_note(
span,
"...so that reference is valid \
at the time of implicit borrow");
"...so that auto-reference is valid \
at the time of borrow");
}
infer::ExprTypeIsNotInScope(t, span) => {
self.tcx.sess.span_note(
......
......@@ -161,6 +161,9 @@ pub enum SubregionOrigin {
// Closure bound must not outlive captured free variables
FreeVariable(Span, ast::NodeId),
// Proc upvars must be 'static
ProcCapture(Span, ast::NodeId),
// Index into slice must be within its lifetime
IndexSlice(Span),
......@@ -933,6 +936,7 @@ pub fn span(&self) -> Span {
InvokeClosure(a) => a,
DerefPointer(a) => a,
FreeVariable(a, _) => a,
ProcCapture(a, _) => a,
IndexSlice(a) => a,
RelateObjectBound(a) => a,
RelateProcBound(a, _, _) => a,
......@@ -972,6 +976,9 @@ fn repr(&self, tcx: &ty::ctxt) -> String {
FreeVariable(a, b) => {
format!("FreeVariable({}, {})", a.repr(tcx), b)
}
ProcCapture(a, b) => {
format!("ProcCapture({}, {})", a.repr(tcx), b)
}
IndexSlice(a) => {
format!("IndexSlice({})", a.repr(tcx))
}
......
// Copyright 2014 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.
// Test that, when a variable of type `&T` is captured inside a proc,
// we correctly infer/require that its lifetime is 'static.
fn foo(_p: proc():'static) { }
static i: int = 3;
fn capture_local() {
let x = 3i;
let y = &x; //~ ERROR `x` does not live long enough
foo(proc() {
let _a = *y;
});
}
fn capture_static() {
// Legal because &i can have static lifetime:
let y = &i;
foo(proc() {
let _a = *y;
});
}
fn main() { }
// Copyright 2014 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 the 'static bound on a proc influences lifetimes of
// region variables contained within (otherwise, region inference will
// give `x` a very short lifetime).
static i: uint = 3;
fn foo(_: proc():'static) {}
fn read(_: uint) { }
pub fn main() {
let x = &i;
foo(proc() {
read(*x);
});
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册