Auto merge of #28052 - Manishearth:rollup, r=Manishearth

- Successful merges: #28010, #28013, #28022, #28029, #28033, #28039, #28045, #28048
- Failed merges:
This commit is contained in:
bors 2015-08-27 23:25:38 +00:00
commit 8dba06aeee
21 changed files with 430 additions and 145 deletions

View file

@ -120,13 +120,26 @@ And that's reflected in the summary line:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
``` ```
We also get a non-zero status code: We also get a non-zero status code. We can use `$?` on OS X and Linux:
```bash ```bash
$ echo $? $ echo $?
101 101
``` ```
On Windows, if youre using `cmd`:
```bash
> echo %ERRORLEVEL%
```
And if youre using PowerShell:
```bash
> echo $LASTEXITCODE # the code itself
> echo $? # a boolean, fail or succeed
```
This is useful if you want to integrate `cargo test` into other tooling. This is useful if you want to integrate `cargo test` into other tooling.
We can invert our test's failure with another attribute: `should_panic`: We can invert our test's failure with another attribute: `should_panic`:

View file

@ -254,6 +254,51 @@ macro_rules! unreachable {
/// A standardised placeholder for marking unfinished code. It panics with the /// A standardised placeholder for marking unfinished code. It panics with the
/// message `"not yet implemented"` when executed. /// message `"not yet implemented"` when executed.
///
/// This can be useful if you are prototyping and are just looking to have your
/// code typecheck, or if you're implementing a trait that requires multiple
/// methods, and you're only planning on using one of them.
///
/// # Examples
///
/// Here's an example of some in-progress code. We have a trait `Foo`:
///
/// ```
/// trait Foo {
/// fn bar(&self);
/// fn baz(&self);
/// }
/// ```
///
/// We want to implement `Foo` on one of our types, but we also want to work on
/// just `bar()` first. In order for our code to compile, we need to implement
/// `baz()`, so we can use `unimplemented!`:
///
/// ```
/// # trait Foo {
/// # fn foo(&self);
/// # fn bar(&self);
/// # }
/// struct MyStruct;
///
/// impl Foo for MyStruct {
/// fn foo(&self) {
/// // implementation goes here
/// }
///
/// fn bar(&self) {
/// // let's not worry about implementing bar() for now
/// unimplemented!();
/// }
/// }
///
/// fn main() {
/// let s = MyStruct;
/// s.foo();
///
/// // we aren't even using bar() yet, so this is fine.
/// }
/// ```
#[macro_export] #[macro_export]
#[unstable(feature = "core", #[unstable(feature = "core",
reason = "relationship with panic is unclear")] reason = "relationship with panic is unclear")]

View file

