Skip to content

Rollup of 10 pull requests #33948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
abe9961
* Fix compile_fail tag (in some cases, it compiled whereas it wasn't …
GuillaumeGomez May 22, 2016
a850d40
Improve E0132 error explanation
GuillaumeGomez May 27, 2016
a1e240c
Improve E0137 error explanatIon
GuillaumeGomez May 27, 2016
360d723
Improve E0138 error explanation
GuillaumeGomez May 27, 2016
c848ca1
Improve E0133 error explanation
GuillaumeGomez May 27, 2016
4fa8483
improve E0152 error explanation
GuillaumeGomez May 27, 2016
3fd0e4c
rustfmt liballoc folder
srinivasreddy May 27, 2016
feb0b27
Added examples/docs to split in str.rs
Ophirr33 May 26, 2016
68641d8
run rustfmt on librustc_lint folder
srinivasreddy May 28, 2016
72baa41
run rustfmt on librand folder
srinivasreddy May 29, 2016
5ed45ef
run rustfmt on libunwind
srinivasreddy May 29, 2016
31b9060
Improve E0161 error explanation
GuillaumeGomez May 27, 2016
cae6c75
Rollup merge of #33793 - GuillaumeGomez:compile_fail, r=GuillaumeGomez
GuillaumeGomez May 29, 2016
48245ae
Rollup merge of #33893 - Ophirr33:docs_string_split_fix, r=GuillaumeG…
GuillaumeGomez May 29, 2016
075ea13
Rollup merge of #33912 - GuillaumeGomez:improve_E0132, r=steveklabnik
GuillaumeGomez May 29, 2016
7475236
Rollup merge of #33913 - GuillaumeGomez:improve_e0133, r=GuillaumeGomez
GuillaumeGomez May 29, 2016
deb6bc6
Rollup merge of #33914 - GuillaumeGomez:improve_err_expl, r=Guillaume…
GuillaumeGomez May 29, 2016
df9dd98
Rollup merge of #33917 - srinivasreddy:rustfmt_liballoc, r=GuillaumeG…
GuillaumeGomez May 29, 2016
1bbbd5d
Rollup merge of #33931 - srinivasreddy:lint_folder, r=GuillaumeGomez
GuillaumeGomez May 29, 2016
fce2b41
Rollup merge of #33937 - srinivasreddy:rustfmt_librand, r=GuillaumeGomez
GuillaumeGomez May 29, 2016
59aef48
Rollup merge of #33938 - srinivasreddy:rustfmt_libunwind, r=Manishearth
GuillaumeGomez May 29, 2016
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
22 changes: 13 additions & 9 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@
use boxed::Box;

use core::sync::atomic;
use core::sync::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use core::borrow;
use core::fmt;
use core::cmp::Ordering;
@@ -85,7 +85,7 @@ use core::ops::CoerceUnsized;
use core::ptr::{self, Shared};
use core::marker::Unsize;
use core::hash::{Hash, Hasher};
use core::{usize, isize};
use core::{isize, usize};
use core::convert::From;
use heap::deallocate;

@@ -608,11 +608,13 @@ impl<T> Weak<T> {
#[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> {
unsafe {
Weak { ptr: Shared::new(Box::into_raw(box ArcInner {
strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1),
data: uninitialized(),
}))}
Weak {
ptr: Shared::new(Box::into_raw(box ArcInner {
strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1),
data: uninitialized(),
})),
}
}
}
}
@@ -655,7 +657,9 @@ impl<T: ?Sized> Weak<T> {

// See comments in `Arc::clone` for why we do this (for `mem::forget`).
if n > MAX_REFCOUNT {
unsafe { abort(); }
unsafe {
abort();
}
}

// Relaxed is valid for the same reason it is on Arc's Clone impl
@@ -946,7 +950,7 @@ mod tests {
use std::mem::drop;
use std::ops::Drop;
use std::option::Option;
use std::option::Option::{Some, None};
use std::option::Option::{None, Some};
use std::sync::atomic;
use std::sync::atomic::Ordering::{Acquire, SeqCst};
use std::thread;
5 changes: 3 additions & 2 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ use core::hash::{self, Hash};
use core::marker::{self, Unsize};
use core::mem;
use core::ops::{CoerceUnsized, Deref, DerefMut};
use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
use core::ptr::{self, Unique};
use core::raw::TraitObject;
use core::convert::From;
@@ -535,7 +535,8 @@ pub trait FnBox<A> {

#[unstable(feature = "fnbox",
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
impl<A, F> FnBox<A> for F where F: FnOnce<A>
impl<A, F> FnBox<A> for F
where F: FnOnce<A>
{
type Output = F::Output;

2 changes: 1 addition & 1 deletion src/liballoc/boxed_test.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
use core::any::Any;
use core::ops::Deref;
use core::result::Result::{Ok, Err};
use core::result::Result::{Err, Ok};
use core::clone::Clone;

use std::boxed::Box;
2 changes: 1 addition & 1 deletion src/liballoc/heap.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@

use core::{isize, usize};
#[cfg(not(test))]
use core::intrinsics::{size_of, min_align_of};
use core::intrinsics::{min_align_of, size_of};

#[allow(improper_ctypes)]
extern "C" {
8 changes: 4 additions & 4 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
@@ -159,11 +159,11 @@ use core::borrow;
use core::cell::Cell;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hasher, Hash};
use core::intrinsics::{assume, abort};
use core::hash::{Hash, Hasher};
use core::intrinsics::{abort, assume};
use core::marker;
use core::marker::Unsize;
use core::mem::{self, align_of_val, size_of_val, forget, uninitialized};
use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
use core::ops::Deref;
use core::ops::CoerceUnsized;
use core::ptr::{self, Shared};
@@ -935,7 +935,7 @@ mod tests {
use std::boxed::Box;
use std::cell::RefCell;
use std::option::Option;
use std::option::Option::{Some, None};
use std::option::Option::{None, Some};
use std::result::Result::{Err, Ok};
use std::mem::drop;
use std::clone::Clone;
30 changes: 28 additions & 2 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
@@ -1097,8 +1097,34 @@ impl str {
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
/// ```
///
/// This can lead to possibly surprising behavior when whitespace is used
/// as the separator. This code is correct:
/// Contiguous separators are separated by the empty string.
///
/// ```
/// let x = "(///)".to_string();
/// let d: Vec<_> = x.split('/').collect();;
///
/// assert_eq!(d, &["(", "", "", ")"]);
/// ```
///
/// Separators at the start or end of a string are neighbored
/// by empty strings.
///
/// ```
/// let d: Vec<_> = "010".split("0").collect();
/// assert_eq!(d, &["", "1", ""]);
/// ```
///
/// When the empty string is used as a separator, it separates
/// every character in the string, along with the beginning
/// and end of the string.
///
/// ```
/// let f: Vec<_> = "rust".split("").collect();
/// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
/// ```
///
/// Contiguous separators can lead to possibly surprising behavior
/// when whitespace is used as the separator. This code is correct:
///
/// ```
/// let x = " a b c".to_string();
8 changes: 5 additions & 3 deletions src/librand/chacha.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@

//! The ChaCha random number generator.
use {Rng, SeedableRng, Rand};
use {Rand, Rng, SeedableRng};

const KEY_WORDS: usize = 8; // 8 words for the 256-bit key
const STATE_WORDS: usize = 16;
@@ -216,7 +216,8 @@ mod tests {
let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
let mut ra: ChaChaRng = SeedableRng::from_seed(&*s);
let mut rb: ChaChaRng = SeedableRng::from_seed(&*s);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}

@@ -225,7 +226,8 @@ mod tests {
let seed: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}

6 changes: 3 additions & 3 deletions src/librand/distributions/exponential.rs
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@
#[cfg(not(test))] // only necessary for no_std
use FloatMath;

use {Rng, Rand};
use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
use {Rand, Rng};
use distributions::{IndependentSample, Sample, ziggurat, ziggurat_tables};

/// A wrapper around an `f64` to generate Exp(1) random numbers.
///
@@ -88,7 +88,7 @@ impl IndependentSample<f64> for Exp {

#[cfg(test)]
mod tests {
use distributions::{Sample, IndependentSample};
use distributions::{IndependentSample, Sample};
use super::Exp;

#[test]
8 changes: 4 additions & 4 deletions src/librand/distributions/gamma.rs
Original file line number Diff line number Diff line change
@@ -16,9 +16,9 @@ use self::ChiSquaredRepr::*;
#[cfg(not(test))] // only necessary for no_std
use FloatMath;

use {Rng, Open01};
use {Open01, Rng};
use super::normal::StandardNormal;
use super::{IndependentSample, Sample, Exp};
use super::{Exp, IndependentSample, Sample};

/// The Gamma distribution `Gamma(shape, scale)` distribution.
///
@@ -291,8 +291,8 @@ impl IndependentSample<f64> for StudentT {

#[cfg(test)]
mod tests {
use distributions::{Sample, IndependentSample};
use super::{ChiSquared, StudentT, FisherF};
use distributions::{IndependentSample, Sample};
use super::{ChiSquared, FisherF, StudentT};

#[test]
fn test_chi_squared_one() {
10 changes: 5 additions & 5 deletions src/librand/distributions/mod.rs
Original file line number Diff line number Diff line change
@@ -22,11 +22,11 @@ use core::num::Float;

use core::marker::PhantomData;

use {Rng, Rand};
use {Rand, Rng};

pub use self::range::Range;
pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
pub use self::normal::{Normal, LogNormal};
pub use self::gamma::{ChiSquared, FisherF, Gamma, StudentT};
pub use self::normal::{LogNormal, Normal};
pub use self::exponential::Exp;

pub mod range;
@@ -266,8 +266,8 @@ fn ziggurat<R: Rng, P, Z>(rng: &mut R,

#[cfg(test)]
mod tests {
use {Rng, Rand};
use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};
use {Rand, Rng};
use super::{IndependentSample, RandSample, Sample, Weighted, WeightedChoice};

#[derive(PartialEq, Debug)]
struct ConstRand(usize);
8 changes: 4 additions & 4 deletions src/librand/distributions/normal.rs
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@
#[cfg(not(test))] // only necessary for no_std
use FloatMath;

use {Rng, Rand, Open01};
use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
use {Open01, Rand, Rng};
use distributions::{IndependentSample, Sample, ziggurat, ziggurat_tables};

/// A wrapper around an `f64` to generate N(0, 1) random numbers
/// (a.k.a. a standard normal, or Gaussian).
@@ -145,8 +145,8 @@ impl IndependentSample<f64> for LogNormal {

#[cfg(test)]
mod tests {
use distributions::{Sample, IndependentSample};
use super::{Normal, LogNormal};
use distributions::{IndependentSample, Sample};
use super::{LogNormal, Normal};

#[test]
fn test_normal() {
4 changes: 2 additions & 2 deletions src/librand/distributions/range.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@

use core::marker::Sized;
use Rng;
use distributions::{Sample, IndependentSample};
use distributions::{IndependentSample, Sample};

/// Sample values uniformly between two bounds.
///
@@ -148,7 +148,7 @@ float_impl! { f64 }

#[cfg(test)]
mod tests {
use distributions::{Sample, IndependentSample};
use distributions::{IndependentSample, Sample};
use super::Range;

#[should_panic]
16 changes: 10 additions & 6 deletions src/librand/isaac.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use core::slice;
use core::iter::repeat;
use core::num::Wrapping as w;

use {Rng, SeedableRng, Rand};
use {Rand, Rng, SeedableRng};

type w32 = w<u32>;
type w64 = w<u64>;
@@ -591,22 +591,24 @@ mod tests {
use std::prelude::v1::*;

use {Rng, SeedableRng};
use super::{IsaacRng, Isaac64Rng};
use super::{Isaac64Rng, IsaacRng};

#[test]
fn test_rng_32_rand_seeded() {
let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
let mut ra: IsaacRng = SeedableRng::from_seed(&s[..]);
let mut rb: IsaacRng = SeedableRng::from_seed(&s[..]);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}
#[test]
fn test_rng_64_rand_seeded() {
let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
let mut ra: Isaac64Rng = SeedableRng::from_seed(&s[..]);
let mut rb: Isaac64Rng = SeedableRng::from_seed(&s[..]);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}

@@ -615,15 +617,17 @@ mod tests {
let seed: &[_] = &[1, 23, 456, 7890, 12345];
let mut ra: IsaacRng = SeedableRng::from_seed(seed);
let mut rb: IsaacRng = SeedableRng::from_seed(seed);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}
#[test]
fn test_rng_64_seeded() {
let seed: &[_] = &[1, 23, 456, 7890, 12345];
let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}

10 changes: 5 additions & 5 deletions src/librand/lib.rs
Original file line number Diff line number Diff line change
@@ -47,10 +47,10 @@ use core::f64;
use core::intrinsics;
use core::marker::PhantomData;

pub use isaac::{IsaacRng, Isaac64Rng};
pub use isaac::{Isaac64Rng, IsaacRng};
pub use chacha::ChaChaRng;

use distributions::{Range, IndependentSample};
use distributions::{IndependentSample, Range};
use distributions::range::SampleRange;

#[cfg(test)]
@@ -67,7 +67,7 @@ mod rand_impls;
// depend on libstd. This will go away when librand is integrated
// into libstd.
#[doc(hidden)]
trait FloatMath : Sized {
trait FloatMath: Sized {
fn exp(self) -> Self;
fn ln(self) -> Self;
fn sqrt(self) -> Self;
@@ -102,14 +102,14 @@ impl FloatMath for f64 {

/// A type that can be randomly generated using an `Rng`.
#[doc(hidden)]
pub trait Rand : Sized {
pub trait Rand: Sized {
/// Generates a random instance of this type using the specified source of
/// randomness.
fn rand<R: Rng>(rng: &mut R) -> Self;
}

/// A random number generator.
pub trait Rng : Sized {
pub trait Rng: Sized {
/// Return the next random u32.
///
/// This rarely needs to be called directly, prefer `r.gen()` to
11 changes: 6 additions & 5 deletions src/librand/reseeding.rs
Original file line number Diff line number Diff line change
@@ -83,8 +83,8 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
self.bytes_generated = 0;
}

/// Create a new `ReseedingRng` from the given reseeder and
/// seed. This uses a default value for `generation_threshold`.
/// Create a new `ReseedingRng` from the given reseeder and
/// seed. This uses a default value for `generation_threshold`.
fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
ReseedingRng {
rng: SeedableRng::from_seed(seed),
@@ -122,8 +122,8 @@ impl Default for ReseedWithDefault {
mod tests {
use std::prelude::v1::*;

use super::{ReseedingRng, ReseedWithDefault};
use {SeedableRng, Rng};
use super::{ReseedWithDefault, ReseedingRng};
use {Rng, SeedableRng};

struct Counter {
i: u32,
@@ -166,7 +166,8 @@ mod tests {
fn test_rng_seeded() {
let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
assert!(ra.gen_ascii_chars().take(100)
assert!(ra.gen_ascii_chars()
.take(100)
.eq(rb.gen_ascii_chars().take(100)));
}

76 changes: 72 additions & 4 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,8 @@ remainder of a zero divisor) in a static or constant expression. Erroneous
code example:
```compile_fail
#[deny(const_err)]
const X: i32 = 42 / 0;
// error: attempted to divide by zero in a constant expression
```
@@ -66,7 +68,7 @@ this restriction.
This happens when a trait has a method like the following:
```compile_fail
```
trait Trait {
fn foo(&self) -> Self;
}
@@ -364,6 +366,18 @@ type X = u32; // ok!
"##,

E0133: r##"
Unsafe code was used outside of an unsafe function or block.
Erroneous code example:
```compile_fail
unsafe fn f() { return; } // This is the unsafe code
fn main() {
f(); // error: call to unsafe function requires unsafe function or block
}
```
Using unsafe functionality is potentially dangerous and disallowed by safety
checks. Examples:
@@ -378,7 +392,7 @@ unsafe instructions with an `unsafe` block. For instance:
unsafe fn f() { return; }
fn main() {
unsafe { f(); }
unsafe { f(); } // ok!
}
```
@@ -392,15 +406,58 @@ function `main()`. If there are multiple such functions, please rename one.
"##,

E0137: r##"
More than one function was declared with the `#[main]` attribute.
Erroneous code example:
```compile_fail
#![feature(main)]
#[main]
fn foo() {}
#[main]
fn f() {} // error: multiple functions with a #[main] attribute
```
This error indicates that the compiler found multiple functions with the
`#[main]` attribute. This is an error because there must be a unique entry
point into a Rust program.
point into a Rust program. Example:
```
#![feature(main)]
#[main]
fn f() {} // ok!
```
"##,

E0138: r##"
More than one function was declared with the `#[start]` attribute.
Erroneous code example:
```compile_fail
#![feature(start)]
#[start]
fn foo(argc: isize, argv: *const *const u8) -> isize {}
#[start]
fn f(argc: isize, argv: *const *const u8) -> isize {}
// error: multiple 'start' functions
```
This error indicates that the compiler found multiple functions with the
`#[start]` attribute. This is an error because there must be a unique entry
point into a Rust program.
point into a Rust program. Example:
```
#![feature(start)]
#[start]
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
```
"##,

// FIXME link this to the relevant turpl chapters for instilling fear of the
@@ -481,6 +538,17 @@ call to `mem::forget(v)` in case you want to avoid destructors being called.
"##,

E0152: r##"
A lang item was redefined.
Erroneous code example:
```compile_fail
#![feature(lang_items)]
#[lang = "panic_fmt"]
struct Foo; // error: duplicate lang item found: `panic_fmt`
```
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.
2 changes: 1 addition & 1 deletion src/librustc_borrowck/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ structure that is currently uninitialized.
For example, this can happen when a drop has taken place:
```compile_fail
```ignore
struct Foo {
a: u32,
}
4 changes: 3 additions & 1 deletion src/librustc_const_eval/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -76,6 +76,8 @@ Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. So, the following will not compile:
```compile_fail
#![deny(illegal_floating_point_constant_pattern)]
const NAN: f32 = 0.0 / 0.0;
let number = 0.1f32;
@@ -160,7 +162,7 @@ let Some(y) = x;
If you encounter this error you probably need to use a `match` or `if let` to
deal with the possibility of failure. Example:
```compile_fail
```
let x = Some(1);
match x {
166 changes: 97 additions & 69 deletions src/librustc_lint/bad_style.rs
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@

use rustc::hir::def::Def;
use rustc::ty;
use lint::{LateContext, LintContext, LintArray};
use lint::{LintPass, LateLintPass};
use lint::{LateContext, LintArray, LintContext};
use lint::{LateLintPass, LintPass};

use syntax::ast;
use syntax::attr::{self, AttrMetaMethods};
@@ -24,19 +24,21 @@ use rustc::hir::intravisit::FnKind;
pub enum MethodLateContext {
TraitDefaultImpl,
TraitImpl,
PlainImpl
PlainImpl,
}

pub fn method_context(cx: &LateContext, id: ast::NodeId, span: Span) -> MethodLateContext {
let def_id = cx.tcx.map.local_def_id(id);
match cx.tcx.impl_or_trait_items.borrow().get(&def_id) {
None => span_bug!(span, "missing method descriptor?!"),
Some(item) => match item.container() {
ty::TraitContainer(..) => MethodLateContext::TraitDefaultImpl,
ty::ImplContainer(cid) => {
match cx.tcx.impl_trait_ref(cid) {
Some(_) => MethodLateContext::TraitImpl,
None => MethodLateContext::PlainImpl
Some(item) => {
match item.container() {
ty::TraitContainer(..) => MethodLateContext::TraitDefaultImpl,
ty::ImplContainer(cid) => {
match cx.tcx.impl_trait_ref(cid) {
Some(_) => MethodLateContext::TraitImpl,
None => MethodLateContext::PlainImpl,
}
}
}
}
@@ -63,29 +65,37 @@ impl NonCamelCaseTypes {

// start with a non-lowercase letter rather than non-uppercase
// ones (some scripts don't have a concept of upper/lowercase)
!name.is_empty() &&
!name.chars().next().unwrap().is_lowercase() &&
!name.contains('_')
!name.is_empty() && !name.chars().next().unwrap().is_lowercase() && !name.contains('_')
}

fn to_camel_case(s: &str) -> String {
s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
if i == 0 {
c.to_uppercase().collect::<String>()
} else {
c.to_lowercase().collect()
}
)).collect::<Vec<_>>().concat()
s.split('_')
.flat_map(|word| {
word.chars().enumerate().map(|(i, c)| {
if i == 0 {
c.to_uppercase().collect::<String>()
} else {
c.to_lowercase().collect()
}
})
})
.collect::<Vec<_>>()
.concat()
}

let s = name.as_str();

if !is_camel_case(name) {
let c = to_camel_case(&s);
let m = if c.is_empty() {
format!("{} `{}` should have a camel case name such as `CamelCase`", sort, s)
format!("{} `{}` should have a camel case name such as `CamelCase`",
sort,
s)
} else {
format!("{} `{}` should have a camel case name such as `{}`", sort, s, c)
format!("{} `{}` should have a camel case name such as `{}`",
sort,
s,
c)
};
cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
}
@@ -100,23 +110,23 @@ impl LintPass for NonCamelCaseTypes {

impl LateLintPass for NonCamelCaseTypes {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
let extern_repr_count = it.attrs.iter().filter(|attr| {
attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter()
.any(|r| r == &attr::ReprExtern)
}).count();
let extern_repr_count = it.attrs
.iter()
.filter(|attr| {
attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr)
.iter()
.any(|r| r == &attr::ReprExtern)
})
.count();
let has_extern_repr = extern_repr_count > 0;

if has_extern_repr {
return;
}

match it.node {
hir::ItemTy(..) | hir::ItemStruct(..) => {
self.check_case(cx, "type", it.name, it.span)
}
hir::ItemTrait(..) => {
self.check_case(cx, "trait", it.name, it.span)
}
hir::ItemTy(..) | hir::ItemStruct(..) => self.check_case(cx, "type", it.name, it.span),
hir::ItemTrait(..) => self.check_case(cx, "trait", it.name, it.span),
hir::ItemEnum(ref enum_definition, _) => {
if has_extern_repr {
return;
@@ -126,7 +136,7 @@ impl LateLintPass for NonCamelCaseTypes {
self.check_case(cx, "variant", variant.node.name, variant.span);
}
}
_ => ()
_ => (),
}
}

@@ -165,9 +175,7 @@ impl NonSnakeCase {
continue;
}
for ch in s.chars() {
if !buf.is_empty() && buf != "'"
&& ch.is_uppercase()
&& !last_upper {
if !buf.is_empty() && buf != "'" && ch.is_uppercase() && !last_upper {
words.push(buf);
buf = String::new();
}
@@ -205,10 +213,11 @@ impl NonSnakeCase {
let sc = NonSnakeCase::to_snake_case(name);
let msg = if sc != name {
format!("{} `{}` should have a snake case name such as `{}`",
sort, name, sc)
sort,
name,
sc)
} else {
format!("{} `{}` should have a snake case name",
sort, name)
format!("{} `{}` should have a snake case name", sort, name)
};
match span {
Some(span) => cx.span_lint(NON_SNAKE_CASE, span, &msg),
@@ -226,31 +235,39 @@ impl LintPass for NonSnakeCase {

impl LateLintPass for NonSnakeCase {
fn check_crate(&mut self, cx: &LateContext, cr: &hir::Crate) {
let attr_crate_name = cr.attrs.iter().find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
let attr_crate_name = cr.attrs
.iter()
.find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(ref name) = cx.tcx.sess.opts.crate_name {
self.check_snake_case(cx, "crate", name, None);
} else if let Some((attr, ref name)) = attr_crate_name {
self.check_snake_case(cx, "crate", name, Some(attr.span));
}
}

fn check_fn(&mut self, cx: &LateContext,
fk: FnKind, _: &hir::FnDecl,
_: &hir::Block, span: Span, id: ast::NodeId) {
fn check_fn(&mut self,
cx: &LateContext,
fk: FnKind,
_: &hir::FnDecl,
_: &hir::Block,
span: Span,
id: ast::NodeId) {
match fk {
FnKind::Method(name, _, _, _) => match method_context(cx, id, span) {
MethodLateContext::PlainImpl => {
self.check_snake_case(cx, "method", &name.as_str(), Some(span))
},
MethodLateContext::TraitDefaultImpl => {
self.check_snake_case(cx, "trait method", &name.as_str(), Some(span))
},
_ => (),
},
FnKind::Method(name, _, _, _) => {
match method_context(cx, id, span) {
MethodLateContext::PlainImpl => {
self.check_snake_case(cx, "method", &name.as_str(), Some(span))
}
MethodLateContext::TraitDefaultImpl => {
self.check_snake_case(cx, "trait method", &name.as_str(), Some(span))
}
_ => (),
}
}
FnKind::ItemFn(name, _, _, _, _, _, _) => {
self.check_snake_case(cx, "function", &name.as_str(), Some(span))
},
}
FnKind::Closure(_) => (),
}
}
@@ -263,13 +280,17 @@ impl LateLintPass for NonSnakeCase {

fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
if let hir::MethodTraitItem(_, None) = trait_item.node {
self.check_snake_case(cx, "trait method", &trait_item.name.as_str(),
self.check_snake_case(cx,
"trait method",
&trait_item.name.as_str(),
Some(trait_item.span));
}
}

fn check_lifetime_def(&mut self, cx: &LateContext, t: &hir::LifetimeDef) {
self.check_snake_case(cx, "lifetime", &t.lifetime.name.as_str(),
self.check_snake_case(cx,
"lifetime",
&t.lifetime.name.as_str(),
Some(t.lifetime.span));
}

@@ -282,8 +303,12 @@ impl LateLintPass for NonSnakeCase {
}
}

fn check_struct_def(&mut self, cx: &LateContext, s: &hir::VariantData,
_: ast::Name, _: &hir::Generics, _: ast::NodeId) {
fn check_struct_def(&mut self,
cx: &LateContext,
s: &hir::VariantData,
_: ast::Name,
_: &hir::Generics,
_: ast::NodeId) {
for sf in s.fields() {
self.check_snake_case(cx, "structure field", &sf.name.as_str(), Some(sf.span));
}
@@ -306,13 +331,16 @@ impl NonUpperCaseGlobals {
if s.chars().any(|c| c.is_lowercase()) {
let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
if uc != &s[..] {
cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
&format!("{} `{}` should have an upper case name such as `{}`",
sort, s, uc));
cx.span_lint(NON_UPPER_CASE_GLOBALS,
span,
&format!("{} `{}` should have an upper case name such as `{}`",
sort,
s,
uc));
} else {
cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
&format!("{} `{}` should have an upper case name",
sort, s));
cx.span_lint(NON_UPPER_CASE_GLOBALS,
span,
&format!("{} `{}` should have an upper case name", sort, s));
}
}
}
@@ -341,8 +369,7 @@ impl LateLintPass for NonUpperCaseGlobals {
fn check_trait_item(&mut self, cx: &LateContext, ti: &hir::TraitItem) {
match ti.node {
hir::ConstTraitItem(..) => {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
ti.name, ti.span);
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", ti.name, ti.span);
}
_ => {}
}
@@ -351,8 +378,7 @@ impl LateLintPass for NonUpperCaseGlobals {
fn check_impl_item(&mut self, cx: &LateContext, ii: &hir::ImplItem) {
match ii.node {
hir::ImplItemKind::Const(..) => {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
ii.name, ii.span);
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", ii.name, ii.span);
}
_ => {}
}
@@ -362,8 +388,10 @@ impl LateLintPass for NonUpperCaseGlobals {
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
(&PatKind::Ident(_, ref path1, _), Some(Def::Const(..))) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
path1.node, p.span);
NonUpperCaseGlobals::check_upper_case(cx,
"constant in pattern",
path1.node,
p.span);
}
_ => {}
}
328 changes: 190 additions & 138 deletions src/librustc_lint/builtin.rs

Large diffs are not rendered by default.

42 changes: 28 additions & 14 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
@@ -46,10 +46,10 @@ extern crate log;
extern crate rustc_back;
extern crate rustc_const_eval;

pub use rustc::lint as lint;
pub use rustc::middle as middle;
pub use rustc::session as session;
pub use rustc::util as util;
pub use rustc::lint;
pub use rustc::middle;
pub use rustc::session;
pub use rustc::util;

use session::Session;
use lint::LintId;
@@ -136,13 +136,24 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
MissingDebugImplementations,
);

add_lint_group!(sess, "bad_style",
NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS);

add_lint_group!(sess, "unused",
UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
UNUSED_UNSAFE, PATH_STATEMENTS, UNUSED_ATTRIBUTES);
add_lint_group!(sess,
"bad_style",
NON_CAMEL_CASE_TYPES,
NON_SNAKE_CASE,
NON_UPPER_CASE_GLOBALS);

add_lint_group!(sess,
"unused",
UNUSED_IMPORTS,
UNUSED_VARIABLES,
UNUSED_ASSIGNMENTS,
DEAD_CODE,
UNUSED_MUT,
UNREACHABLE_CODE,
UNUSED_MUST_USE,
UNUSED_UNSAFE,
PATH_STATEMENTS,
UNUSED_ATTRIBUTES);

// Guidelines for creating a future incompatibility lint:
//
@@ -152,7 +163,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
// and include the full URL.
// - Later, change lint to error
// - Eventually, remove lint
store.register_future_incompatible(sess, vec![
store.register_future_incompatible(sess,
vec![
FutureIncompatibleInfo {
id: LintId::of(PRIVATE_IN_PUBLIC),
reference: "the explanation for E0446 (`--explain E0446`)",
@@ -209,10 +221,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {

// Register renamed and removed lints
store.register_renamed("unknown_features", "unused_features");
store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
store.register_removed("unsigned_negation",
"replaced by negate_unsigned feature gate");
store.register_removed("negate_unsigned", "cast a signed value instead");
store.register_removed("raw_pointer_derive", "using derive with raw pointers is ok");
// This was renamed to raw_pointer_derive, which was then removed,
// so it is also considered removed
store.register_removed("raw_pointer_deriving", "using derive with raw pointers is ok");
store.register_removed("raw_pointer_deriving",
"using derive with raw pointers is ok");
}
278 changes: 153 additions & 125 deletions src/librustc_lint/types.rs

Large diffs are not rendered by default.

129 changes: 75 additions & 54 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@ use rustc::hir::pat_util;
use rustc::ty;
use rustc::ty::adjustment;
use util::nodemap::FnvHashMap;
use lint::{LateContext, EarlyContext, LintContext, LintArray};
use lint::{LintPass, EarlyLintPass, LateLintPass};
use lint::{EarlyContext, LateContext, LintArray, LintContext};
use lint::{EarlyLintPass, LateLintPass, LintPass};

use std::collections::hash_map::Entry::{Occupied, Vacant};

use syntax::ast;
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span;
use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
use syntax::feature_gate::{AttributeType, KNOWN_ATTRIBUTES};
use syntax::ptr::P;

use rustc_back::slice;
@@ -48,8 +48,12 @@ impl UnusedMut {
if let hir::BindByValue(hir::MutMutable) = mode {
if !name.as_str().starts_with("_") {
match mutables.entry(name.0 as usize) {
Vacant(entry) => { entry.insert(vec![id]); },
Occupied(mut entry) => { entry.get_mut().push(id); },
Vacant(entry) => {
entry.insert(vec![id]);
}
Occupied(mut entry) => {
entry.get_mut().push(id);
}
}
}
}
@@ -59,7 +63,8 @@ impl UnusedMut {
let used_mutables = cx.tcx.used_mut_nodes.borrow();
for (_, v) in &mutables {
if !v.iter().any(|e| used_mutables.contains(e)) {
cx.span_lint(UNUSED_MUT, cx.tcx.map.span(v[0]),
cx.span_lint(UNUSED_MUT,
cx.tcx.map.span(v[0]),
"variable does not need to be mutable");
}
}
@@ -89,9 +94,13 @@ impl LateLintPass for UnusedMut {
}
}

fn check_fn(&mut self, cx: &LateContext,
_: FnKind, decl: &hir::FnDecl,
_: &hir::Block, _: Span, _: ast::NodeId) {
fn check_fn(&mut self,
cx: &LateContext,
_: FnKind,
decl: &hir::FnDecl,
_: &hir::Block,
_: Span,
_: ast::NodeId) {
for a in &decl.inputs {
self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
}
@@ -123,7 +132,7 @@ impl LateLintPass for UnusedResults {
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
let expr = match s.node {
hir::StmtSemi(ref expr, _) => &**expr,
_ => return
_ => return,
};

if let hir::ExprRet(..) = expr.node {
@@ -186,8 +195,8 @@ impl LateLintPass for UnusedUnsafe {
if let hir::ExprBlock(ref blk) = e.node {
// Don't warn about generated blocks, that'll just pollute the output.
if blk.rules == hir::UnsafeBlock(hir::UserProvided) &&
!cx.tcx.used_unsafe.borrow().contains(&blk.id) {
cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
!cx.tcx.used_unsafe.borrow().contains(&blk.id) {
cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
}
}
}
@@ -212,8 +221,7 @@ impl LateLintPass for PathStatements {
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
if let hir::StmtSemi(ref expr, _) = s.node {
if let hir::ExprPath(..) = expr.node {
cx.span_lint(PATH_STATEMENTS, s.span,
"path statement with no effect");
cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect");
}
}
}
@@ -241,8 +249,8 @@ impl LateLintPass for UnusedAttributes {
match ty {
AttributeType::Whitelisted if attr.check_name(name) => {
break;
},
_ => ()
}
_ => (),
}
}

@@ -256,24 +264,31 @@ impl LateLintPass for UnusedAttributes {
if !attr::is_used(attr) {
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
// Is it a builtin attribute that must be used at the crate level?
let known_crate = KNOWN_ATTRIBUTES.iter().find(|&&(name, ty, _)| {
attr.name() == name &&
ty == AttributeType::CrateLevel
}).is_some();
let known_crate = KNOWN_ATTRIBUTES.iter()
.find(|&&(name, ty, _)| {
attr.name() == name &&
ty == AttributeType::CrateLevel
})
.is_some();

// Has a plugin registered this attribute as one which must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
.find(|&&(ref x, t)| {
&*attr.name() == x &&
AttributeType::CrateLevel == t
}).is_some();
if known_crate || plugin_crate {
&*attr.name() == x &&
AttributeType::CrateLevel == t
})
.is_some();
if known_crate || plugin_crate {
let msg = match attr.node.style {
ast::AttrStyle::Outer => "crate-level attribute should be an inner \
attribute: add an exclamation mark: #![foo]",
ast::AttrStyle::Inner => "crate-level attribute should be in the \
root module",
ast::AttrStyle::Outer => {
"crate-level attribute should be an inner \
attribute: add an exclamation mark: #![foo]"
}
ast::AttrStyle::Inner => {
"crate-level attribute should be in the \
root module"
}
};
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, msg);
}
@@ -291,12 +306,16 @@ declare_lint! {
pub struct UnusedParens;

impl UnusedParens {
fn check_unused_parens_core(&self, cx: &EarlyContext, value: &ast::Expr, msg: &str,
fn check_unused_parens_core(&self,
cx: &EarlyContext,
value: &ast::Expr,
msg: &str,
struct_lit_needs_parens: bool) {
if let ast::ExprKind::Paren(ref inner) = value.node {
let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&inner);
if !necessary {
cx.span_lint(UNUSED_PARENS, value.span,
cx.span_lint(UNUSED_PARENS,
value.span,
&format!("unnecessary parentheses around {}", msg))
}
}
@@ -314,8 +333,7 @@ impl UnusedParens {
ast::ExprKind::AssignOp(_, ref lhs, ref rhs) |
ast::ExprKind::Binary(_, ref lhs, ref rhs) => {
// X { y: 1 } + X { y: 2 }
contains_exterior_struct_lit(&lhs) ||
contains_exterior_struct_lit(&rhs)
contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
}
ast::ExprKind::Unary(_, ref x) |
ast::ExprKind::Cast(ref x, _) |
@@ -332,7 +350,7 @@ impl UnusedParens {
contains_exterior_struct_lit(&exprs[0])
}

_ => false
_ => false,
}
}
}
@@ -358,21 +376,25 @@ impl EarlyLintPass for UnusedParens {
Assign(_, ref value) => (value, "assigned value", false),
AssignOp(_, _, ref value) => (value, "assigned value", false),
InPlace(_, ref value) => (value, "emplacement value", false),
_ => return
_ => return,
};
self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
}

fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
let (value, msg) = match s.node {
ast::StmtKind::Decl(ref decl, _) => match decl.node {
ast::DeclKind::Local(ref local) => match local.init {
Some(ref value) => (value, "assigned value"),
None => return
},
_ => return
},
_ => return
ast::StmtKind::Decl(ref decl, _) => {
match decl.node {
ast::DeclKind::Local(ref local) => {
match local.init {
Some(ref value) => (value, "assigned value"),
None => return,
}
}
_ => return,
}
}
_ => return,
};
self.check_unused_parens_core(cx, &value, msg, false);
}
@@ -398,11 +420,9 @@ impl LateLintPass for UnusedImportBraces {
if let hir::ItemUse(ref view_path) = item.node {
if let hir::ViewPathList(_, ref items) = view_path.node {
if items.len() == 1 {
if let hir::PathListIdent {ref name, ..} = items[0].node {
let m = format!("braces around {} is unnecessary",
name);
cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
&m[..]);
if let hir::PathListIdent { ref name, .. } = items[0].node {
let m = format!("braces around {} is unnecessary", name);
cx.span_lint(UNUSED_IMPORT_BRACES, item.span, &m[..]);
}
}
}
@@ -429,23 +449,24 @@ impl LateLintPass for UnusedAllocation {
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
match e.node {
hir::ExprBox(_) => {}
_ => return
_ => return,
}

if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
if let adjustment::AdjustDerefRef(adjustment::AutoDerefRef {
ref autoref, ..
}) = *adjustment {
if let adjustment::AdjustDerefRef(adjustment::AutoDerefRef { ref autoref, .. }) =
*adjustment {
match autoref {
&Some(adjustment::AutoPtr(_, hir::MutImmutable)) => {
cx.span_lint(UNUSED_ALLOCATION, e.span,
cx.span_lint(UNUSED_ALLOCATION,
e.span,
"unnecessary allocation, use & instead");
}
&Some(adjustment::AutoPtr(_, hir::MutMutable)) => {
cx.span_lint(UNUSED_ALLOCATION, e.span,
cx.span_lint(UNUSED_ALLOCATION,
e.span,
"unnecessary allocation, use &mut instead");
}
_ => ()
_ => (),
}
}
}
27 changes: 26 additions & 1 deletion src/librustc_passes/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -50,11 +50,36 @@ match 5u32 {
"##,

E0161: r##"
A value was moved. However, its size was not known at compile time, and only
values of a known size can be moved.
Erroneous code example:
```compile_fail
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<[isize]> = box *array;
// error: cannot move a value of type [isize]: the size of [isize] cannot
// be statically determined
}
```
In Rust, you can only move a value when its size is known at compile time.
To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
it around as usual. Example:
```
#![feature(box_syntax)]
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<&[isize]> = box array; // ok!
}
```
"##,

E0265: r##"
6 changes: 5 additions & 1 deletion src/librustc_privacy/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@ A private trait was used on a public type parameter bound. Erroneous code
examples:
```compile_fail
#![deny(private_in_public)]
trait Foo {
fn dummy(&self) { }
}
@@ -45,6 +47,8 @@ E0446: r##"
A private type was used in a public type signature. Erroneous code example:
```compile_fail
#![deny(private_in_public)]
mod Foo {
struct Bar(u32);
@@ -73,7 +77,7 @@ mod Foo {
E0447: r##"
The `pub` keyword was used inside a function. Erroneous code example:
```compile_fail
```ignore
fn foo() {
pub struct Bar; // error: visibility has no effect inside functions
}
2 changes: 1 addition & 1 deletion src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ variable declarations and expression statements.
Here is an example that demonstrates the error:
```compile_fail
```ignore
fn f() {
// Variable declaration before import
let x = 0;
4 changes: 2 additions & 2 deletions src/librustc_trans/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ register_long_diagnostics! {
E0510: r##"
`return_address` was used in an invalid context. Erroneous code example:
```compile_fail
```ignore
#![feature(intrinsics)]
extern "rust-intrinsic" {
@@ -54,7 +54,7 @@ E0511: r##"
Invalid monomorphization of an intrinsic function was used. Erroneous code
example:
```compile_fail
```ignore
#![feature(platform_intrinsics)]
extern "platform-intrinsic" {
38 changes: 31 additions & 7 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -931,7 +931,7 @@ first instance of `Foo` could be made to initialize another instance!
Here's an example of a struct that has this problem:
```compile_fail
```ignore
struct Foo { x: Box<Foo> } // error
```
@@ -952,7 +952,7 @@ are generic.
This will cause an error:
```compile_fail
```ignore
#![feature(repr_simd)]
#[repr(simd)]
@@ -1143,7 +1143,7 @@ for an explicit choice of the discriminant type. In either cases, the
discriminant values must fall within a valid range for the expected type;
otherwise this error is raised. For example:
```compile_fail
```ignore
#[repr(u8)]
enum Thing {
A = 1024,
@@ -1154,7 +1154,7 @@ enum Thing {
Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is
invalid. Here is another, more subtle example which depends on target word size:
```compile_fail
```ignore
enum DependsOnPointerSize {
A = 1 << 32
}
@@ -1864,12 +1864,35 @@ fn main<T>() { // error: main function is not allowed to have type parameters
"##,

E0132: r##"
A function with the `start` attribute was declared with type parameters.
Erroneous code example:
```compile_fail
#![feature(start)]
#[start]
fn f<T>() {}
```
It is not possible to declare type parameters on a function that has the `start`
attribute. Such a function must have the following type signature:
attribute. Such a function must have the following type signature (for more
information: http://doc.rust-lang.org/stable/book/no-stdlib.html):
```ignore
fn(isize, *const *const u8) -> isize;
```
Example:
```
#![feature(start)]
#[start]
fn my_start(argc: isize, argv: *const *const u8) -> isize {
0
}
```
"##,

E0163: r##"
@@ -2076,7 +2099,7 @@ E0193: r##"
`where` clauses must use generic type parameters: it does not make sense to use
them otherwise. An example causing this error:
```compile_fail
```ignore
trait Foo {
fn bar(&self);
}
@@ -3140,7 +3163,7 @@ An attempt was made to access an associated constant through either a generic
type parameter or `Self`. This is not supported yet. An example causing this
error is shown below:
```compile_fail
```ignore
#![feature(associated_consts)]
trait Foo {
@@ -3327,6 +3350,7 @@ The maximum value of an enum was reached, so it cannot be automatically
set in the next enum value. Erroneous code example:
```compile_fail
#[deny(overflowing_literals)]
enum Foo {
X = 0x7fffffffffffffff,
Y, // error: enum discriminant overflowed on value after
8 changes: 6 additions & 2 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
@@ -271,8 +271,12 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
match res {
Ok(r) => {
match r {
Err(count) if count > 0 && compile_fail == false => {
sess.fatal("aborting due to previous error(s)")
Err(count) => {
if count > 0 && compile_fail == false {
sess.fatal("aborting due to previous error(s)")
} else if count == 0 && compile_fail == true {
panic!("test compiled while it wasn't supposed to")
}
}
Ok(()) if compile_fail => panic!("test compiled while it wasn't supposed to"),
_ => {}
1 change: 0 additions & 1 deletion src/libunwind/lib.rs
Original file line number Diff line number Diff line change
@@ -27,4 +27,3 @@ extern crate libc;
mod libunwind;
#[cfg(not(target_env = "msvc"))]
pub use libunwind::*;

47 changes: 20 additions & 27 deletions src/libunwind/libunwind.rs
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ pub enum _Unwind_State {
_US_UNWIND_FRAME_RESUME = 2,
_US_ACTION_MASK = 3,
_US_FORCE_UNWIND = 8,
_US_END_OF_STACK = 16
_US_END_OF_STACK = 16,
}

#[repr(C)]
@@ -59,9 +59,8 @@ pub type _Unwind_Exception_Class = u64;

pub type _Unwind_Word = libc::uintptr_t;

pub type _Unwind_Trace_Fn =
extern fn(ctx: *mut _Unwind_Context,
arg: *mut libc::c_void) -> _Unwind_Reason_Code;
pub type _Unwind_Trace_Fn = extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut libc::c_void)
-> _Unwind_Reason_Code;

#[cfg(target_arch = "x86")]
pub const unwinder_private_data_size: usize = 5;
@@ -97,9 +96,8 @@ pub struct _Unwind_Exception {

pub enum _Unwind_Context {}

pub type _Unwind_Exception_Cleanup_Fn =
extern "C" fn(unwind_code: _Unwind_Reason_Code,
exception: *mut _Unwind_Exception);
pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
exception: *mut _Unwind_Exception);

#[cfg_attr(any(all(target_os = "linux", not(target_env = "musl")),
target_os = "freebsd",
@@ -127,20 +125,18 @@ pub type _Unwind_Exception_Cleanup_Fn =
#[cfg_attr(all(target_os = "windows", target_env = "gnu"),
link(name = "gcc_eh"))]
#[cfg(not(cargobuild))]
extern {}
extern "C" {}

extern {
extern "C" {
// iOS on armv7 uses SjLj exceptions and requires to link
// against corresponding routine (..._SjLj_...)
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
#[unwind]
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;

#[cfg(all(target_os = "ios", target_arch = "arm"))]
#[unwind]
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;

pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);

@@ -151,28 +147,26 @@ extern {
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
trace_argument: *mut libc::c_void)
-> _Unwind_Reason_Code;
-> _Unwind_Reason_Code;

// available since GCC 4.2.0, should be fine for our purpose
#[cfg(all(not(all(target_os = "android", target_arch = "arm")),
not(all(target_os = "linux", target_arch = "arm"))))]
pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
ip_before_insn: *mut libc::c_int)
-> libc::uintptr_t;
-> libc::uintptr_t;

#[cfg(all(not(target_os = "android"),
not(all(target_os = "linux", target_arch = "arm"))))]
pub fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-> *mut libc::c_void;
pub fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void) -> *mut libc::c_void;
}

// ... and now we just providing access to SjLj counterspart
// through a standard name to hide those details from others
// (see also comment above regarding _Unwind_RaiseException)
#[cfg(all(target_os = "ios", target_arch = "arm"))]
#[inline]
pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception)
-> _Unwind_Reason_Code {
pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
_Unwind_SjLj_RaiseException(exc)
}

@@ -207,18 +201,20 @@ pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
}

type _Unwind_Word = libc::c_uint;
extern {
extern "C" {
fn _Unwind_VRS_Get(ctx: *mut _Unwind_Context,
klass: _Unwind_VRS_RegClass,
word: _Unwind_Word,
repr: _Unwind_VRS_DataRepresentation,
data: *mut libc::c_void)
-> _Unwind_VRS_Result;
-> _Unwind_VRS_Result;
}

let mut val: _Unwind_Word = 0;
let ptr = &mut val as *mut _Unwind_Word;
let _ = _Unwind_VRS_Get(ctx, _Unwind_VRS_RegClass::_UVRSC_CORE, 15,
let _ = _Unwind_VRS_Get(ctx,
_Unwind_VRS_RegClass::_UVRSC_CORE,
15,
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
ptr as *mut libc::c_void);
(val & !1) as libc::uintptr_t
@@ -230,8 +226,7 @@ pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
ip_before_insn: *mut libc::c_int)
-> libc::uintptr_t
{
-> libc::uintptr_t {
*ip_before_insn = 0;
_Unwind_GetIP(ctx)
}
@@ -240,8 +235,6 @@ pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
// a no-op
#[cfg(any(target_os = "android",
all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-> *mut libc::c_void
{
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void) -> *mut libc::c_void {
pc
}