diff --git a/src/doc/book/advanced-linking.md b/src/doc/book/advanced-linking.md index 9ef6d5c2bff..c8a9082947e 100644 --- a/src/doc/book/advanced-linking.md +++ b/src/doc/book/advanced-linking.md @@ -12,7 +12,7 @@ the `link_args` attribute. This attribute is applied to `extern` blocks and specifies raw flags which need to get passed to the linker when producing an artifact. An example usage would be: -``` no_run +```rust,no_run #![feature(link_args)] #[link_args = "-foo -bar -baz"] @@ -52,7 +52,7 @@ By default, all Rust programs on Linux will link to the system `libc` along with a number of other libraries. Let's look at an example on a 64-bit Linux machine with GCC and `glibc` (by far the most common `libc` on Linux): -``` text +```text $ cat example.rs fn main() {} $ rustc example.rs diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index d81619b647f..dedf9d5c28a 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -319,6 +319,53 @@ assert_eq!(3, answer); Now we take a trait object, a `&Fn`. And we have to make a reference to our closure when we pass it to `call_with_one`, so we use `&||`. +A quick note about closures that use explicit lifetimes. Sometimes you might have a closure +that takes a reference like so: + +``` +fn call_with_ref(some_closure:F) -> i32 + where F: Fn(&i32) -> i32 { + + let mut value = 0; + some_closure(&value) +} +``` + +Normally you can specify the lifetime of the parameter to our closure. We +could annotate it on the function declaration: + +```ignore +fn call_with_ref<'a, F>(some_closure:F) -> i32 + where F: Fn(&'a 32) -> i32 { +``` + +However this presents a problem with in our case. When you specify the explict +lifetime on a function it binds that lifetime to the *entire* scope of the function +instead of just the invocation scope of our closure. This means that the borrow checker +will see a mutable reference in the same lifetime as our immutable reference and fail +to compile. + +In order to say that we only need the lifetime to be valid for the invocation scope +of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax: + +```ignore +fn call_with_ref(some_closure:F) -> i32 + where F: for<'a> Fn(&'a 32) -> i32 { +``` + +This lets the Rust compiler find the minimum lifetime to invoke our closure and +satisfy the borrow checker's rules. Our function then compiles and excutes as we +expect. + +``` +fn call_with_ref(some_closure:F) -> i32 + where F: for<'a> Fn(&'a i32) -> i32 { + + let mut value = 0; + some_closure(&value) +} +``` + # Function pointers and closures A function pointer is kind of like a closure that has no environment. As such, @@ -344,7 +391,7 @@ assert_eq!(2, answer); In this example, we don’t strictly need the intermediate variable `f`, the name of the function works just fine too: -```ignore +```rust,ignore let answer = call_with_one(&add_one); ``` diff --git a/src/doc/book/compiler-plugins.md b/src/doc/book/compiler-plugins.md index 1af05bfea19..2d0cc61fb11 100644 --- a/src/doc/book/compiler-plugins.md +++ b/src/doc/book/compiler-plugins.md @@ -37,7 +37,7 @@ Let's write a plugin [`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs) that implements Roman numeral integer literals. -```ignore +```rust,ignore #![crate_type="dylib"] #![feature(plugin_registrar, rustc_private)] @@ -102,7 +102,7 @@ pub fn plugin_registrar(reg: &mut Registry) { Then we can use `rn!()` like any other macro: -```ignore +```rust,ignore #![feature(plugin)] #![plugin(roman_numerals)] @@ -132,7 +132,7 @@ Some of the [macro debugging tips](macros.html#debugging-macro-code) are applica You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: -```ignore +```rust,ignore fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box { @@ -169,7 +169,7 @@ infrastructure](../reference.html#lint-check-attributes) with additional checks code style, safety, etc. Now let's write a plugin [`lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs) that warns about any item named `lintme`. -```ignore +```rust,ignore #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] @@ -211,7 +211,7 @@ pub fn plugin_registrar(reg: &mut Registry) { Then code like -```ignore +```rust,ignore #![plugin(lint_plugin_test)] fn lintme() { } diff --git a/src/doc/book/concurrency.md b/src/doc/book/concurrency.md index c179629a79a..a783650f8ea 100644 --- a/src/doc/book/concurrency.md +++ b/src/doc/book/concurrency.md @@ -165,7 +165,7 @@ concurrency bugs. As an example, here is a Rust program that would have a data race in many languages. It will not compile: -```ignore +```rust,ignore use std::thread; use std::time::Duration; @@ -204,7 +204,7 @@ Calling `clone()` on an `Rc` will return a new owned reference and bump the internal reference count. We create one of these for each thread: -```ignore +```rust,ignore use std::thread; use std::time::Duration; use std::rc::Rc; @@ -250,7 +250,7 @@ In essence, `Arc` is a type that lets us share ownership of data _across threads_. -```ignore +```rust,ignore use std::thread; use std::sync::Arc; use std::time::Duration; @@ -336,7 +336,7 @@ The lock "release" here is implicit; when the result of the lock (in this case, Note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of [`Mutex`](../std/sync/struct.Mutex.html) has this signature: -```ignore +```rust,ignore fn lock(&self) -> LockResult> ``` diff --git a/src/doc/book/documentation.md b/src/doc/book/documentation.md index 8d1e58ac173..4a41bb7b7f3 100644 --- a/src/doc/book/documentation.md +++ b/src/doc/book/documentation.md @@ -362,7 +362,7 @@ Here’s an example of documenting a macro: /// # } /// ``` /// -/// ```should_panic +/// ```rust,should_panic /// # #[macro_use] extern crate foo; /// # fn main() { /// panic_unless!(true == false, “I’m broken.”); @@ -429,7 +429,7 @@ There are a few more annotations that are useful to help `rustdoc` do the right thing when testing your code: ```rust -/// ```ignore +/// ```rust,ignore /// fn foo() { /// ``` # fn foo() {} @@ -441,7 +441,7 @@ with `text` if it's not code, or using `#`s to get a working example that only shows the part you care about. ```rust -/// ```should_panic +/// ```rust,should_panic /// assert!(false); /// ``` # fn foo() {} @@ -451,7 +451,7 @@ only shows the part you care about. not actually pass as a test. ```rust -/// ```no_run +/// ```rust,no_run /// loop { /// println!("Hello, world"); /// } @@ -563,7 +563,7 @@ can be useful when changing some options, or when writing a macro. `rustdoc` will show the documentation for a public re-export in both places: -```ignore +```rust,ignore extern crate foo; pub use foo::bar; @@ -575,7 +575,7 @@ documentation in both places. This behavior can be suppressed with `no_inline`: -```ignore +```rust,ignore extern crate foo; #[doc(no_inline)] diff --git a/src/doc/book/ffi.md b/src/doc/book/ffi.md index 6aec8d2a048..f48e87c4224 100644 --- a/src/doc/book/ffi.md +++ b/src/doc/book/ffi.md @@ -28,7 +28,7 @@ and add `extern crate libc;` to your crate root. The following is a minimal example of calling a foreign function which will compile if snappy is installed: -```no_run +```rust,no_run # #![feature(libc)] extern crate libc; use libc::size_t; @@ -62,7 +62,7 @@ keeping the binding correct at runtime. The `extern` block can be extended to cover the entire snappy API: -```no_run +```rust,no_run # #![feature(libc)] extern crate libc; use libc::{c_int, size_t}; @@ -209,7 +209,7 @@ A basic example is: Rust code: -```no_run +```rust,no_run extern fn callback(a: i32) { println!("I'm called from C with value {0}", a); } @@ -262,7 +262,7 @@ referenced Rust object. Rust code: -```no_run +```rust,no_run #[repr(C)] struct RustObject { a: i32, @@ -406,7 +406,7 @@ Foreign APIs often export a global variable which could do something like track global state. In order to access these variables, you declare them in `extern` blocks with the `static` keyword: -```no_run +```rust,no_run # #![feature(libc)] extern crate libc; @@ -425,7 +425,7 @@ Alternatively, you may need to alter global state provided by a foreign interface. To do this, statics can be declared with `mut` so we can mutate them. -```no_run +```rust,no_run # #![feature(libc)] extern crate libc; diff --git a/src/doc/book/functions.md b/src/doc/book/functions.md index 8a2444323f1..3a10d2aecc2 100644 --- a/src/doc/book/functions.md +++ b/src/doc/book/functions.md @@ -134,7 +134,7 @@ x = y = 5 In Rust, however, using `let` to introduce a binding is _not_ an expression. The following will produce a compile-time error: -```ignore +```rust,ignore let x = (let y = 5); // expected identifier, found keyword `let` ``` @@ -283,7 +283,7 @@ stack backtrace: A diverging function can be used as any type: -```should_panic +```rust,should_panic # fn diverges() -> ! { # panic!("This function never returns!"); # } diff --git a/src/doc/book/inline-assembly.md b/src/doc/book/inline-assembly.md index a5a2d7ce74e..2c2d89a1fbf 100644 --- a/src/doc/book/inline-assembly.md +++ b/src/doc/book/inline-assembly.md @@ -4,7 +4,7 @@ For extremely low-level manipulations and performance reasons, one might wish to control the CPU directly. Rust supports using inline assembly to do this via the `asm!` macro. -```ignore +```rust,ignore asm!(assembly template : output operands : input operands diff --git a/src/doc/book/loops.md b/src/doc/book/loops.md index b5dde9be17f..97ca2e3e702 100644 --- a/src/doc/book/loops.md +++ b/src/doc/book/loops.md @@ -74,7 +74,7 @@ for x in 0..10 { In slightly more abstract terms, -```ignore +```rust,ignore for var in expression { code } diff --git a/src/doc/book/macros.md b/src/doc/book/macros.md index c16e2ea4535..f535fb96af8 100644 --- a/src/doc/book/macros.md +++ b/src/doc/book/macros.md @@ -78,7 +78,7 @@ macro_rules! vec { Whoa, that’s a lot of new syntax! Let’s break it down. -```ignore +```rust,ignore macro_rules! vec { ... } ``` @@ -92,7 +92,7 @@ syntax and serves to distinguish a macro from an ordinary function. The macro is defined through a series of rules, which are pattern-matching cases. Above, we had -```ignore +```rust,ignore ( $( $x:expr ),* ) => { ... }; ``` @@ -112,7 +112,7 @@ separated by commas. Aside from the special matcher syntax, any Rust tokens that appear in a matcher must match exactly. For example, -```rust +```rust,ignore macro_rules! foo { (x => $e:expr) => (println!("mode X: {}", $e)); (y => $e:expr) => (println!("mode Y: {}", $e)); @@ -147,7 +147,7 @@ The right-hand side of a macro rule is ordinary Rust syntax, for the most part. But we can splice in bits of syntax captured by the matcher. From the original example: -```ignore +```rust,ignore $( temp_vec.push($x); )* @@ -165,7 +165,7 @@ within the repeated block. Another detail: the `vec!` macro has *two* pairs of braces on the right-hand side. They are often combined like so: -```ignore +```rust,ignore macro_rules! foo { () => {{ ... diff --git a/src/doc/book/mutability.md b/src/doc/book/mutability.md index 6aad3c5f746..e4627151146 100644 --- a/src/doc/book/mutability.md +++ b/src/doc/book/mutability.md @@ -55,6 +55,8 @@ fn foo(mut x: i32) { # } ``` +Note that here, the `x` is mutable, but not the `y`. + [pattern]: patterns.html # Interior vs. Exterior Mutability diff --git a/src/doc/book/operators-and-overloading.md b/src/doc/book/operators-and-overloading.md index fcce831c2d0..424e2cda615 100644 --- a/src/doc/book/operators-and-overloading.md +++ b/src/doc/book/operators-and-overloading.md @@ -123,7 +123,7 @@ fn main() { For `HasArea` and `Square`, we declare a type parameter `T` and replace `f64` with it. The `impl` needs more involved modifications: -```ignore +```rust,ignore impl HasArea for Square where T: Mul + Copy { ... } ``` diff --git a/src/doc/book/trait-objects.md b/src/doc/book/trait-objects.md index 1d63435ed5f..b31a34a0425 100644 --- a/src/doc/book/trait-objects.md +++ b/src/doc/book/trait-objects.md @@ -306,7 +306,7 @@ let y = TraitObject { Not every trait can be used to make a trait object. For example, vectors implement `Clone`, but if we try to make a trait object: -```ignore +```rust,ignore let v = vec![1, 2, 3]; let o = &v as &Clone; ``` diff --git a/src/doc/book/traits.md b/src/doc/book/traits.md index b3b41979245..107ef2b44d5 100644 --- a/src/doc/book/traits.md +++ b/src/doc/book/traits.md @@ -195,7 +195,7 @@ fn main() { `is_square()` needs to check that the sides are equal, so the sides must be of a type that implements the [`core::cmp::PartialEq`][PartialEq] trait: -```ignore +```rust,ignore impl Rectangle { ... } ``` diff --git a/src/doc/book/vectors.md b/src/doc/book/vectors.md index 75e961e4c4a..1c44af2f21a 100644 --- a/src/doc/book/vectors.md +++ b/src/doc/book/vectors.md @@ -40,7 +40,7 @@ The indices count from `0`, so the third element is `v[2]`. It’s also important to note that you must index with the `usize` type: -```ignore +```rust,ignore let v = vec![1, 2, 3, 4, 5]; let i: usize = 0; @@ -71,7 +71,7 @@ you cannot index with an `i32`. If you try to access an index that doesn’t exist: -```ignore +```rust,ignore let v = vec![1, 2, 3]; println!("Item 7 is {}", v[7]); ``` diff --git a/src/liblibc b/src/liblibc index 6598e2cbfd7..b19b5465a12 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 6598e2cbfd7e09bfca249cc3dcbf889735f73ce1 +Subproject commit b19b5465a1235be3323363cdc11838739b593029 diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index b5d8192b4dd..116e3476897 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -502,6 +502,33 @@ fn foo(a: &mut i32) { ``` "##, +E0502: r##" +This error indicates that you are trying to borrow a variable as mutable when it +has already been borrowed as immutable. + +Example of erroneous code: + +```compile_fail +fn bar(x: &mut i32) {} +fn foo(a: &mut i32) { + let ref y = a; // a is borrowed as immutable. + bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed + // as immutable +} +``` +To fix this error, ensure that you don't have any other references to the +variable before trying to access it mutably: +``` +fn bar(x: &mut i32) {} +fn foo(a: &mut i32) { + bar(a); + let ref y = a; // ok! +} +``` +For more information on the rust ownership system, take a look at +https://doc.rust-lang.org/stable/book/references-and-borrowing.html. +"##, + E0504: r##" This error occurs when an attempt is made to move a borrowed variable into a closure. @@ -984,7 +1011,6 @@ fn main() { register_diagnostics! { E0385, // {} in an aliasable location E0388, // {} in a static location - E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ... E0503, // cannot use `..` because it was mutably borrowed E0508, // cannot move out of type `..`, a non-copy fixed-size array E0524, // two closures require unique access to `..` at the same time diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9944f453f0a..1df12b63e0a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -215,15 +215,18 @@ fn report_elision_failure( { let mut m = String::new(); let len = params.len(); - let mut any_lifetimes = false; - for (i, info) in params.into_iter().enumerate() { + let elided_params: Vec<_> = params.into_iter() + .filter(|info| info.lifetime_count > 0) + .collect(); + + let elided_len = elided_params.len(); + + for (i, info) in elided_params.into_iter().enumerate() { let ElisionFailureInfo { name, lifetime_count: n, have_bound_regions } = info; - any_lifetimes = any_lifetimes || (n > 0); - let help_name = if name.is_empty() { format!("argument {}", i + 1) } else { @@ -237,13 +240,14 @@ fn report_elision_failure( if have_bound_regions { "free " } else { "" } ) })[..]); - if len == 2 && i == 0 { + if elided_len == 2 && i == 0 { m.push_str(" or "); - } else if i + 2 == len { + } else if i + 2 == elided_len { m.push_str(", or "); - } else if i + 1 != len { + } else if i != elided_len - 1 { m.push_str(", "); } + } if len == 0 { @@ -252,7 +256,7 @@ fn report_elision_failure( there is no value for it to be borrowed from"); help!(db, "consider giving it a 'static lifetime"); - } else if !any_lifetimes { + } else if elided_len == 0 { help!(db, "this function's return type contains a borrowed value with \ an elided lifetime, but the lifetime cannot be derived from \ @@ -260,7 +264,7 @@ fn report_elision_failure( help!(db, "consider giving it an explicit bounded or 'static \ lifetime"); - } else if len == 1 { + } else if elided_len == 1 { help!(db, "this function's return type contains a borrowed value, but \ the signature does not say which {} it is borrowed from", diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 005e25b07d4..a103acadcf6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1566,7 +1566,8 @@ impl<'a> fmt::Display for Item<'a> { write!(fmt, "")?; // in-band write!(fmt, "")?; if let Some(version) = self.item.stable_since() { - write!(fmt, "{}", version)?; + write!(fmt, "{0}", + version)?; } write!(fmt, r##" @@ -2136,7 +2137,7 @@ fn render_stability_since_raw<'a>(w: &mut fmt::Formatter, containing_ver: Option<&'a str>) -> fmt::Result { if let Some(v) = ver { if containing_ver != ver && v.len() > 0 { - write!(w, "
{}
", + write!(w, "
{0}
", v)? } } diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index 8d0c93f21b2..7c9985d7d23 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -423,7 +423,7 @@ impl EmitterWriter { &format!(" (defined in {})", self.cm.span_to_filename(def_site_span))); } - let snippet = self.cm.span_to_string(sp); + let snippet = self.cm.span_to_string(trace.call_site); print_diagnostic(&mut self.dst, &snippet, Note, &diag_string, None)?; } Ok(()) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 65df379781e..f243706eecb 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -70,15 +70,9 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // Keep going, outside-in. let fully_expanded = fld.fold_expr(expanded_expr); - let span = fld.new_span(span); fld.cx.bt_pop(); - fully_expanded.map(|e| ast::Expr { - id: ast::DUMMY_NODE_ID, - node: e.node, - span: span, - attrs: e.attrs, - }) + fully_expanded } ast::ExprKind::InPlace(placer, value_expr) => { diff --git a/src/test/compile-fail/borrowck/borrowck-borrowed-uniq-rvalue-2.rs b/src/test/compile-fail/borrowck/borrowck-borrowed-uniq-rvalue-2.rs index 309e286f48e..7b811f581c1 100644 --- a/src/test/compile-fail/borrowck/borrowck-borrowed-uniq-rvalue-2.rs +++ b/src/test/compile-fail/borrowck/borrowck-borrowed-uniq-rvalue-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern: borrowed value does not live long enough + struct defer<'a> { x: &'a [&'a str], } @@ -28,6 +30,5 @@ fn defer<'r>(x: &'r [&'r str]) -> defer<'r> { fn main() { let x = defer(&vec!("Goodbye", "world!")); - //~^ ERROR borrowed value does not live long enough x.x[0]; } diff --git a/src/test/compile-fail/issue-15167.rs b/src/test/compile-fail/issue-15167.rs index 898e6be6fc8..2bd7da91d2c 100644 --- a/src/test/compile-fail/issue-15167.rs +++ b/src/test/compile-fail/issue-15167.rs @@ -11,22 +11,26 @@ // macro f should not be able to inject a reference to 'n'. macro_rules! f { () => (n) } +//~^ ERROR unresolved name `n` +//~| ERROR unresolved name `n` +//~| ERROR unresolved name `n` +//~| ERROR unresolved name `n` fn main() -> (){ for n in 0..1 { - println!("{}", f!()); //~ ERROR unresolved name `n` + println!("{}", f!()); } if let Some(n) = None { - println!("{}", f!()); //~ ERROR unresolved name `n` + println!("{}", f!()); } if false { } else if let Some(n) = None { - println!("{}", f!()); //~ ERROR unresolved name `n` + println!("{}", f!()); } while let Some(n) = None { - println!("{}", f!()); //~ ERROR unresolved name `n` + println!("{}", f!()); } } diff --git a/src/test/compile-fail/issue-30255.rs b/src/test/compile-fail/issue-30255.rs new file mode 100644 index 00000000000..1daa6a61f77 --- /dev/null +++ b/src/test/compile-fail/issue-30255.rs @@ -0,0 +1,35 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// Test that lifetime elision error messages correctly omit parameters +// with no elided lifetimes + +struct S<'a> { + field: &'a i32, +} + +fn f(a: &S, b: i32) -> &i32 { +//~^ ERROR missing lifetime specifier [E0106] +//~^^ HELP does not say which one of `a`'s 2 elided lifetimes it is borrowed from + panic!(); +} + +fn g(a: &S, b: bool, c: &i32) -> &i32 { +//~^ ERROR missing lifetime specifier [E0106] +//~^^ HELP does not say whether it is borrowed from one of `a`'s 2 elided lifetimes or `c` + panic!(); +} + +fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { +//~^ ERROR missing lifetime specifier [E0106] +//~^^ HELP does not say whether it is borrowed from `a`, one of `c`'s 2 elided lifetimes, or `d` + panic!(); +} + diff --git a/src/test/compile-fail/macro-backtrace-invalid-internals.rs b/src/test/compile-fail/macro-backtrace-invalid-internals.rs index 5069ec7d284..ebec204184d 100644 --- a/src/test/compile-fail/macro-backtrace-invalid-internals.rs +++ b/src/test/compile-fail/macro-backtrace-invalid-internals.rs @@ -36,13 +36,13 @@ macro_rules! fake_method_expr { macro_rules! fake_field_expr { () => { - 1.fake + 1.fake //~ ERROR no field with that name } } macro_rules! fake_anon_field_expr { () => { - (1).0 + (1).0 //~ ERROR type was not a tuple } } @@ -52,8 +52,6 @@ fn main() { fake_anon_field_stmt!(); //~ NOTE in this expansion of let _ = fake_method_expr!(); //~ NOTE in this expansion of - let _ = fake_field_expr!(); //~ ERROR no field with that name - //~^ NOTE in this expansion of - let _ = fake_anon_field_expr!(); //~ ERROR type was not a tuple - //~^ NOTE in this expansion of + let _ = fake_field_expr!(); //~ NOTE in this expansion of + let _ = fake_anon_field_expr!(); //~ NOTE in this expansion of } diff --git a/src/test/compile-fail/macro-backtrace-nested.rs b/src/test/compile-fail/macro-backtrace-nested.rs index c935ccef055..c2a270ea9f5 100644 --- a/src/test/compile-fail/macro-backtrace-nested.rs +++ b/src/test/compile-fail/macro-backtrace-nested.rs @@ -12,20 +12,19 @@ // we replace the span of the expanded expression with that of the call site. macro_rules! nested_expr { - () => (fake) + () => (fake) //~ ERROR unresolved name + //~^ ERROR unresolved name } macro_rules! call_nested_expr { - () => (nested_expr!()) + () => (nested_expr!()) //~ NOTE in this expansion of nested_expr! } macro_rules! call_nested_expr_sum { - () => { 1 + nested_expr!(); } //~ ERROR unresolved name - //~^ NOTE in this expansion of nested_expr! + () => { 1 + nested_expr!(); } //~ NOTE in this expansion of nested_expr! } fn main() { - 1 + call_nested_expr!(); //~ ERROR unresolved name - //~^ NOTE in this expansion of call_nested_expr! + 1 + call_nested_expr!(); //~ NOTE in this expansion of call_nested_expr! call_nested_expr_sum!(); //~ NOTE in this expansion of } diff --git a/src/test/compile-fail/macro-backtrace-println.rs b/src/test/compile-fail/macro-backtrace-println.rs index a485b9056de..c2277c3e6d8 100644 --- a/src/test/compile-fail/macro-backtrace-println.rs +++ b/src/test/compile-fail/macro-backtrace-println.rs @@ -21,11 +21,11 @@ macro_rules! myprint { } macro_rules! myprintln { - ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ ERROR invalid reference to argument `0` - //~^ NOTE in this expansion of myprint! - //~^^ NOTE in this expansion of concat! + ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); //~ NOTE in this expansion of myprint! + //~^ NOTE in this expansion of concat! } fn main() { - myprintln!("{}"); //~ NOTE in this expansion of + myprintln!("{}"); //~ ERROR invalid reference to argument `0` + //~^ NOTE in this expansion of } diff --git a/src/test/compile-fail/variant-used-as-type.rs b/src/test/compile-fail/variant-used-as-type.rs new file mode 100644 index 00000000000..73defa6eef9 --- /dev/null +++ b/src/test/compile-fail/variant-used-as-type.rs @@ -0,0 +1,30 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test error message when enum variants are used as types + + +// issue 21225 +enum Ty { + A, + B(Ty::A), + //~^ ERROR: found value `Ty::A` used as a type +} + + +// issue 19197 +enum E { + A +} + +impl E::A {} +//~^ ERROR: found value `E::A` used as a type + +fn main() {}