Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
549bd55
resurrect research paper list #24004
Apr 9, 2015
c3aa057
Add regression test for #19097
aturon Apr 9, 2015
644a75e
Fix `borrow` docs
apasel422 Apr 9, 2015
69f63e9
Indicate keyword in doc comment is code-like
frewsxcv Apr 9, 2015
8578fee
Don't use skolemized parameters but rather fresh variables in
nikomatsakis Apr 9, 2015
9eb8528
Copyediting for 'variable bindings'
steveklabnik Apr 9, 2015
bf88539
TRPL: new introduction
steveklabnik Apr 9, 2015
7bb0cd7
Write the 'primitive types' section of TRPL
steveklabnik Apr 9, 2015
2a88b79
Add tests for E-needstest issues
lgrz Apr 10, 2015
16574e3
Replace the use of the rather randomly named boolean `custom` to mean
nikomatsakis Apr 9, 2015
5156b3a
Modify the codemap code to use more slices and to information about
nikomatsakis Apr 9, 2015
906a972
Add a new `span_suggestion` infrastructure. This lets you edit a snippet
nikomatsakis Apr 9, 2015
e313b33
Improve error message where a closure escapes fn while trying to borrow
nikomatsakis Apr 9, 2015
e66569e
Fix pow docs to not use Int
steveklabnik Apr 10, 2015
cdce32f
Changed the wording of the documentation for the insert method for Ve…
djallen89 Apr 10, 2015
c2fa1f7
Doc: remove a "safety note" made obsolete by dropck for TypedArena
SimonSapin Apr 10, 2015
7bf1da1
s/Panicks/Panics/
apasel422 Apr 10, 2015
288b1c9
Add examples for Convert
steveklabnik Apr 6, 2015
9e68d23
Fix mistake in documentation
xamgore Apr 10, 2015
c7697ee
mod.rs docs fix
White-Oak Apr 10, 2015
b4c49ba
mod.rs docs fix - for floats
White-Oak Apr 10, 2015
f01dbf2
More editing work on TRPL
steveklabnik Apr 9, 2015
df8d266
Rollup merge of #24121 - steveklabnik:gh24107, r=steveklabnik
steveklabnik Apr 10, 2015
dcc70bc
Rollup merge of #24234 - thiagooak:academic-research, r=steveklabnik
steveklabnik Apr 10, 2015
2b1c5c0
Rollup merge of #24236 - aturon:issue-19097, r=alexcrichton
steveklabnik Apr 10, 2015
019d358
Rollup merge of #24239 - steveklabnik:editing_pass, r=steveklabnik
steveklabnik Apr 10, 2015
702149c
Rollup merge of #24240 - apasel422:patch-1, r=aturon
steveklabnik Apr 10, 2015
c6ec2a2
Rollup merge of #24242 - nikomatsakis:escaping-closure-error-message,…
steveklabnik Apr 10, 2015
003ba7e
Rollup merge of #24243 - frewsxcv:patch-13, r=steveklabnik
steveklabnik Apr 10, 2015
3223009
Rollup merge of #24244 - steveklabnik:more_editing, r=steveklabnik
steveklabnik Apr 10, 2015
e0f4d92
Rollup merge of #24245 - nikomatsakis:issue-24241-coherence-failure, …
steveklabnik Apr 10, 2015
21eb4a4
Rollup merge of #24247 - steveklabnik:update_variable_bindings, r=huonw
steveklabnik Apr 10, 2015
d749328
Rollup merge of #24253 - steveklabnik:doc_primitive_types, r=alexcric…
steveklabnik Apr 10, 2015
bbad292
Rollup merge of #24259 - lstat:needstest, r=alexcrichton
steveklabnik Apr 10, 2015
b6ec2d2
Rollup merge of #24274 - steveklabnik:fix_pow_docs, r=nikomatsakis
steveklabnik Apr 10, 2015
e303a7e
Rollup merge of #24279 - libfud:vec_insertion_docs, r=steveklabnik
steveklabnik Apr 10, 2015
8ca00a4
Rollup merge of #24282 - SimonSapin:patch-6, r=pnkfelix
steveklabnik Apr 10, 2015
bdcf5da
Rollup merge of #24283 - apasel422:patch-2, r=alexcrichton
steveklabnik Apr 10, 2015
a7c5f51
Rollup merge of #24291 - xamgore:patch-1, r=steveklabnik
steveklabnik Apr 10, 2015
6a6c02a
Rollup merge of #24298 - White-Oak:master, r=alexcrichton
steveklabnik Apr 10, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Improve error message where a closure escapes fn while trying to borrow
from the current fn. Employ the new `span_suggestion` to show how you
can use `move`.
  • Loading branch information
nikomatsakis committed Apr 10, 2015
commit e313b3334b82676bbdcf90cd48f08b87fc0d03da
62 changes: 53 additions & 9 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,16 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}

