Auto merge of #28516 - steveklabnik:rollup, r=steveklabnik

- Successful merges: #28400, #28430, #28443, #28483, #28485, #28496, #28511, #28515
- Failed merges:
This commit is contained in:
bors 2015-09-19 19:28:59 +00:00
commit 837840c61f
16 changed files with 192 additions and 83 deletions

View file

@ -1,6 +1,6 @@
# Compiler Test Documentation # 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: comments to test the Rust compiler. There are two groups of commands:
1. Header commands 1. Header commands
@ -29,11 +29,11 @@ The error levels that you can have are:
3. `NOTE` 3. `NOTE`
4. `HELP` and `SUGGESTION`* 4. `HELP` and `SUGGESTION`*
\* **Note**: `SUGGESTION` must follow emediatly after `HELP`. \* **Note**: `SUGGESTION` must follow immediately after `HELP`.
## Summary of Header Commands ## 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. 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 * `ignore-X` where `X` is an architecture, OS or stage will ignore the test accordingly

View file

@ -26,7 +26,7 @@
# #
# * check - Run the complete test suite # * 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 # command if you want to build Rust again, after an update
# of the git repository. # of the git repository.
# #

View file

@ -28,7 +28,7 @@ systems may want to jump around.
* [The `Result` type](#the-result-type) * [The `Result` type](#the-result-type)
* [Parsing integers](#parsing-integers) * [Parsing integers](#parsing-integers)
* [The `Result` type alias idiom](#the-result-type-alias-idiom) * [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) * [Working with multiple error types](#working-with-multiple-error-types)
* [Composing `Option` and `Result`](#composing-option-and-result) * [Composing `Option` and `Result`](#composing-option-and-result)
* [The limits of combinators](#the-limits-of-combinators) * [The limits of combinators](#the-limits-of-combinators)
@ -41,11 +41,11 @@ systems may want to jump around.
* [The real `try!` macro](#the-real-try!-macro) * [The real `try!` macro](#the-real-try!-macro)
* [Composing custom error types](#composing-custom-error-types) * [Composing custom error types](#composing-custom-error-types)
* [Advice for library writers](#advice-for-library-writers) * [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) * [Initial setup](#initial-setup)
* [Argument parsing](#argument-parsing) * [Argument parsing](#argument-parsing)
* [Writing the logic](#writing-the-logic) * [Writing the logic](#writing-the-logic)
* [Error handling with `Box<Error>`](#error-handling-with-box<error>) * [Error handling with `Box<Error>`](#error-handling-with-box%3Cerror%3E)
* [Reading from stdin](#reading-from-stdin) * [Reading from stdin](#reading-from-stdin)
* [Error handling with a custom type](#error-handling-with-a-custom-type) * [Error handling with a custom type](#error-handling-with-a-custom-type)
* [Adding functionality](#adding-functionality) * [Adding functionality](#adding-functionality)
@ -87,9 +87,9 @@ thread '<main>' panicked at 'Invalid number: 11', src/bin/panic-simple.rs:5
Here's another example that is slightly less contrived. A program that accepts Here's another example that is slightly less contrived. A program that accepts
an integer as an argument, doubles it and prints it. an integer as an argument, doubles it and prints it.
<div id="code-unwrap-double"> <a name="code-unwrap-double"></a>
```rust,should_panic
```rust,should_panic
use std::env; use std::env;
fn main() { fn main() {
@ -99,7 +99,6 @@ fn main() {
println!("{}", 2 * n); println!("{}", 2 * n);
} }
``` ```
</div>
If you give this program zero arguments (error 1) or if the first argument 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 isn't an integer (error 2), the program will panic just like in the first
@ -140,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 programmer to handle that absence. Let's take a look at an example that tries
to find a character in a string: to find a character in a string:
<div id="code-option-ex-string-find"> <a name="code-option-ex-string-find"></a>
```rust ```rust
// Searches `haystack` for the Unicode character `needle`. If one is found, the // Searches `haystack` for the Unicode character `needle`. If one is found, the
// byte offset of the character is returned. Otherwise, `None` is returned. // byte offset of the character is returned. Otherwise, `None` is returned.
@ -153,7 +153,6 @@ fn find(haystack: &str, needle: char) -> Option<usize> {
None None
} }
``` ```
</div>
Notice that when this function finds a matching character, it doen't just 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 return the `offset`. Instead, it returns `Some(offset)`. `Some` is a variant or
@ -187,6 +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 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: `unwrap` method for you. You could define it yourself if you want:
<a name="code-option-def-unwrap"></a>
```rust ```rust
enum Option<T> { enum Option<T> {
None, None,
@ -210,7 +211,7 @@ that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that
### Composing `Option<T>` values ### Composing `Option<T>` 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, 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 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 no extension. This *possibility of absence* is encoded into the types using
@ -252,6 +253,8 @@ option is `None`, in which case, just return `None`.
Rust has parametric polymorphism, so it is very easy to define a combinator Rust has parametric polymorphism, so it is very easy to define a combinator
that abstracts this pattern: that abstracts this pattern:
<a name="code-option-map"></a>
```rust ```rust
fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A { fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A {
match option { match option {
@ -391,6 +394,8 @@ remove choices because they will panic if `Option<T>` is `None`.
The `Result` type is also The `Result` type is also
[defined in the standard library][6]: [defined in the standard library][6]:
<a name="code-result-def-1"></a>
```rust ```rust
enum Result<T, E> { enum Result<T, E> {
Ok(T), Ok(T),
@ -667,6 +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 (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: could just use a `String` to describe the error. Let's try:
<a name="code-error-double-string"></a>
```rust ```rust
use std::env; use std::env;
@ -899,6 +906,8 @@ seen above.
Here is a simplified definition of a `try!` macro: Here is a simplified definition of a `try!` macro:
<a nama name="code-try-def-simple"></a>
```rust ```rust
macro_rules! try { macro_rules! try {
($e:expr) => (match $e { ($e:expr) => (match $e {
@ -1159,6 +1168,8 @@ The `std::convert::From` trait is
[defined in the standard [defined in the standard
library](../std/convert/trait.From.html): library](../std/convert/trait.From.html):
<a name="code-from-def"></a>
```rust ```rust
trait From<T> { trait From<T> {
fn from(T) -> Self; fn from(T) -> Self;
@ -1236,9 +1247,11 @@ 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): [in the standard library](../std/macro.try!.html):
<a name="code-try-def"></a>
```rust ```rust
macro_rules! try { macro_rules! try {
($e:expr) => (match $e { ($e:expr) => (match $e {
@ -1457,7 +1470,7 @@ representation. But certainly, this will vary depending on use cases.
At a minimum, you should probably implement the At a minimum, you should probably implement the
[`Error`](../std/error/trait.Error.html) [`Error`](../std/error/trait.Error.html)
trait. This will give users of your library some minimum flexibility for 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 means that users are guaranteed the ability to obtain a string representation
of an error (because it requires impls for both `fmt::Debug` and of an error (because it requires impls for both `fmt::Debug` and
`fmt::Display`). `fmt::Display`).

View file

@ -147,7 +147,7 @@ a few tricks up their sleeves.
For example, theyre [immutable][immutable] by default. Thats why our example For example, theyre [immutable][immutable] by default. Thats why our example
uses `mut`: it makes a binding mutable, rather than immutable. `let` doesnt uses `mut`: it makes a binding mutable, rather than immutable. `let` doesnt
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]. Well use patterns later. Its easy enough [pattern][patterns]. Well use patterns later. Its easy enough
to use for now: to use for now:

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,
"cannot move `{}` into closure because it is borrowed",
&self.bccx.loan_path_to_string(move_path)), &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,
"cannot move out of `{}` because it is borrowed",
&self.bccx.loan_path_to_string(move_path)) &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

@ -542,7 +542,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 { match crate_type {
config::CrateTypeRlib => { config::CrateTypeRlib => {
link_rlib(sess, Some(trans), &objects, &out_filename, link_rlib(sess, Some(trans), &objects, &out_filename,

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,7 +803,7 @@ 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))
@ -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,7 +1466,8 @@ 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(
bcx.sess(), call_info.span,
&format!(concat!("invalid monomorphization of `{}` intrinsic: ", &format!(concat!("invalid monomorphization of `{}` intrinsic: ",
$msg), $msg),
name, $($fmt)*)); name, $($fmt)*));

View file

@ -54,7 +54,8 @@
} }
function browserSupportsHistoryApi() { 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) { function highlightSourceLines(ev) {

View file

@ -68,6 +68,10 @@ macro_rules! panic {
/// necessary to use `io::stdout().flush()` to ensure the output is emitted /// necessary to use `io::stdout().flush()` to ensure the output is emitted
/// immediately. /// immediately.
/// ///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -99,6 +103,10 @@ macro_rules! print {
/// Use the `format!` syntax to write data to the standard output. /// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information. /// See `std::fmt` for more information.
/// ///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```

View file

@ -0,0 +1,4 @@
-include ../tools.mk
all:
TMP=fake TMPDIR=fake $(RUSTC) foo.rs 2>&1 | grep "couldn't create a temp dir:"

View file

@ -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 <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.
fn main() {}