Rollup merge of #28443 - GuillaumeGomez:error_codes, r=Manishearth

r? @Manishearth
This commit is contained in:
Steve Klabnik 2015-09-19 11:15:48 -04:00
commit f1473b6c00
7 changed files with 133 additions and 65 deletions

View file

@ -464,40 +464,36 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
match (new_loan.kind, old_loan.kind) { match (new_loan.kind, old_loan.kind) {
(ty::MutBorrow, ty::MutBorrow) => { (ty::MutBorrow, ty::MutBorrow) => {
self.bccx.span_err( span_err!(self.bccx, new_loan.span, E0499,
new_loan.span, "cannot borrow `{}`{} as mutable \
&format!("cannot borrow `{}`{} as mutable \ more than once at a time",
more than once at a time", nl, new_loan_msg);
nl, new_loan_msg))
} }
(ty::UniqueImmBorrow, _) => { (ty::UniqueImmBorrow, _) => {
self.bccx.span_err( span_err!(self.bccx, new_loan.span, E0500,
new_loan.span, "closure requires unique access to `{}` \
&format!("closure requires unique access to `{}` \ but {} is already borrowed{}",
but {} is already borrowed{}", nl, ol_pronoun, old_loan_msg);
nl, ol_pronoun, old_loan_msg));
} }
(_, ty::UniqueImmBorrow) => { (_, ty::UniqueImmBorrow) => {
self.bccx.span_err( span_err!(self.bccx, new_loan.span, E0501,
new_loan.span, "cannot borrow `{}`{} as {} because \
&format!("cannot borrow `{}`{} as {} because \ previous closure requires unique access",
previous closure requires unique access", nl, new_loan_msg, new_loan.kind.to_user_str());
nl, new_loan_msg, new_loan.kind.to_user_str()));
} }
(_, _) => { (_, _) => {
self.bccx.span_err( span_err!(self.bccx, new_loan.span, E0502,
new_loan.span, "cannot borrow `{}`{} as {} because \
&format!("cannot borrow `{}`{} as {} because \ {} is also borrowed as {}{}",
{} is also borrowed as {}{}", nl,
nl, new_loan_msg,
new_loan_msg, new_loan.kind.to_user_str(),
new_loan.kind.to_user_str(), ol_pronoun,
ol_pronoun, old_loan.kind.to_user_str(),
old_loan.kind.to_user_str(), old_loan_msg);
old_loan_msg));
} }
} }
@ -617,11 +613,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) { match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) {
UseOk => { } UseOk => { }
UseWhileBorrowed(loan_path, loan_span) => { UseWhileBorrowed(loan_path, loan_span) => {
self.bccx.span_err( span_err!(self.bccx, span, E0503,
span, "cannot use `{}` because it was mutably borrowed",
&format!("cannot use `{}` because it was mutably borrowed", &self.bccx.loan_path_to_string(copy_path));
&self.bccx.loan_path_to_string(copy_path))
);
self.bccx.span_note( self.bccx.span_note(
loan_span, loan_span,
&format!("borrow of `{}` occurs here", &format!("borrow of `{}` occurs here",
@ -642,18 +636,19 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
match self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow) { match self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow) {
UseOk => { } UseOk => { }
UseWhileBorrowed(loan_path, loan_span) => { UseWhileBorrowed(loan_path, loan_span) => {
let err_message = match move_kind { match move_kind {
move_data::Captured => move_data::Captured =>
format!("cannot move `{}` into closure because it is borrowed", span_err!(self.bccx, span, E0504,
&self.bccx.loan_path_to_string(move_path)), "cannot move `{}` into closure because it is borrowed",
&self.bccx.loan_path_to_string(move_path)),
move_data::Declared | move_data::Declared |
move_data::MoveExpr | move_data::MoveExpr |
move_data::MovePat => move_data::MovePat =>
format!("cannot move out of `{}` because it is borrowed", span_err!(self.bccx, span, E0505,
&self.bccx.loan_path_to_string(move_path)) "cannot move out of `{}` because it is borrowed",
&self.bccx.loan_path_to_string(move_path))
}; };
self.bccx.span_err(span, &err_message[..]);
self.bccx.span_note( self.bccx.span_note(
loan_span, loan_span,
&format!("borrow of `{}` occurs here", &format!("borrow of `{}` occurs here",
@ -820,10 +815,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
span: Span, span: Span,
loan_path: &LoanPath<'tcx>, loan_path: &LoanPath<'tcx>,
loan: &Loan) { loan: &Loan) {
self.bccx.span_err( span_err!(self.bccx, span, E0506,
span, "cannot assign to `{}` because it is borrowed",
&format!("cannot assign to `{}` because it is borrowed", self.bccx.loan_path_to_string(loan_path));
self.bccx.loan_path_to_string(loan_path)));
self.bccx.span_note( self.bccx.span_note(
loan.span, loan.span,
&format!("borrow of `{}` occurs here", &format!("borrow of `{}` occurs here",

View file

@ -119,18 +119,18 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
mc::cat_deref(_, _, mc::Implicit(..)) | mc::cat_deref(_, _, mc::Implicit(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) | mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item => { mc::cat_static_item => {
bccx.span_err(move_from.span, span_err!(bccx, move_from.span, E0507,
&format!("cannot move out of {}", "cannot move out of {}",
move_from.descriptive_string(bccx.tcx))); move_from.descriptive_string(bccx.tcx));
} }
mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => { mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
let expr = bccx.tcx.map.expect_expr(move_from.id); let expr = bccx.tcx.map.expect_expr(move_from.id);
if let hir::ExprIndex(..) = expr.node { if let hir::ExprIndex(..) = expr.node {
bccx.span_err(move_from.span, span_err!(bccx, move_from.span, E0508,
&format!("cannot move out of type `{}`, \ "cannot move out of type `{}`, \
a non-copy fixed-size array", a non-copy fixed-size array",
b.ty)); b.ty);
} }
} }
@ -139,11 +139,10 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
match b.ty.sty { match b.ty.sty {
ty::TyStruct(def, _) | ty::TyStruct(def, _) |
ty::TyEnum(def, _) if def.has_dtor() => { ty::TyEnum(def, _) if def.has_dtor() => {
bccx.span_err( span_err!(bccx, move_from.span, E0509,
move_from.span, "cannot move out of type `{}`, \
&format!("cannot move out of type `{}`, \ which defines the `Drop` trait",
which defines the `Drop` trait", b.ty);
b.ty));
}, },
_ => { _ => {
bccx.span_bug(move_from.span, "this path should not cause illegal move") bccx.span_bug(move_from.span, "this path should not cause illegal move")

View file

@ -803,6 +803,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.tcx.sess.span_err(s, m); self.tcx.sess.span_err(s, m);
} }
pub fn span_err_with_code(&self, s: Span, msg: &str, code: &str) {
self.tcx.sess.span_err_with_code(s, msg, code);
}
pub fn span_bug(&self, s: Span, m: &str) { pub fn span_bug(&self, s: Span, m: &str) {
self.tcx.sess.span_bug(s, m); self.tcx.sess.span_bug(s, m);
} }

View file

@ -263,12 +263,50 @@ fn mutable() {
You can read more about cell types in the API documentation: You can read more about cell types in the API documentation:
https://doc.rust-lang.org/std/cell/ https://doc.rust-lang.org/std/cell/
"## "##,
E0499: r##"
A variable was borrowed as mutable more than once. Erroneous code example:
```
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
// error: cannot borrow `i` as mutable more than once at a time
```
Please note that in rust, you can either have many immutable references, or one
mutable reference. Take a look at
https://doc.rust-lang.org/stable/book/references-and-borrowing.html for more
information. Example:
```
let mut i = 0;
let mut x = &mut i; // ok!
// or:
let mut i = 0;
let a = &i; // ok!
let b = &i; // still ok!
let c = &i; // still ok!
```
"##,
} }
register_diagnostics! { register_diagnostics! {
E0385, // {} in an aliasable location E0385, // {} in an aliasable location
E0388, // {} in a static location E0388, // {} in a static location
E0389 // {} in a `&` reference E0389, // {} in a `&` reference
E0500, // closure requires unique access to `..` but .. is already borrowed
E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
E0503, // cannot use `..` because it was mutably borrowed
E0504, // cannot move `..` into closure because it is borrowed
E0505, // cannot move out of `..` because it is borrowed
E0506, // cannot assign to `..` because it is borrowed
E0507, // cannot move out of ..
E0508, // cannot move out of type `..`, a non-copy fixed-size array
E0509, // cannot move out of type `..`, which defines the `Drop` trait
} }

View file

@ -0,0 +1,21 @@
// 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.
#![allow(non_snake_case)]
register_long_diagnostics! {
}
register_diagnostics! {
E0510, // invalid use of `return_address` intrinsic: function does not use out pointer
E0511, // invalid monomorphization of `{}` intrinsic
E0512, // transmute called on types with potentially different sizes...
}

View file

@ -80,6 +80,8 @@ pub mod back {
pub mod msvc; pub mod msvc;
} }
pub mod diagnostics;
pub mod trans; pub mod trans;
pub mod save; pub mod save;

View file

@ -44,6 +44,9 @@ use syntax::ast;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::parse::token; use syntax::parse::token;
use rustc::session::Session;
use syntax::codemap::Span;
use std::cmp::Ordering; use std::cmp::Ordering;
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &hir::ForeignItem) -> Option<ValueRef> { pub fn get_simple_intrinsic(ccx: &CrateContext, item: &hir::ForeignItem) -> Option<ValueRef> {
@ -99,6 +102,10 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &hir::ForeignItem) -> Opti
Some(ccx.get_intrinsic(&name)) Some(ccx.get_intrinsic(&name))
} }
pub fn span_transmute_size_error(a: &Session, b: Span, msg: &str) {
span_err!(a, b, E0512, "{}", msg);
}
/// Performs late verification that intrinsics are used correctly. At present, /// Performs late verification that intrinsics are used correctly. At present,
/// the only intrinsic that needs such verification is `transmute`. /// the only intrinsic that needs such verification is `transmute`.
pub fn check_intrinsics(ccx: &CrateContext) { pub fn check_intrinsics(ccx: &CrateContext) {
@ -127,8 +134,7 @@ pub fn check_intrinsics(ccx: &CrateContext) {
last_failing_id = Some(transmute_restriction.id); last_failing_id = Some(transmute_restriction.id);
if transmute_restriction.original_from != transmute_restriction.substituted_from { if transmute_restriction.original_from != transmute_restriction.substituted_from {
ccx.sess().span_err( span_transmute_size_error(ccx.sess(), transmute_restriction.span,
transmute_restriction.span,
&format!("transmute called on types with potentially different sizes: \ &format!("transmute called on types with potentially different sizes: \
{} (could be {} bit{}) to {} (could be {} bit{})", {} (could be {} bit{}) to {} (could be {} bit{})",
transmute_restriction.original_from, transmute_restriction.original_from,
@ -138,8 +144,7 @@ pub fn check_intrinsics(ccx: &CrateContext) {
to_type_size as usize, to_type_size as usize,
if to_type_size == 1 {""} else {"s"})); if to_type_size == 1 {""} else {"s"}));
} else { } else {
ccx.sess().span_err( span_transmute_size_error(ccx.sess(), transmute_restriction.span,
transmute_restriction.span,
&format!("transmute called on types with different sizes: \ &format!("transmute called on types with different sizes: \
{} ({} bit{}) to {} ({} bit{})", {} ({} bit{}) to {} ({} bit{})",
transmute_restriction.original_from, transmute_restriction.original_from,
@ -798,9 +803,9 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(_, "return_address") => { (_, "return_address") => {
if !fcx.caller_expects_out_pointer { if !fcx.caller_expects_out_pointer {
tcx.sess.span_err(call_info.span, span_err!(tcx.sess, call_info.span, E0510,
"invalid use of `return_address` intrinsic: function \ "invalid use of `return_address` intrinsic: function \
does not use out pointer"); does not use out pointer");
C_null(Type::i8p(ccx)) C_null(Type::i8p(ccx))
} else { } else {
PointerCast(bcx, llvm::get_param(fcx.llfn, 0), Type::i8p(ccx)) PointerCast(bcx, llvm::get_param(fcx.llfn, 0), Type::i8p(ccx))
@ -1439,6 +1444,10 @@ fn get_rust_try_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
return rust_try return rust_try
} }
fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
span_err!(a, b, E0511, "{}", c);
}
fn generic_simd_intrinsic<'blk, 'tcx, 'a> fn generic_simd_intrinsic<'blk, 'tcx, 'a>
(bcx: Block<'blk, 'tcx>, (bcx: Block<'blk, 'tcx>,
name: &str, name: &str,
@ -1457,10 +1466,11 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
emit_error!($msg, ) emit_error!($msg, )
}; };
($msg: tt, $($fmt: tt)*) => { ($msg: tt, $($fmt: tt)*) => {
bcx.sess().span_err(call_info.span, span_invalid_monomorphization_error(
&format!(concat!("invalid monomorphization of `{}` intrinsic: ", bcx.sess(), call_info.span,
$msg), &format!(concat!("invalid monomorphization of `{}` intrinsic: ",
name, $($fmt)*)); $msg),
name, $($fmt)*));
} }
} }
macro_rules! require { macro_rules! require {