pub fn report(&self, err: BckError<'tcx>) {
// Catch and handle some particular cases.
match (&err.code, &err.cause) {
(&err_out_of_scope(ty::ReScope(_), ty::ReStatic), &euv::ClosureCapture(span)) |
(&err_out_of_scope(ty::ReScope(_), ty::ReFree(..)), &euv::ClosureCapture(span)) => {
return self.report_out_of_scope_escaping_closure_capture(&err, span);
}
_ => { }
}

// General fallback.
self.span_err(
err.span,
&self.bckerr_to_string(&err));
Expand Down Expand Up @@ -796,16 +806,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
format!("{} does not live long enough", msg)
}
err_borrowed_pointer_too_short(..) => {
let descr = match opt_loan_path(&err.cmt) {
Some(lp) => {
format!("`{}`", self.loan_path_to_string(&*lp))
}
None => self.cmt_to_string(&*err.cmt),
};

let descr = self.cmt_to_path_or_string(&err.cmt);
format!("lifetime of {} is too short to guarantee \
its contents can be safely reborrowed",
descr)
its contents can be safely reborrowed",
descr)
}
}
}
Expand Down Expand Up @@ -888,6 +892,39 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
}

fn report_out_of_scope_escaping_closure_capture(&self,
err: &BckError<'tcx>,
capture_span: Span)
{
let cmt_path_or_string = self.cmt_to_path_or_string(&err.cmt);

span_err!(
self.tcx.sess, err.span, E0373,
"closure may outlive the current function, \
but it borrows {}, \
which is owned by the current function",
cmt_path_or_string);

self.tcx.sess.span_note(
capture_span,
&format!("{} is borrowed here",
cmt_path_or_string));

let suggestion =
match self.tcx.sess.codemap().span_to_snippet(err.span) {
Ok(string) => format!("move {}", string),
Err(_) => format!("move |<args>| <body>")
};

self.tcx.sess.span_suggestion(
err.span,
&format!("to force the closure to take ownership of {} \
(and any other referenced variables), \
use the `move` keyword, as shown:",
cmt_path_or_string),
suggestion);
}

pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
let code = err.code;
match code {
Expand Down Expand Up @@ -1035,6 +1072,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
pub fn cmt_to_string(&self, cmt: &mc::cmt_<'tcx>) -> String {
cmt.descriptive_string(self.tcx)
}

pub fn cmt_to_path_or_string(&self, cmt: &mc::cmt<'tcx>) -> String {
match opt_loan_path(cmt) {
Some(lp) => format!("`{}`", self.loan_path_to_string(&lp)),
None => self.cmt_to_string(cmt),
}
}
}

fn is_statement_scope(tcx: &ty::ctxt, region: ty::Region) -> bool {
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_borrowck/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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.

#![allow(non_snake_case)]

register_diagnostics! {
E0373 // closure may outlive current fn, but it borrows {}, which is owned by current fn
}

__build_diagnostic_array! { DIAGNOSTICS }
4 changes: 4 additions & 0 deletions src/librustc_borrowck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub use borrowck::check_crate;
pub use borrowck::build_borrowck_dataflow_data_for_fn;
pub use borrowck::FnPartsWithCFG;

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

mod borrowck;

pub mod graphviz;
25 changes: 25 additions & 0 deletions src/test/compile-fail/borrowck-escaping-closure-error-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.

use std::thread::spawn;

// Test that we give a custom error (E0373) for the case where a
// closure is escaping current frame, and offer a suggested code edit.
// I refrained from including the precise message here, but the
// original text as of the time of this writing is:
//
// closure may outlive the current function, but it borrows `books`,
// which is owned by the current function

fn main() {
let mut books = vec![1,2,3];
spawn(|| books.push(4));
//~^ ERROR E0373
}
25 changes: 25 additions & 0 deletions src/test/compile-fail/borrowck-escaping-closure-error-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.

// Test that we give a custom error (E0373) for the case where a
// closure is escaping current frame, and offer a suggested code edit.
// I refrained from including the precise message here, but the
// original text as of the time of this writing is:
//
// closure may outlive the current function, but it borrows `books`,
// which is owned by the current function

fn foo<'a>(x: &'a i32) -> Box<FnMut()+'a> {
let mut books = vec![1,2,3];
Box::new(|| books.push(4))
//~^ ERROR E0373
}

fn main() { }
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-16747.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ trait Collection { fn len(&self) -> usize; }

struct List<'a, T: ListItem<'a>> {
//~^ ERROR the parameter type `T` may not live long enough
//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
//~| HELP consider adding an explicit lifetime bound
//~| NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
slice: &'a [T]
}
//~^ HELP consider adding an explicit lifetime bound
impl<'a, T: ListItem<'a>> Collection for List<'a, T> {
fn len(&self) -> usize {
0
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-4335.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn id<T>(t: T) -> T { t }
fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
id(Box::new(|| *v))
//~^ ERROR `v` does not live long enough
//~^ ERROR E0373
//~| ERROR cannot move out of borrowed content
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/regions-nested-fns-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn ignore<F>(_f: F) where F: for<'z> FnOnce(&'z isize) -> &'z isize {}
fn nested() {
let y = 3;
ignore(
|z| { //~ ERROR `y` does not live long enough
|z| { //~ ERROR E0373
if false { &y } else { z }
});
}
Expand Down