@ -779,6 +779,26 @@ impl<T> IntoIterator for Option<T> {
} }
} }
#[stable(since = "1.4.0", feature = "option_iter")]
impl<'a, T> IntoIterator for &'a Option<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[stable(since = "1.4.0", feature = "option_iter")]
impl<'a, T> IntoIterator for &'a mut Option<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// The Option Iterators // The Option Iterators
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -815,6 +815,26 @@ impl<T, E> IntoIterator for Result<T, E> {
} }
} }
#[stable(since = "1.4.0", feature = "result_iter")]
impl<'a, T, E> IntoIterator for &'a Result<T, E> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[stable(since = "1.4.0", feature = "result_iter")]
impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// The Result Iterators // The Result Iterators
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use core::iter::*; use core::iter::*;
use core::iter::order::*;
use core::{i8, i16, isize}; use core::{i8, i16, isize};
use core::usize; use core::usize;
@ -21,51 +20,51 @@ fn test_lt() {
let xs = [1,2,3]; let xs = [1,2,3];
let ys = [1,2,0]; let ys = [1,2,0];
assert!(!lt(xs.iter(), ys.iter())); assert!(!xs.iter().lt(ys.iter()));
assert!(!le(xs.iter(), ys.iter())); assert!(!xs.iter().le(ys.iter()));
assert!( gt(xs.iter(), ys.iter())); assert!( xs.iter().gt(ys.iter()));
assert!( ge(xs.iter(), ys.iter())); assert!( xs.iter().ge(ys.iter()));
assert!( lt(ys.iter(), xs.iter())); assert!( ys.iter().lt(xs.iter()));
assert!( le(ys.iter(), xs.iter())); assert!( ys.iter().le(xs.iter()));
assert!(!gt(ys.iter(), xs.iter())); assert!(!ys.iter().gt(xs.iter()));
assert!(!ge(ys.iter(), xs.iter())); assert!(!ys.iter().ge(xs.iter()));
assert!( lt(empty.iter(), xs.iter())); assert!( empty.iter().lt(xs.iter()));
assert!( le(empty.iter(), xs.iter())); assert!( empty.iter().le(xs.iter()));
assert!(!gt(empty.iter(), xs.iter())); assert!(!empty.iter().gt(xs.iter()));
assert!(!ge(empty.iter(), xs.iter())); assert!(!empty.iter().ge(xs.iter()));
// Sequence with NaN // Sequence with NaN
let u = [1.0f64, 2.0]; let u = [1.0f64, 2.0];
let v = [0.0f64/0.0, 3.0]; let v = [0.0f64/0.0, 3.0];
assert!(!lt(u.iter(), v.iter())); assert!(!u.iter().lt(v.iter()));
assert!(!le(u.iter(), v.iter())); assert!(!u.iter().le(v.iter()));
assert!(!gt(u.iter(), v.iter())); assert!(!u.iter().gt(v.iter()));
assert!(!ge(u.iter(), v.iter())); assert!(!u.iter().ge(v.iter()));
let a = [0.0f64/0.0]; let a = [0.0f64/0.0];
let b = [1.0f64]; let b = [1.0f64];
let c = [2.0f64]; let c = [2.0f64];
assert!(lt(a.iter(), b.iter()) == (a[0] < b[0])); assert!(a.iter().lt(b.iter()) == (a[0] < b[0]));
assert!(le(a.iter(), b.iter()) == (a[0] <= b[0])); assert!(a.iter().le(b.iter()) == (a[0] <= b[0]));
assert!(gt(a.iter(), b.iter()) == (a[0] > b[0])); assert!(a.iter().gt(b.iter()) == (a[0] > b[0]));
assert!(ge(a.iter(), b.iter()) == (a[0] >= b[0])); assert!(a.iter().ge(b.iter()) == (a[0] >= b[0]));
assert!(lt(c.iter(), b.iter()) == (c[0] < b[0])); assert!(c.iter().lt(b.iter()) == (c[0] < b[0]));
assert!(le(c.iter(), b.iter()) == (c[0] <= b[0])); assert!(c.iter().le(b.iter()) == (c[0] <= b[0]));
assert!(gt(c.iter(), b.iter()) == (c[0] > b[0])); assert!(c.iter().gt(b.iter()) == (c[0] > b[0]));
assert!(ge(c.iter(), b.iter()) == (c[0] >= b[0])); assert!(c.iter().ge(b.iter()) == (c[0] >= b[0]));
} }
#[test] #[test]
fn test_multi_iter() { fn test_multi_iter() {
let xs = [1,2,3,4]; let xs = [1,2,3,4];
let ys = [4,3,2,1]; let ys = [4,3,2,1];
assert!(eq(xs.iter(), ys.iter().rev())); assert!(xs.iter().eq(ys.iter().rev()));
assert!(lt(xs.iter(), xs.iter().skip(2))); assert!(xs.iter().lt(xs.iter().skip(2)));
} }
#[test] #[test]

View file

@ -180,11 +180,14 @@ fn test_iter() {
assert_eq!(it.next(), Some(&val)); assert_eq!(it.next(), Some(&val));
assert_eq!(it.size_hint(), (0, Some(0))); assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none()); assert!(it.next().is_none());
let mut it = (&x).into_iter();
assert_eq!(it.next(), Some(&val));
} }
#[test] #[test]
fn test_mut_iter() { fn test_mut_iter() {
let val = 5; let mut val = 5;
let new_val = 11; let new_val = 11;
let mut x = Some(val); let mut x = Some(val);
@ -205,6 +208,10 @@ fn test_mut_iter() {
assert!(it.next().is_none()); assert!(it.next().is_none());
} }
assert_eq!(x, Some(new_val)); assert_eq!(x, Some(new_val));
let mut y = Some(val);
let mut it = (&mut y).into_iter();
assert_eq!(it.next(), Some(&mut val));
} }
#[test] #[test]

View file

@ -150,3 +150,36 @@ pub fn test_expect_err() {
let err: Result<isize, &'static str> = Err("All good"); let err: Result<isize, &'static str> = Err("All good");
err.expect("Got expected error"); err.expect("Got expected error");
} }
#[test]
pub fn test_iter() {
let ok: Result<isize, &'static str> = Ok(100);
let mut it = ok.iter();
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next(), Some(&100));
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
assert_eq!((&ok).into_iter().next(), Some(&100));
let err: Result<isize, &'static str> = Err("error");
assert_eq!(err.iter().next(), None);
}
#[test]
pub fn test_iter_mut() {
let mut ok: Result<isize, &'static str> = Ok(100);
for loc in ok.iter_mut() {
*loc = 200;
}
assert_eq!(ok, Ok(200));
for loc in &mut ok {
*loc = 300;
}
assert_eq!(ok, Ok(300));
let mut err: Result<isize, &'static str> = Err("error");
for loc in err.iter_mut() {
*loc = 200;
}
assert_eq!(err, Err("error"));
}

View file

