auto merge of #7534 : bblum/rust/soundness-messages, r=catamorphism

This commit is contained in:
bors 2013-07-03 15:25:55 -07:00
commit 648c5e9c92
5 changed files with 55 additions and 7 deletions

View file

@ -538,12 +538,13 @@ impl BorrowckCtxt {
move_data::MoveExpr(expr) => {
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
let suggestion = move_suggestion(self.tcx, expr_ty,
"moved by default (use `copy` to override)");
self.tcx.sess.span_note(
expr.span,
fmt!("`%s` moved here because it has type `%s`, \
which is moved by default (use `copy` to override)",
fmt!("`%s` moved here because it has type `%s`, which is %s",
self.loan_path_to_str(moved_lp),
expr_ty.user_string(self.tcx)));
expr_ty.user_string(self.tcx), suggestion));
}
move_data::MovePat(pat) => {
@ -557,12 +558,28 @@ impl BorrowckCtxt {
}
move_data::Captured(expr) => {
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
let suggestion = move_suggestion(self.tcx, expr_ty,
"moved by default (make a copy and \
capture that instead to override)");
self.tcx.sess.span_note(
expr.span,
fmt!("`%s` moved into closure environment here \
because its type is moved by default \
(make a copy and capture that instead to override)",
self.loan_path_to_str(moved_lp)));
fmt!("`%s` moved into closure environment here because it \
has type `%s`, which is %s",
self.loan_path_to_str(moved_lp),
expr_ty.user_string(self.tcx), suggestion));
}
}
fn move_suggestion(tcx: ty::ctxt, ty: ty::t, default_msg: &'static str)
-> &'static str {
match ty::get(ty).sty {
ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil =>
"a non-copyable stack closure (capture it in a new closure, \
e.g. `|x| f(x)`, to override)",
_ if !ty::type_is_copyable(tcx, ty) =>
"non-copyable (perhaps you meant to use clone()?)",
_ => default_msg,
}
}
}

View file

@ -0,0 +1,31 @@
// Copyright 2013 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.
// Ensures that it's legal to create a recursive stack closure as long as
// its environment is copyable
struct R<'self> {
// This struct is needed to create the
// otherwise infinite type of a fn that
// accepts itself as argument:
c: &'self fn:Copy(&R, uint) -> uint
}
fn main() {
// Stupid version of fibonacci.
let fib: &fn:Copy(&R, uint) -> uint = |fib, x| {
if x == 0 || x == 1 {
x
} else {
(fib.c)(fib, x-1) + (fib.c)(fib, x-2)
}
};
assert!(fib(&R { c: fib }, 7) == 13);
}