From 7f5ec6c392c53225d85b160bcef3cedbc366ed72 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 14 Sep 2015 13:52:32 +0200 Subject: [PATCH 01/18] Disable browser history API on file:/ URLs history.pushState is defined, but not working whenever document.origin is "null" (literally that string, not just the null object). This is due to some security considerations and is unlikely to be ever working. For now just disable the usage of the history API when the documentation is accessed through a file:/ URL. See https://code.google.com/p/chromium/issues/detail?id=301210 for a Chrome-specific issue on the history API on file:/ URLs Closes #25953 --- src/librustdoc/html/static/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9d84d4ea3c1a..5b0b19b95af1 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -54,7 +54,8 @@ } function browserSupportsHistoryApi() { - return window.history && typeof window.history.pushState === "function"; + return document.location.protocol != "file:" && + window.history && typeof window.history.pushState === "function"; } function highlightSourceLines(ev) { From 7352722cdddf2869341b55a3479e3a1124d5be3c Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Wed, 16 Sep 2015 13:52:02 -0400 Subject: [PATCH 02/18] Emit an error upon failing to create a temp dir instead of panicking Closes #14698. --- src/librustc_trans/back/link.rs | 6 +++++- src/test/run-make/issue-14698/Makefile | 4 ++++ src/test/run-make/issue-14698/foo.rs | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make/issue-14698/Makefile create mode 100644 src/test/run-make/issue-14698/foo.rs diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index d5486e84fc43..fdce46ba272a 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -543,7 +543,11 @@ fn link_binary_output(sess: &Session, } } - let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir"); + let tmpdir = match TempDir::new("rustc") { + Ok(tmpdir) => tmpdir, + Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)), + }; + match crate_type { config::CrateTypeRlib => { link_rlib(sess, Some(trans), &objects, &out_filename, diff --git a/src/test/run-make/issue-14698/Makefile b/src/test/run-make/issue-14698/Makefile new file mode 100644 index 000000000000..28502f67e074 --- /dev/null +++ b/src/test/run-make/issue-14698/Makefile @@ -0,0 +1,4 @@ +-include ../tools.mk + +all: + TMP=fake TMPDIR=fake $(RUSTC) foo.rs 2>&1 | grep "couldn't create a temp dir:" diff --git a/src/test/run-make/issue-14698/foo.rs b/src/test/run-make/issue-14698/foo.rs new file mode 100644 index 000000000000..7dc79f2043ba --- /dev/null +++ b/src/test/run-make/issue-14698/foo.rs @@ -0,0 +1,11 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} From 37cfa75d43cecd5c81cb9d4adb77719ea7978ac4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 16 Sep 2015 20:40:38 +0200 Subject: [PATCH 03/18] Add error codes for librustc_borrowck --- src/librustc_borrowck/borrowck/check_loans.rs | 74 +++++++++---------- .../borrowck/gather_loans/move_error.rs | 23 +++--- src/librustc_borrowck/diagnostics.rs | 38 +++++++++- 3 files changed, 81 insertions(+), 54 deletions(-) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index eed8f82b5d85..43e9cdd73c43 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -464,40 +464,36 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { match (new_loan.kind, old_loan.kind) { (ty::MutBorrow, ty::MutBorrow) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as mutable \ - more than once at a time", - nl, new_loan_msg)) + span_err!(self.bccx, new_loan.span, E0499, + "cannot borrow `{}`{} as mutable \ + more than once at a time", + nl, new_loan_msg); } (ty::UniqueImmBorrow, _) => { - self.bccx.span_err( - new_loan.span, - &format!("closure requires unique access to `{}` \ - but {} is already borrowed{}", - nl, ol_pronoun, old_loan_msg)); + span_err!(self.bccx, new_loan.span, E0500, + "closure requires unique access to `{}` \ + but {} is already borrowed{}", + nl, ol_pronoun, old_loan_msg); } (_, ty::UniqueImmBorrow) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as {} because \ - previous closure requires unique access", - nl, new_loan_msg, new_loan.kind.to_user_str())); + span_err!(self.bccx, new_loan.span, E0501, + "cannot borrow `{}`{} as {} because \ + previous closure requires unique access", + nl, new_loan_msg, new_loan.kind.to_user_str()); } (_, _) => { - self.bccx.span_err( - new_loan.span, - &format!("cannot borrow `{}`{} as {} because \ - {} is also borrowed as {}{}", - nl, - new_loan_msg, - new_loan.kind.to_user_str(), - ol_pronoun, - old_loan.kind.to_user_str(), - old_loan_msg)); + span_err!(self.bccx, new_loan.span, E0502, + "cannot borrow `{}`{} as {} because \ + {} is also borrowed as {}{}", + nl, + new_loan_msg, + new_loan.kind.to_user_str(), + ol_pronoun, + old_loan.kind.to_user_str(), + old_loan_msg); } } @@ -617,11 +613,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) { UseOk => { } UseWhileBorrowed(loan_path, loan_span) => { - self.bccx.span_err( - span, - &format!("cannot use `{}` because it was mutably borrowed", - &self.bccx.loan_path_to_string(copy_path)) - ); + span_err!(self.bccx, span, E0503, + "cannot use `{}` because it was mutably borrowed", + &self.bccx.loan_path_to_string(copy_path)); self.bccx.span_note( loan_span, &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) { UseOk => { } UseWhileBorrowed(loan_path, loan_span) => { - let err_message = match move_kind { + match move_kind { move_data::Captured => - format!("cannot move `{}` into closure because it is borrowed", - &self.bccx.loan_path_to_string(move_path)), + span_err!(self.bccx, span, E0504, + "cannot move `{}` into closure because it is borrowed", + &self.bccx.loan_path_to_string(move_path)), move_data::Declared | move_data::MoveExpr | move_data::MovePat => - format!("cannot move out of `{}` because it is borrowed", - &self.bccx.loan_path_to_string(move_path)) + span_err!(self.bccx, span, E0505, + "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( loan_span, &format!("borrow of `{}` occurs here", @@ -820,10 +815,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { span: Span, loan_path: &LoanPath<'tcx>, loan: &Loan) { - self.bccx.span_err( - span, - &format!("cannot assign to `{}` because it is borrowed", - self.bccx.loan_path_to_string(loan_path))); + span_err!(self.bccx, span, E0506, + "cannot assign to `{}` because it is borrowed", + self.bccx.loan_path_to_string(loan_path)); self.bccx.span_note( loan.span, &format!("borrow of `{}` occurs here", diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index c39b1a9da07e..bbcf51933422 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -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::UnsafePtr(..)) | mc::cat_static_item => { - bccx.span_err(move_from.span, - &format!("cannot move out of {}", - move_from.descriptive_string(bccx.tcx))); + span_err!(bccx, move_from.span, E0507, + "cannot move out of {}", + move_from.descriptive_string(bccx.tcx)); } mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => { let expr = bccx.tcx.map.expect_expr(move_from.id); if let hir::ExprIndex(..) = expr.node { - bccx.span_err(move_from.span, - &format!("cannot move out of type `{}`, \ - a non-copy fixed-size array", - b.ty)); + span_err!(bccx, move_from.span, E0508, + "cannot move out of type `{}`, \ + a non-copy fixed-size array", + b.ty); } } @@ -139,11 +139,10 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, match b.ty.sty { ty::TyStruct(def, _) | ty::TyEnum(def, _) if def.has_dtor() => { - bccx.span_err( - move_from.span, - &format!("cannot move out of type `{}`, \ - which defines the `Drop` trait", - b.ty)); + span_err!(bccx, move_from.span, E0509, + "cannot move out of type `{}`, \ + which defines the `Drop` trait", + b.ty); }, _ => { bccx.span_bug(move_from.span, "this path should not cause illegal move") diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index e94a214309d1..ede1bb58ce68 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -263,12 +263,46 @@ fn mutable() { You can read more about cell types in the API documentation: 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 have as many reference on a variable as you +want, but only one can be mutable. Example: + + +``` +let mut i = 0; +let mut x = &mut i; +let mut a = &i; +let mut b = &i; +let mut c = &i; +// ... +``` +"##, } register_diagnostics! { E0385, // {} in an aliasable 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 } From bc72f540ac2326fda259c9e5aec407f2c62d8ddd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 17 Sep 2015 23:31:37 +0200 Subject: [PATCH 04/18] Add span_err_with_code method for BorrowckCtxt struct --- src/librustc_borrowck/borrowck/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 57e578d10c66..4db7974f0944 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -803,6 +803,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { 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) { self.tcx.sess.span_bug(s, m); } From 5a91ba8e6028241558c5eb1a9405ede07bf306c6 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Thu, 17 Sep 2015 23:43:33 -0400 Subject: [PATCH 05/18] Fix spelling and remove weirdly placed comma. --- COMPILER_TESTS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/COMPILER_TESTS.md b/COMPILER_TESTS.md index e4acf230e721..546164c1492a 100644 --- a/COMPILER_TESTS.md +++ b/COMPILER_TESTS.md @@ -1,6 +1,6 @@ # Compiler Test Documentation -In the Rust project, we use a special set of comands imbedded in +In the Rust project, we use a special set of comands embedded in comments to test the Rust compiler. There are two groups of commands: 1. Header commands @@ -29,11 +29,11 @@ The error levels that you can have are: 3. `NOTE` 4. `HELP` and `SUGGESTION`* -\* **Note**: `SUGGESTION` must follow emediatly after `HELP`. +\* **Note**: `SUGGESTION` must follow immediately after `HELP`. ## Summary of Header Commands -Header commands specify something about the entire test file, as a +Header commands specify something about the entire test file as a whole, instead of just a few lines inside the test. * `ignore-X` where `X` is an architecture, OS or stage will ignore the test accordingly From cbc9517b023f3484816b59fd13993027c412748d Mon Sep 17 00:00:00 2001 From: Colin Wallace Date: Thu, 17 Sep 2015 21:39:19 -0700 Subject: [PATCH 06/18] Clarify where let accepts a pattern, spatially --- src/doc/trpl/guessing-game.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md index 3a4328562f87..94280aa4a331 100644 --- a/src/doc/trpl/guessing-game.md +++ b/src/doc/trpl/guessing-game.md @@ -147,7 +147,7 @@ a few tricks up their sleeves. For example, they’re [immutable][immutable] by default. That’s why our example uses `mut`: it makes a binding mutable, rather than immutable. `let` doesn’t -take a name on the left hand side, it actually accepts a +take a name on the left hand side of the assignment, it actually accepts a ‘[pattern][patterns]’. We’ll use patterns later. It’s easy enough to use for now: From 7badafa593400b272ff05efd26a8fabb5c9d4cdd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 18 Sep 2015 19:12:27 +0200 Subject: [PATCH 07/18] Add url to rust-book --- src/librustc_borrowck/diagnostics.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index ede1bb58ce68..2ae998841d92 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -275,17 +275,21 @@ let mut a = &mut i; // error: cannot borrow `i` as mutable more than once at a time ``` -Please note that in rust, you can have as many reference on a variable as you -want, but only one can be mutable. Example: +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; -let mut a = &i; -let mut b = &i; -let mut c = &i; -// ... +let mut x = &mut i; // ok! + +// or: +let mut i = 0; +let a = &i; // ok! +let b = &i; // still ok! +let c = &i; // super still ok! ``` "##, From 9d3deb4766e1c3c9d0a0f98fc124de7063b47030 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Fri, 18 Sep 2015 17:21:30 +0100 Subject: [PATCH 08/18] fix anchor link --- src/doc/trpl/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index edb794a54aea..5cd847da823c 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -210,7 +210,7 @@ that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that ### Composing `Option` values -In [`option-ex-string-find`](#code-option-ex-string-find-2) +In [`option-ex-string-find`](#code-option-ex-string-find) we saw how to use `find` to discover the extension in a file name. Of course, not all file names have a `.` in them, so it's possible that the file name has no extension. This *possibility of absence* is encoded into the types using From 634ffe562450278e9d77066d3607a1971353979b Mon Sep 17 00:00:00 2001 From: David Szotten Date: Fri, 18 Sep 2015 22:16:31 +0100 Subject: [PATCH 09/18] remove preceeding blank line --- src/doc/trpl/error-handling.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 5cd847da823c..f7d5db2ddf1d 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -89,7 +89,6 @@ an integer as an argument, doubles it and prints it.
```rust,should_panic - use std::env; fn main() { From 49b1902345468564a9da16d745cc1a5c5c650908 Mon Sep 17 00:00:00 2001 From: llogiq Date: Sat, 19 Sep 2015 09:04:12 +0200 Subject: [PATCH 10/18] added panic docs for print\! and println\! macros --- src/libstd/macros.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a0c3f013f2b4..a07d21add8db 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -68,6 +68,10 @@ macro_rules! panic { /// necessary to use `io::stdout().flush()` to ensure the output is emitted /// immediately. /// +/// # Panics +/// +/// Panics if writing to `io::stdout()` fails. +/// /// # Examples /// /// ``` @@ -99,6 +103,10 @@ macro_rules! print { /// Use the `format!` syntax to write data to the standard output. /// See `std::fmt` for more information. /// +/// # Panics +/// +/// Panics if writing to `io::stdout()` fails. +/// /// # Examples /// /// ``` From 4e42fcd92ad0d918cb0474551601c387fa4999a3 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 11:43:32 +0100 Subject: [PATCH 11/18] link needs puncuation --- src/doc/trpl/error-handling.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index f7d5db2ddf1d..6d1d2f409984 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -28,7 +28,7 @@ systems may want to jump around. * [The `Result` type](#the-result-type) * [Parsing integers](#parsing-integers) * [The `Result` type alias idiom](#the-result-type-alias-idiom) - * [A brief interlude: unwrapping isn't evil](#a-brief-interlude-unwrapping-isnt-evil) + * [A brief interlude: unwrapping isn't evil](#a-brief-interlude:-unwrapping-isn't-evil) * [Working with multiple error types](#working-with-multiple-error-types) * [Composing `Option` and `Result`](#composing-option-and-result) * [The limits of combinators](#the-limits-of-combinators) @@ -41,7 +41,7 @@ systems may want to jump around. * [The real `try!` macro](#the-real-try!-macro) * [Composing custom error types](#composing-custom-error-types) * [Advice for library writers](#advice-for-library-writers) -* [Case study: A program to read population data](#case-study-a-program-to-read-population-data) +* [Case study: A program to read population data](#case-study:-a-program-to-read-population-data) * [Initial setup](#initial-setup) * [Argument parsing](#argument-parsing) * [Writing the logic](#writing-the-logic) From 30c91cd7f7527cee89e4997827fbe61ea39f2729 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 11:43:57 +0100 Subject: [PATCH 12/18] angle brackets get mis-parsed. bug? --- src/doc/trpl/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 6d1d2f409984..9dbc27dfcb8a 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -45,7 +45,7 @@ systems may want to jump around. * [Initial setup](#initial-setup) * [Argument parsing](#argument-parsing) * [Writing the logic](#writing-the-logic) - * [Error handling with `Box`](#error-handling-with-box) + * [Error handling with `Box`](#error-handling-with-box%3Cerror%3E) * [Reading from stdin](#reading-from-stdin) * [Error handling with a custom type](#error-handling-with-a-custom-type) * [Adding functionality](#adding-functionality) From 3a5e9a3f9934a850753110769c49521a659cd03a Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 11:44:55 +0100 Subject: [PATCH 13/18] wrap more referenced code blocks in divs --- src/doc/trpl/error-handling.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 9dbc27dfcb8a..521538b95567 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -186,6 +186,7 @@ But wait, what about `unwrap` used in [`unwrap-double`](#code-unwrap-double)? There was no case analysis there! Instead, the case analysis was put inside the `unwrap` method for you. You could define it yourself if you want: +
```rust enum Option { None, @@ -202,6 +203,7 @@ impl Option { } } ``` +
The `unwrap` method *abstracts away the case analysis*. This is precisely the thing that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that @@ -251,6 +253,7 @@ option is `None`, in which case, just return `None`. Rust has parametric polymorphism, so it is very easy to define a combinator that abstracts this pattern: + Indeed, `map` is [defined as a method][2] on `Option` in the standard library. @@ -390,12 +394,14 @@ remove choices because they will panic if `Option` is `None`. The `Result` type is also [defined in the standard library][6]: +
```rust enum Result { Ok(T), Err(E), } ``` +
The `Result` type is a richer version of `Option`. Instead of expressing the possibility of *absence* like `Option` does, `Result` expresses the possibility @@ -666,6 +672,7 @@ with both an `Option` and a `Result`, the solution is *usually* to convert the (from `env::args()`) means the user didn't invoke the program correctly. We could just use a `String` to describe the error. Let's try: +
```rust use std::env; @@ -682,6 +689,7 @@ fn main() { } } ``` +
There are a couple new things in this example. The first is the use of the [`Option::ok_or`](../std/option/enum.Option.html#method.ok_or) @@ -898,6 +906,7 @@ seen above. Here is a simplified definition of a `try!` macro: +
```rust macro_rules! try { ($e:expr) => (match $e { @@ -906,6 +915,7 @@ macro_rules! try { }); } ``` +
(The [real definition](../std/macro.try!.html) is a bit more sophisticated. We will address that later.) @@ -1158,11 +1168,13 @@ The `std::convert::From` trait is [defined in the standard library](../std/convert/trait.From.html): +
```rust trait From { fn from(T) -> Self; } ``` +
Deliciously simple, yes? `From` is very useful because it gives us a generic way to talk about conversion *from* a particular type `T` to some other type @@ -1238,6 +1250,7 @@ macro_rules! try { This is not it's real definition. It's real definition is [in the standard library](../std/macro.try!.html): +
```rust macro_rules! try { ($e:expr) => (match $e { @@ -1246,6 +1259,7 @@ macro_rules! try { }); } ``` +
There's one tiny but powerful change: the error value is passed through `From::from`. This makes the `try!` macro a lot more powerful because it gives From 436e8d69bf7326181225cb3c0226d11efef5d8f8 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 11:45:09 +0100 Subject: [PATCH 14/18] its vs it's --- src/doc/trpl/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 521538b95567..4cba68e17246 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -1247,7 +1247,7 @@ macro_rules! try { } ``` -This is not it's real definition. It's real definition is +This is not its real definition. Its real definition is [in the standard library](../std/macro.try!.html):
From f7d8b418147fe46f3d0eaba295a0111394446bb0 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 11:45:30 +0100 Subject: [PATCH 15/18] missing punctuation --- src/doc/trpl/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 4cba68e17246..18d2fae0d754 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -1470,7 +1470,7 @@ representation. But certainly, this will vary depending on use cases. At a minimum, you should probably implement the [`Error`](../std/error/trait.Error.html) trait. This will give users of your library some minimum flexibility for -[composing errors](#the-real-try-macro). Implementing the `Error` trait also +[composing errors](#the-real-try!-macro). Implementing the `Error` trait also means that users are guaranteed the ability to obtain a string representation of an error (because it requires impls for both `fmt::Debug` and `fmt::Display`). From 5ab3058569245171a44283fddee6c119a31765b7 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Sat, 19 Sep 2015 12:06:36 +0100 Subject: [PATCH 16/18] change back to anchors; divs break md --- src/doc/trpl/error-handling.md | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 18d2fae0d754..18ce93ea06a6 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -87,7 +87,8 @@ thread '
' panicked at 'Invalid number: 11', src/bin/panic-simple.rs:5 Here's another example that is slightly less contrived. A program that accepts an integer as an argument, doubles it and prints it. -
+ + ```rust,should_panic use std::env; @@ -98,7 +99,6 @@ fn main() { println!("{}", 2 * n); } ``` -
If you give this program zero arguments (error 1) or if the first argument isn't an integer (error 2), the program will panic just like in the first @@ -139,7 +139,8 @@ system is an important concept because it will cause the compiler to force the programmer to handle that absence. Let's take a look at an example that tries to find a character in a string: -
+ + ```rust // Searches `haystack` for the Unicode character `needle`. If one is found, the // byte offset of the character is returned. Otherwise, `None` is returned. @@ -152,7 +153,6 @@ fn find(haystack: &str, needle: char) -> Option { None } ``` -
Notice that when this function finds a matching character, it doen't just return the `offset`. Instead, it returns `Some(offset)`. `Some` is a variant or @@ -186,7 +186,8 @@ But wait, what about `unwrap` used in [`unwrap-double`](#code-unwrap-double)? There was no case analysis there! Instead, the case analysis was put inside the `unwrap` method for you. You could define it yourself if you want: -
+ + ```rust enum Option { None, @@ -203,7 +204,6 @@ impl Option { } } ``` -
The `unwrap` method *abstracts away the case analysis*. This is precisely the thing that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that @@ -253,7 +253,8 @@ option is `None`, in which case, just return `None`. Rust has parametric polymorphism, so it is very easy to define a combinator that abstracts this pattern: - Indeed, `map` is [defined as a method][2] on `Option` in the standard library. @@ -394,14 +394,14 @@ remove choices because they will panic if `Option` is `None`. The `Result` type is also [defined in the standard library][6]: -
+ + ```rust enum Result { Ok(T), Err(E), } ``` -
The `Result` type is a richer version of `Option`. Instead of expressing the possibility of *absence* like `Option` does, `Result` expresses the possibility @@ -672,7 +672,8 @@ with both an `Option` and a `Result`, the solution is *usually* to convert the (from `env::args()`) means the user didn't invoke the program correctly. We could just use a `String` to describe the error. Let's try: -
+ + ```rust use std::env; @@ -689,7 +690,6 @@ fn main() { } } ``` -
There are a couple new things in this example. The first is the use of the [`Option::ok_or`](../std/option/enum.Option.html#method.ok_or) @@ -906,7 +906,8 @@ seen above. Here is a simplified definition of a `try!` macro: -
+ + ```rust macro_rules! try { ($e:expr) => (match $e { @@ -915,7 +916,6 @@ macro_rules! try { }); } ``` -
(The [real definition](../std/macro.try!.html) is a bit more sophisticated. We will address that later.) @@ -1168,13 +1168,13 @@ The `std::convert::From` trait is [defined in the standard library](../std/convert/trait.From.html): -
+ + ```rust trait From { fn from(T) -> Self; } ``` -
Deliciously simple, yes? `From` is very useful because it gives us a generic way to talk about conversion *from* a particular type `T` to some other type @@ -1250,7 +1250,8 @@ macro_rules! try { This is not its real definition. Its real definition is [in the standard library](../std/macro.try!.html): -
+ + ```rust macro_rules! try { ($e:expr) => (match $e { @@ -1259,7 +1260,6 @@ macro_rules! try { }); } ``` -
There's one tiny but powerful change: the error value is passed through `From::from`. This makes the `try!` macro a lot more powerful because it gives From a2fbf9da29404c3d1826b2c256440d13541b164f Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 19 Sep 2015 08:10:54 -0400 Subject: [PATCH 17/18] Fixed an apparent typo Repertory is a real world, but it doesn't really make sense in that context. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 8968fabf1b4b..baa7e77394a0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -26,7 +26,7 @@ # # * check - Run the complete test suite # -# * clean - Clean the build repertory. It is advised to run this +# * clean - Clean the build repository. It is advised to run this # command if you want to build Rust again, after an update # of the git repository. # From 1adcfb8c13a2c224ae78178350de2e0fba8291c4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 19 Sep 2015 00:42:57 +0200 Subject: [PATCH 18/18] Add librustc_trans error codes --- src/librustc_borrowck/diagnostics.rs | 2 +- src/librustc_trans/diagnostics.rs | 21 ++++++++++++++++++ src/librustc_trans/lib.rs | 2 ++ src/librustc_trans/trans/intrinsic.rs | 32 ++++++++++++++++++--------- 4 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 src/librustc_trans/diagnostics.rs diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index 2ae998841d92..a5b313e2dd67 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -289,7 +289,7 @@ let mut x = &mut i; // ok! let mut i = 0; let a = &i; // ok! let b = &i; // still ok! -let c = &i; // super still ok! +let c = &i; // still ok! ``` "##, diff --git a/src/librustc_trans/diagnostics.rs b/src/librustc_trans/diagnostics.rs new file mode 100644 index 000000000000..dd7c3834e564 --- /dev/null +++ b/src/librustc_trans/diagnostics.rs @@ -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 or the MIT license +// , 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... +} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index a7fb3af13845..049d8fbe390a 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -80,6 +80,8 @@ pub mod back { pub mod msvc; } +pub mod diagnostics; + pub mod trans; pub mod save; diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index bcfd44d8835d..b43a4b3fc889 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -44,6 +44,9 @@ use syntax::ast; use syntax::ptr::P; use syntax::parse::token; +use rustc::session::Session; +use syntax::codemap::Span; + use std::cmp::Ordering; pub fn get_simple_intrinsic(ccx: &CrateContext, item: &hir::ForeignItem) -> Option { @@ -99,6 +102,10 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &hir::ForeignItem) -> Opti 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, /// the only intrinsic that needs such verification is `transmute`. pub fn check_intrinsics(ccx: &CrateContext) { @@ -127,8 +134,7 @@ pub fn check_intrinsics(ccx: &CrateContext) { last_failing_id = Some(transmute_restriction.id); if transmute_restriction.original_from != transmute_restriction.substituted_from { - ccx.sess().span_err( - transmute_restriction.span, + span_transmute_size_error(ccx.sess(), transmute_restriction.span, &format!("transmute called on types with potentially different sizes: \ {} (could be {} bit{}) to {} (could be {} bit{})", transmute_restriction.original_from, @@ -138,8 +144,7 @@ pub fn check_intrinsics(ccx: &CrateContext) { to_type_size as usize, if to_type_size == 1 {""} else {"s"})); } else { - ccx.sess().span_err( - transmute_restriction.span, + span_transmute_size_error(ccx.sess(), transmute_restriction.span, &format!("transmute called on types with different sizes: \ {} ({} bit{}) to {} ({} bit{})", transmute_restriction.original_from, @@ -798,9 +803,9 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, (_, "return_address") => { if !fcx.caller_expects_out_pointer { - tcx.sess.span_err(call_info.span, - "invalid use of `return_address` intrinsic: function \ - does not use out pointer"); + span_err!(tcx.sess, call_info.span, E0510, + "invalid use of `return_address` intrinsic: function \ + does not use out pointer"); C_null(Type::i8p(ccx)) } else { 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 } +fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { + span_err!(a, b, E0511, "{}", c); +} + fn generic_simd_intrinsic<'blk, 'tcx, 'a> (bcx: Block<'blk, 'tcx>, name: &str, @@ -1457,10 +1466,11 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a> emit_error!($msg, ) }; ($msg: tt, $($fmt: tt)*) => { - bcx.sess().span_err(call_info.span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", - $msg), - name, $($fmt)*)); + span_invalid_monomorphization_error( + bcx.sess(), call_info.span, + &format!(concat!("invalid monomorphization of `{}` intrinsic: ", + $msg), + name, $($fmt)*)); } } macro_rules! require {