Auto merge of #33742 - Manishearth:rollup, r=Manishearth
Rollup of 10 pull requests - Successful merges: #33353, #33611, #33696, #33698, #33705, #33708, #33712, #33720, #33721, #33730 - Failed merges:
This commit is contained in:
commit
764ef92ae7
@ -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
|
||||
|
@ -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<F>(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<F>(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<F>(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);
|
||||
```
|
||||
|
||||
|
@ -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<MacResult+'static> {
|
||||
|
||||
@ -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() { }
|
||||
|
@ -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<T>` 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<T>` 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<MutexGuard<T>>
|
||||
```
|
||||
|
||||
|
@ -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)]
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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!");
|
||||
# }
|
||||
|
@ -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
|
||||
|
@ -74,7 +74,7 @@ for x in 0..10 {
|
||||
|
||||
In slightly more abstract terms,
|
||||
|
||||
```ignore
|
||||
```rust,ignore
|
||||
for var in expression {
|
||||
code
|
||||
}
|
||||
|
@ -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 {
|
||||
() => {{
|
||||
...
|
||||
|
@ -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
|
||||
|
@ -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<T> HasArea<T> for Square<T>
|
||||
where T: Mul<Output=T> + Copy { ... }
|
||||
```
|
||||
|
@ -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;
|
||||
```
|
||||
|
@ -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<T: PartialEq> Rectangle<T> { ... }
|
||||
```
|
||||
|
||||
|
@ -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]);
|
||||
```
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6598e2cbfd7e09bfca249cc3dcbf889735f73ce1
|
||||
Subproject commit b19b5465a1235be3323363cdc11838739b593029
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -1566,7 +1566,8 @@ impl<'a> fmt::Display for Item<'a> {
|
||||
write!(fmt, "</span>")?; // in-band
|
||||
write!(fmt, "<span class='out-of-band'>")?;
|
||||
if let Some(version) = self.item.stable_since() {
|
||||
write!(fmt, "<span class='since'>{}</span>", version)?;
|
||||
write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
|
||||
version)?;
|
||||
}
|
||||
write!(fmt,
|
||||
r##"<span id='render-detail'>
|
||||
@ -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, "<div class=\"since\">{}</div>",
|
||||
write!(w, "<div class='since' title='Stable since Rust version {0}'>{0}</div>",
|
||||
v)?
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
|
@ -70,15 +70,9 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
||||
|
||||
// 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) => {
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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!());
|
||||
}
|
||||
}
|
||||
|
35
src/test/compile-fail/issue-30255.rs
Normal file
35
src/test/compile-fail/issue-30255.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//
|
||||
// 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!();
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
30
src/test/compile-fail/variant-used-as-type.rs
Normal file
30
src/test/compile-fail/variant-used-as-type.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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() {}
|
Loading…
Reference in New Issue
Block a user