@ -73,10 +73,39 @@ the enum.
"##, "##,
E0025: r##" E0025: r##"
Each field of a struct can only be bound once in a pattern. Each occurrence of a Each field of a struct can only be bound once in a pattern. Erroneous code
field name binds the value of that field, so to fix this error you will have to example:
remove or alter the duplicate uses of the field name. Perhaps you misspelt
another field name? ```
struct Foo {
a: u8,
b: u8,
}
fn main(){
let x = Foo { a:1, b:2 };
let Foo { a: x, a: y } = x;
// error: field `a` bound multiple times in the pattern
}
```
Each occurrence of a field name binds the value of that field, so to fix this
error you will have to remove or alter the duplicate uses of the field name.
Perhaps you misspelled another field name? Example:
```
struct Foo {
a: u8,
b: u8,
}
fn main(){
let x = Foo { a:1, b:2 };
let Foo { a: x, b: y } = x; // ok!
}
```
"##, "##,
E0026: r##" E0026: r##"
@ -401,10 +430,35 @@ extern "C" {
"##, "##,
E0046: r##" E0046: r##"
Items are missing in a trait implementation. Erroneous code example:
```
trait Foo {
fn foo();
}
struct Bar;
impl Foo for Bar {}
// error: not all trait items implemented, missing: `foo`
```
When trying to make some type implement a trait `Foo`, you must, at minimum, When trying to make some type implement a trait `Foo`, you must, at minimum,
provide implementations for all of `Foo`'s required methods (meaning the provide implementations for all of `Foo`'s required methods (meaning the
methods that do not have default implementations), as well as any required methods that do not have default implementations), as well as any required
trait items like associated types or constants. trait items like associated types or constants. Example:
```
trait Foo {
fn foo();
}
struct Bar;
impl Foo for Bar {
fn foo() {} // ok!
}
```
"##, "##,
E0049: r##" E0049: r##"
@ -615,14 +669,62 @@ variadic functions (except for its C-FFI).
E0062: r##" E0062: r##"
This error indicates that during an attempt to build a struct or struct-like This error indicates that during an attempt to build a struct or struct-like
enum variant, one of the fields was specified more than once. Each field should enum variant, one of the fields was specified more than once. Erroneous code
be specified exactly one time. example:
```
struct Foo {
x: i32
}
fn main() {
let x = Foo {
x: 0,
x: 0, // error: field `x` specified more than once
};
}
```
Each field should be specified exactly one time. Example:
```
struct Foo {
x: i32
}
fn main() {
let x = Foo { x: 0 }; // ok!
}
```
"##, "##,
E0063: r##" E0063: r##"
This error indicates that during an attempt to build a struct or struct-like This error indicates that during an attempt to build a struct or struct-like
enum variant, one of the fields was not provided. Each field should be enum variant, one of the fields was not provided. Erroneous code example:
specified exactly once.
```
struct Foo {
x: i32,
y: i32
}
fn main() {
let x = Foo { x: 0 }; // error: missing field: `y`
}
```
Each field should be specified exactly once. Example:
```
struct Foo {
x: i32,
y: i32
}
fn main() {
let x = Foo { x: 0, y: 0 }; // ok!
}
```
"##, "##,
E0066: r##" E0066: r##"
@ -1025,7 +1127,7 @@ fn main() {
} }
``` ```
The number of supplied parameters much exactly match the number of defined type The number of supplied parameters must exactly match the number of defined type
parameters. parameters.
"##, "##,
@ -1620,6 +1722,12 @@ extern {
E0131: r##" E0131: r##"
It is not possible to define `main` with type parameters, or even with function It is not possible to define `main` with type parameters, or even with function
parameters. When `main` is present, it must take no arguments and return `()`. parameters. When `main` is present, it must take no arguments and return `()`.
Erroneous code example:
```
fn main<T>() { // error: main function is not allowed to have type parameters
}
```
"##, "##,
E0132: r##" E0132: r##"
@ -1627,7 +1735,7 @@ 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:
``` ```
fn(isize, *const *const u8) -> isize fn(isize, *const *const u8) -> isize;
``` ```
"##, "##,
@ -1881,7 +1989,6 @@ unsafe impl Foo { }
// converting it to this will fix it // converting it to this will fix it
impl Foo { } impl Foo { }
``` ```
"##, "##,
E0198: r##" E0198: r##"
@ -1898,7 +2005,6 @@ unsafe impl !Clone for Foo { }
// this will compile // this will compile
impl !Clone for Foo { } impl !Clone for Foo { }
``` ```
"##, "##,
E0199: r##" E0199: r##"
@ -1916,7 +2022,6 @@ unsafe impl Bar for Foo { }
// this will compile // this will compile
impl Bar for Foo { } impl Bar for Foo { }
``` ```
"##, "##,
E0200: r##" E0200: r##"
@ -1934,7 +2039,6 @@ impl Bar for Foo { }
// this will compile // this will compile
unsafe impl Bar for Foo { } unsafe impl Bar for Foo { }
``` ```
"##, "##,
E0201: r##" E0201: r##"
@ -2717,6 +2821,36 @@ It is also possible to overload most operators for your own type by
implementing traits from `std::ops`. implementing traits from `std::ops`.
"##, "##,
E0370: r##"
The maximum value of an enum was reached, so it cannot be automatically
set in the next enum value. Erroneous code example:
```
enum Foo {
X = 0x7fffffffffffffff,
Y // error: enum discriminant overflowed on value after
// 9223372036854775807: i64; set explicitly via
// Y = -9223372036854775808 if that is desired outcome
}
```
To fix this, please set manually the next enum value or put the enum variant
with the maximum value at the end of the enum. Examples:
```
enum Foo {
X = 0x7fffffffffffffff,
Y = 0, // ok!
}
// or:
enum Foo {
Y = 0, // ok!
X = 0x7fffffffffffffff,
}
```
"##,
E0371: r##" E0371: r##"
When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a
definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement
@ -2869,44 +3003,44 @@ https://doc.rust-lang.org/std/marker/struct.PhantomData.html
} }
register_diagnostics! { register_diagnostics! {
E0068, // E0068,
E0085, // E0085,
E0086, // E0086,
E0090, E0090,
E0103, // @GuillaumeGomez: I was unable to get this error, try your best! E0103, // @GuillaumeGomez: I was unable to get this error, try your best!
E0104, E0104,
E0118, E0118,
E0122, E0122,
E0123, // E0123,
E0127, // E0127,
E0129, // E0129,
E0141, // E0141,
// E0159, // use of trait `{}` as struct constructor // E0159, // use of trait `{}` as struct constructor
E0163, E0163,
E0164, E0164,
E0167, E0167,
// E0168, // E0168,
E0173, // manual implementations of unboxed closure traits are experimental // E0173, // manual implementations of unboxed closure traits are experimental
E0174, // explicit use of unboxed closure methods are experimental E0174, // explicit use of unboxed closure methods are experimental
E0182, E0182,
E0183, E0183,
E0187, // can't infer the kind of the closure // E0187, // can't infer the kind of the closure
E0188, // can not cast a immutable reference to a mutable pointer // E0188, // can not cast a immutable reference to a mutable pointer
E0189, // deprecated: can only cast a boxed pointer to a boxed object // E0189, // deprecated: can only cast a boxed pointer to a boxed object
E0190, // deprecated: can only cast a &-pointer to an &-object // E0190, // deprecated: can only cast a &-pointer to an &-object
E0196, // cannot determine a type for this closure E0196, // cannot determine a type for this closure
E0203, // type parameter has more than one relaxed default bound, E0203, // type parameter has more than one relaxed default bound,
// and only one is supported // and only one is supported
E0208, E0208,
E0209, // builtin traits can only be implemented on structs or enums // E0209, // builtin traits can only be implemented on structs or enums
E0212, // cannot extract an associated type from a higher-ranked trait bound E0212, // cannot extract an associated type from a higher-ranked trait bound
E0213, // associated types are not accepted in this context // E0213, // associated types are not accepted in this context
E0214, // parenthesized parameters may only be used with a trait E0214, // parenthesized parameters may only be used with a trait
// E0215, // angle-bracket notation is not stable with `Fn` // E0215, // angle-bracket notation is not stable with `Fn`
// E0216, // parenthetical notation is only stable with `Fn` // E0216, // parenthetical notation is only stable with `Fn`
E0217, // ambiguous associated type, defined in multiple supertraits // E0217, // ambiguous associated type, defined in multiple supertraits
E0218, // no associated type defined // E0218, // no associated type defined
E0219, // associated type defined in higher-ranked supertrait // E0219, // associated type defined in higher-ranked supertrait
// E0222, // Error code E0045 (variadic function must have C calling // E0222, // Error code E0045 (variadic function must have C calling
// convention) duplicate // convention) duplicate
E0224, // at least one non-builtin train is required for an object type E0224, // at least one non-builtin train is required for an object type
@ -2916,25 +3050,24 @@ register_diagnostics! {
E0229, // associated type bindings are not allowed here E0229, // associated type bindings are not allowed here
E0230, // there is no type parameter on trait E0230, // there is no type parameter on trait
E0231, // only named substitution parameters are allowed E0231, // only named substitution parameters are allowed
E0233, // E0233,
E0234, // E0234,
// E0235, // structure constructor specifies a structure of type but // E0235, // structure constructor specifies a structure of type but
E0236, // no lang item for range syntax E0236, // no lang item for range syntax
E0237, // no lang item for range syntax E0237, // no lang item for range syntax
E0238, // parenthesized parameters may only be used with a trait E0238, // parenthesized parameters may only be used with a trait
E0239, // `next` method of `Iterator` trait has unexpected type // E0239, // `next` method of `Iterator` trait has unexpected type
E0240, // E0240,
E0241, // E0241,
E0242, // internal error looking up a definition E0242, // internal error looking up a definition
E0245, // not a trait E0245, // not a trait
E0246, // invalid recursive type // E0246, // invalid recursive type
E0247, // found module name used as a type E0247, // found module name used as a type
E0319, // trait impls for defaulted traits allowed just for structs/enums // E0319, // trait impls for defaulted traits allowed just for structs/enums
E0320, // recursive overflow during dropck E0320, // recursive overflow during dropck
E0321, // extended coherence rules for defaulted traits violated E0321, // extended coherence rules for defaulted traits violated
E0328, // cannot implement Unsize explicitly E0328, // cannot implement Unsize explicitly
E0329, // associated const depends on type parameter or Self. E0329, // associated const depends on type parameter or Self.
E0370, // discriminant overflow
E0374, // the trait `CoerceUnsized` may only be implemented for a coercion E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, none found // between structures with one field being coerced, none found
E0375, // the trait `CoerceUnsized` may only be implemented for a coercion E0375, // the trait `CoerceUnsized` may only be implemented for a coercion

View file

@ -598,8 +598,11 @@ impl<'a> Components<'a> {
/// how much of the prefix is left from the point of view of iteration? /// how much of the prefix is left from the point of view of iteration?
#[inline] #[inline]
fn prefix_remaining(&self) -> usize { fn prefix_remaining(&self) -> usize {
if self.front == State::Prefix { self.prefix_len() } if self.front == State::Prefix {
else { 0 } self.prefix_len()
} else {
0
}
} }
// Given the iteration so far, how much of the pre-State::Body path is left? // Given the iteration so far, how much of the pre-State::Body path is left?

View file

@ -29,6 +29,8 @@ use std::io::{self, Read};
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
use parse::token::intern;
use ast::Name;
// _____________________________________________________________________________ // _____________________________________________________________________________
// Pos, BytePos, CharPos // Pos, BytePos, CharPos
@ -257,21 +259,38 @@ pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos }
// //
/// The source of expansion. /// The source of expansion.
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] #[derive(Clone, Hash, Debug, PartialEq, Eq)]
pub enum ExpnFormat { pub enum ExpnFormat {
/// e.g. #[derive(...)] <item> /// e.g. #[derive(...)] <item>
MacroAttribute, MacroAttribute(Name),
/// e.g. `format!()` /// e.g. `format!()`
MacroBang, MacroBang(Name),
/// Syntax sugar expansion performed by the compiler (libsyntax::expand). /// Syntax sugar expansion performed by the compiler (libsyntax::expand).
CompilerExpansion, CompilerExpansion(CompilerExpansionFormat),
} }
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
pub enum CompilerExpansionFormat {
IfLet,
PlacementIn,
WhileLet,
ForLoop,
Closure,
}
impl CompilerExpansionFormat {
pub fn name(self) -> &'static str {
match self {
CompilerExpansionFormat::IfLet => "if let expansion",
CompilerExpansionFormat::PlacementIn => "placement-in expansion",
CompilerExpansionFormat::WhileLet => "while let expansion",
CompilerExpansionFormat::ForLoop => "for loop expansion",
CompilerExpansionFormat::Closure => "closure expansion",
}
}
}
#[derive(Clone, Hash, Debug)] #[derive(Clone, Hash, Debug)]
pub struct NameAndSpan { pub struct NameAndSpan {
/// The name of the macro that was invoked to create the thing
/// with this Span.
pub name: String,
/// The format with which the macro was invoked. /// The format with which the macro was invoked.
pub format: ExpnFormat, pub format: ExpnFormat,
/// Whether the macro is allowed to use #[unstable]/feature-gated /// Whether the macro is allowed to use #[unstable]/feature-gated
@ -284,6 +303,16 @@ pub struct NameAndSpan {
pub span: Option<Span> pub span: Option<Span>
} }
impl NameAndSpan {
pub fn name(&self) -> Name {
match self.format {
ExpnFormat::MacroAttribute(s) => s,
ExpnFormat::MacroBang(s) => s,
ExpnFormat::CompilerExpansion(ce) => intern(ce.name()),
}
}
}
/// Extra information for tracking spans of macro and syntax sugar expansion /// Extra information for tracking spans of macro and syntax sugar expansion
#[derive(Hash, Debug)] #[derive(Hash, Debug)]
pub struct ExpnInfo { pub struct ExpnInfo {

View file

@ -733,14 +733,14 @@ impl EmitterWriter {
let ss = ei.callee.span.map_or(String::new(), let ss = ei.callee.span.map_or(String::new(),
|span| cm.span_to_string(span)); |span| cm.span_to_string(span));
let (pre, post) = match ei.callee.format { let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"), codemap::MacroAttribute(..) => ("#[", "]"),
codemap::MacroBang => ("", "!"), codemap::MacroBang(..) => ("", "!"),
codemap::CompilerExpansion => ("", ""), codemap::CompilerExpansion(..) => ("", ""),
}; };
try!(self.print_diagnostic(&ss, Note, try!(self.print_diagnostic(&ss, Note,
&format!("in expansion of {}{}{}", &format!("in expansion of {}{}{}",
pre, pre,
ei.callee.name, ei.callee.name(),
post), post),
None)); None));
let ss = cm.span_to_string(ei.call_site); let ss = cm.span_to_string(ei.call_site);

View file

@ -19,7 +19,7 @@ use codemap::Span;
use ext::base; use ext::base;
use ext::base::*; use ext::base::*;
use feature_gate; use feature_gate;
use parse::token::InternedString; use parse::token::{intern, InternedString};
use parse::token; use parse::token;
use ptr::P; use ptr::P;
@ -211,8 +211,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: sp, call_site: sp,
callee: codemap::NameAndSpan { callee: codemap::NameAndSpan {
name: "asm".to_string(), format: codemap::MacroBang(intern("asm")),
format: codemap::MacroBang,
span: None, span: None,
allow_internal_unstable: false, allow_internal_unstable: false,
}, },

View file

@ -714,13 +714,14 @@ impl<'a> ExtCtxt<'a> {
loop { loop {
if self.codemap().with_expn_info(expn_id, |info| { if self.codemap().with_expn_info(expn_id, |info| {
info.map_or(None, |i| { info.map_or(None, |i| {
if i.callee.name == "include" { if i.callee.name() == "include" {
// Stop going up the backtrace once include! is encountered // Stop going up the backtrace once include! is encountered
return None; return None;
} }
expn_id = i.call_site.expn_id; expn_id = i.call_site.expn_id;
if i.callee.format != CompilerExpansion { match i.callee.format {
last_macro = Some(i.call_site) CompilerExpansion(..) => (),
_ => last_macro = Some(i.call_site),
} }
return Some(()); return Some(());
}) })
@ -744,7 +745,7 @@ impl<'a> ExtCtxt<'a> {
if self.recursion_count > self.ecfg.recursion_limit { if self.recursion_count > self.ecfg.recursion_limit {
panic!(self.span_fatal(ei.call_site, panic!(self.span_fatal(ei.call_site,
&format!("recursion limit reached while expanding the macro `{}`", &format!("recursion limit reached while expanding the macro `{}`",
ei.callee.name))); ei.callee.name())));
} }
let mut call_site = ei.call_site; let mut call_site = ei.call_site;

View file

@ -205,7 +205,7 @@ use codemap::Span;
use diagnostic::SpanHandler; use diagnostic::SpanHandler;
use fold::MoveMap; use fold::MoveMap;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token::InternedString; use parse::token::{intern, InternedString};
use parse::token::special_idents; use parse::token::special_idents;
use ptr::P; use ptr::P;
@ -1436,8 +1436,7 @@ impl<'a> TraitDef<'a> {
to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: to_set, call_site: to_set,
callee: codemap::NameAndSpan { callee: codemap::NameAndSpan {
name: format!("derive({})", trait_name), format: codemap::MacroAttribute(intern(&format!("derive({})", trait_name))),
format: codemap::MacroAttribute,
span: Some(self.span), span: Some(self.span),
allow_internal_unstable: false, allow_internal_unstable: false,
} }

View file

@ -19,7 +19,8 @@ use ext::build::AstBuilder;
use attr; use attr;
use attr::AttrMetaMethods; use attr::AttrMetaMethods;
use codemap; use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, CompilerExpansion}; use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
use codemap::{CompilerExpansion, CompilerExpansionFormat};
use ext::base::*; use ext::base::*;
use feature_gate::{self, Features, GatedCfg}; use feature_gate::{self, Features, GatedCfg};
use fold; use fold;
@ -43,12 +44,12 @@ fn mk_core_path(fld: &mut MacroExpander,
} }
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> { pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc: &str) { fn push_compiler_expansion(fld: &mut MacroExpander, span: Span,
expansion_type: CompilerExpansionFormat) {
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: span, call_site: span,
callee: NameAndSpan { callee: NameAndSpan {
name: expansion_desc.to_string(), format: CompilerExpansion(expansion_type),
format: CompilerExpansion,
// This does *not* mean code generated after // This does *not* mean code generated after
// `push_compiler_expansion` is automatically exempt // `push_compiler_expansion` is automatically exempt
@ -111,7 +112,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
&fld.cx.parse_sess.span_diagnostic, &fld.cx.parse_sess.span_diagnostic,
expr_span); expr_span);
push_compiler_expansion(fld, expr_span, "placement-in expansion"); push_compiler_expansion(fld, expr_span, CompilerExpansionFormat::PlacementIn);
let value_span = value_expr.span; let value_span = value_expr.span;
let placer_span = placer.span; let placer_span = placer.span;
@ -223,7 +224,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
// } // }
// } // }
push_compiler_expansion(fld, span, "while let expansion"); push_compiler_expansion(fld, span, CompilerExpansionFormat::WhileLet);
// `<pat> => <body>` // `<pat> => <body>`
let pat_arm = { let pat_arm = {
@ -262,7 +263,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
// _ => [<elseopt> | ()] // _ => [<elseopt> | ()]
// } // }
push_compiler_expansion(fld, span, "if let expansion"); push_compiler_expansion(fld, span, CompilerExpansionFormat::IfLet);
// `<pat> => <body>` // `<pat> => <body>`
let pat_arm = { let pat_arm = {
@ -334,7 +335,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
ast::ExprIf(cond, blk, elseopt) => { ast::ExprIf(cond, blk, elseopt) => {
let elseopt = elseopt.map(|els| els.and_then(|els| match els.node { let elseopt = elseopt.map(|els| els.and_then(|els| match els.node {
ast::ExprIfLet(..) => { ast::ExprIfLet(..) => {
push_compiler_expansion(fld, span, "if let expansion"); push_compiler_expansion(fld, span, CompilerExpansionFormat::IfLet);
// wrap the if-let expr in a block // wrap the if-let expr in a block
let span = els.span; let span = els.span;
let blk = P(ast::Block { let blk = P(ast::Block {
@ -378,7 +379,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
// result // result
// } // }
push_compiler_expansion(fld, span, "for loop expansion"); push_compiler_expansion(fld, span, CompilerExpansionFormat::ForLoop);
let span = fld.new_span(span); let span = fld.new_span(span);
@ -458,7 +459,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
} }
ast::ExprClosure(capture_clause, fn_decl, block) => { ast::ExprClosure(capture_clause, fn_decl, block) => {
push_compiler_expansion(fld, span, "closure expansion"); push_compiler_expansion(fld, span, CompilerExpansionFormat::Closure);
let (rewritten_fn_decl, rewritten_block) let (rewritten_fn_decl, rewritten_block)
= expand_and_rename_fn_decl_and_block(fn_decl, block, fld); = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
let new_node = ast::ExprClosure(capture_clause, let new_node = ast::ExprClosure(capture_clause,
@ -542,8 +543,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: span, call_site: span,
callee: NameAndSpan { callee: NameAndSpan {
name: extname.to_string(), format: MacroBang(extname),
format: MacroBang,
span: exp_span, span: exp_span,
allow_internal_unstable: allow_internal_unstable, allow_internal_unstable: allow_internal_unstable,
}, },
@ -721,8 +721,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: it.span, call_site: it.span,
callee: NameAndSpan { callee: NameAndSpan {
name: extname.to_string(), format: MacroBang(extname),
format: MacroBang,
span: span, span: span,
allow_internal_unstable: allow_internal_unstable, allow_internal_unstable: allow_internal_unstable,
} }
@ -741,8 +740,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: it.span, call_site: it.span,
callee: NameAndSpan { callee: NameAndSpan {
name: extname.to_string(), format: MacroBang(extname),
format: MacroBang,
span: span, span: span,
allow_internal_unstable: allow_internal_unstable, allow_internal_unstable: allow_internal_unstable,
} }
@ -762,8 +760,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: it.span, call_site: it.span,
callee: NameAndSpan { callee: NameAndSpan {
name: extname.to_string(), format: MacroBang(extname),
format: MacroBang,
span: None, span: None,
// `macro_rules!` doesn't directly allow // `macro_rules!` doesn't directly allow
// unstable (this is orthogonal to whether // unstable (this is orthogonal to whether
@ -1090,8 +1087,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: span, call_site: span,
callee: NameAndSpan { callee: NameAndSpan {
name: extname.to_string(), format: MacroBang(extname),
format: MacroBang,
span: tt_span, span: tt_span,
allow_internal_unstable: allow_internal_unstable, allow_internal_unstable: allow_internal_unstable,
} }
@ -1293,8 +1289,8 @@ fn expand_decorators(a: Annotatable,
new_attrs: &mut Vec<ast::Attribute>) new_attrs: &mut Vec<ast::Attribute>)
{ {
for attr in a.attrs() { for attr in a.attrs() {
let mname = attr.name(); let mname = intern(&attr.name());
match fld.cx.syntax_env.find(&intern(&mname)) { match fld.cx.syntax_env.find(&mname) {
Some(rc) => match *rc { Some(rc) => match *rc {
Decorator(ref dec) => { Decorator(ref dec) => {
attr::mark_used(&attr); attr::mark_used(&attr);
@ -1302,8 +1298,7 @@ fn expand_decorators(a: Annotatable,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
callee: NameAndSpan { callee: NameAndSpan {
name: mname.to_string(), format: MacroAttribute(mname),
format: MacroAttribute,
span: Some(attr.span), span: Some(attr.span),
// attributes can do whatever they like, // attributes can do whatever they like,
// for now. // for now.
@ -1330,8 +1325,7 @@ fn expand_decorators(a: Annotatable,
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
callee: NameAndSpan { callee: NameAndSpan {
name: mname.to_string(), format: MacroAttribute(mname),
format: MacroAttribute,
span: Some(attr.span), span: Some(attr.span),
// attributes can do whatever they like, // attributes can do whatever they like,
// for now. // for now.
@ -1372,17 +1366,16 @@ fn expand_item_multi_modifier(mut it: Annotatable,
} }
for attr in &modifiers { for attr in &modifiers {
let mname = attr.name(); let mname = intern(&attr.name());
match fld.cx.syntax_env.find(&intern(&mname)) { match fld.cx.syntax_env.find(&mname) {
Some(rc) => match *rc { Some(rc) => match *rc {
MultiModifier(ref mac) => { MultiModifier(ref mac) => {
attr::mark_used(attr); attr::mark_used(attr);
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
callee: NameAndSpan { callee: NameAndSpan {
name: mname.to_string(), format: MacroAttribute(mname),
format: MacroAttribute,
span: Some(attr.span), span: Some(attr.span),
// attributes can do whatever they like, // attributes can do whatever they like,
// for now // for now
@ -1421,17 +1414,16 @@ fn expand_item_modifiers(mut it: P<ast::Item>,
} }
for attr in &modifiers { for attr in &modifiers {
let mname = attr.name(); let mname = intern(&attr.name());
match fld.cx.syntax_env.find(&intern(&mname)) { match fld.cx.syntax_env.find(&mname) {
Some(rc) => match *rc { Some(rc) => match *rc {
Modifier(ref mac) => { Modifier(ref mac) => {
attr::mark_used(attr); attr::mark_used(attr);
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: attr.span, call_site: attr.span,
callee: NameAndSpan { callee: NameAndSpan {
name: mname.to_string(), format: MacroAttribute(mname),
format: MacroAttribute,
span: Some(attr.span), span: Some(attr.span),
// attributes can do whatever they like, // attributes can do whatever they like,
// for now // for now

View file

@ -14,8 +14,7 @@ use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
use codemap; use codemap;
use fold::Folder; use fold::Folder;
use fold; use fold;
use parse::token::InternedString; use parse::token::{intern, InternedString, special_idents};
use parse::token::special_idents;
use parse::{token, ParseSess}; use parse::{token, ParseSess};
use ptr::P; use ptr::P;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
@ -27,8 +26,7 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
let info = ExpnInfo { let info = ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: NameAndSpan { callee: NameAndSpan {
name: "std_inject".to_string(), format: MacroAttribute(intern("std_inject")),
format: MacroAttribute,
span: None, span: None,
allow_internal_unstable: true, allow_internal_unstable: true,
} }

View file

@ -32,7 +32,7 @@ use ext::expand::ExpansionConfig;
use fold::{Folder, MoveMap}; use fold::{Folder, MoveMap};
use fold; use fold;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token::InternedString; use parse::token::{intern, InternedString};
use parse::{token, ParseSess}; use parse::{token, ParseSess};
use print::pprust; use print::pprust;
use {ast, ast_util}; use {ast, ast_util};
@ -298,8 +298,7 @@ fn generate_test_harness(sess: &ParseSess,
cx.ext_cx.bt_push(ExpnInfo { cx.ext_cx.bt_push(ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: NameAndSpan { callee: NameAndSpan {
name: "test".to_string(), format: MacroAttribute(intern("test")),
format: MacroAttribute,
span: None, span: None,
allow_internal_unstable: false, allow_internal_unstable: false,
} }
@ -331,8 +330,7 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span {
let info = ExpnInfo { let info = ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: NameAndSpan { callee: NameAndSpan {
name: "test".to_string(), format: MacroAttribute(intern("test")),
format: MacroAttribute,
span: None, span: None,
allow_internal_unstable: true, allow_internal_unstable: true,
} }

View file

@ -27,7 +27,7 @@ h1, h2, h3, h4, h5, h6 {
@media only screen { @media only screen {
#toc { #toc {
position: absolute; position: fixed;
left: 0px; left: 0px;
top: 0px; top: 0px;
bottom: 0px; bottom: 0px;
@ -44,11 +44,9 @@ h1, h2, h3, h4, h5, h6 {
#page-wrapper { #page-wrapper {
position: absolute; position: absolute;
overflow-y: auto;
left: 310px; left: 310px;
right: 0px; right: 0px;
top: 0px; top: 0px;
bottom: 0px;
box-sizing: border-box; box-sizing: border-box;
background: none repeat scroll 0% 0% #FFF; background: none repeat scroll 0% 0% #FFF;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;

View file

@ -27,8 +27,7 @@ fn main() {
cx.bt_push(syntax::codemap::ExpnInfo { cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan { callee: syntax::codemap::NameAndSpan {
name: "".to_string(), format: syntax::codemap::MacroBang(parse::token::intern("")),
format: syntax::codemap::MacroBang,
allow_internal_unstable: false, allow_internal_unstable: false,
span: None, span: None,
} }

View file

@ -31,8 +31,7 @@ fn main() {
cx.bt_push(syntax::codemap::ExpnInfo { cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan { callee: syntax::codemap::NameAndSpan {
name: "".to_string(), format: syntax::codemap::MacroBang(parse::token::intern("")),
format: syntax::codemap::MacroBang,
allow_internal_unstable: false, allow_internal_unstable: false,
span: None, span: None,
} }

View file

@ -16,6 +16,7 @@ extern crate syntax;
use syntax::codemap::DUMMY_SP; use syntax::codemap::DUMMY_SP;
use syntax::print::pprust::*; use syntax::print::pprust::*;
use syntax::parse::token::intern;
fn main() { fn main() {
let ps = syntax::parse::ParseSess::new(); let ps = syntax::parse::ParseSess::new();
@ -27,8 +28,7 @@ fn main() {
cx.bt_push(syntax::codemap::ExpnInfo { cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan { callee: syntax::codemap::NameAndSpan {
name: "".to_string(), format: syntax::codemap::MacroBang(intern("")),
format: syntax::codemap::MacroBang,
allow_internal_unstable: false, allow_internal_unstable: false,
span: None, span: None,
} }