From 7da9ea0af48ccf9468863408b449d33c415cbde7 Mon Sep 17 00:00:00 2001 From: Val Vanderschaegen Date: Thu, 12 May 2016 18:56:20 -0700 Subject: [PATCH 01/12] Add a note about Higher-Ranked Trait Bounds in docs on Closures. When using closures that take references with explicit lifetimes sometimes it's required to use where F: for<..> ... syntax to express the right lifetimes. This adds a quick note to the docs so other users can discover it as well. --- src/doc/book/closures.md | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index d81619b647f..7bfe67f4c8b 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: + +``` +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: + +``` +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, From 64feba03d76641a8eb290f3f8409d6be04b3fe11 Mon Sep 17 00:00:00 2001 From: Val Vanderschaegen Date: Fri, 13 May 2016 12:01:45 -0700 Subject: [PATCH 02/12] Updated based on CR feedback. --- src/doc/book/closures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index 7bfe67f4c8b..e690f4edd47 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -334,7 +334,7 @@ fn call_with_ref(some_closure:F) -> i32 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 { ``` @@ -348,12 +348,12 @@ 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 +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. From e2bf1f85330b80e837d35cf3ef3f93cd2c22407d Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Tue, 17 May 2016 15:33:31 -0500 Subject: [PATCH 03/12] Add regression tests for error message when using enum variant as a type I'm guessing these were actually fixed with PR #27085. Closes #21225 Closes #19197 --- src/test/compile-fail/variant-used-as-type.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/compile-fail/variant-used-as-type.rs 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() {} From c22a45be58fa4428211313d77749bdb6f3a5c77a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 May 2016 14:59:06 -0700 Subject: [PATCH 04/12] std: Update libc submodule Brings in a fix where `-lutil` is no longer passed for musl targets, lifting the need for a musl toolchain to be installed again. Closes #33608 --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From acfe199c02a3cbc0d500678ea30426daf392f0d3 Mon Sep 17 00:00:00 2001 From: Timothy McRoy Date: Sun, 15 May 2016 15:30:59 -0500 Subject: [PATCH 05/12] Add descriptive error explanation for E0502 --- src/librustc_borrowck/diagnostics.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index cdbad685008..59484254909 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -501,6 +501,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. @@ -983,7 +1010,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 From 7fef1628735622ad005245ea2294449720ba7c5c Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 18 May 2016 00:02:04 -0500 Subject: [PATCH 06/12] Only print parameters with elided lifetimes in elision error messages. When displaying the function parameters for a lifetime elision error message, this changes it to first filter out the parameters that don't have elided lifetimes. Fixes #30255. --- src/librustc_typeck/astconv.rs | 26 ++++++++++++++------- src/test/compile-fail/issue-30255.rs | 35 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/issue-30255.rs diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4faefb61056..c3633625436 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -215,15 +215,24 @@ 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(); + + let any_lifetimes = if elided_len > 0 { + true + } else { + false + }; + + 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 +246,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 { @@ -260,7 +270,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/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!(); +} + From f630419351122a3af49ca1ea65f88c69b6a8a004 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 18 May 2016 11:26:54 +0000 Subject: [PATCH 07/12] Fix bug in macro expression spans --- src/libsyntax/ext/expand.rs | 8 +------- .../borrowck/borrowck-borrowed-uniq-rvalue-2.rs | 3 ++- src/test/compile-fail/issue-15167.rs | 12 ++++++++---- .../macro-backtrace-invalid-internals.rs | 10 ++++------ src/test/compile-fail/macro-backtrace-nested.rs | 11 +++++------ src/test/compile-fail/macro-backtrace-println.rs | 8 ++++---- 6 files changed, 24 insertions(+), 28 deletions(-) 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/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 } From 98f1c35c77835395d12c72d5d5712fc1686cc3b4 Mon Sep 17 00:00:00 2001 From: mark-summerfield Date: Wed, 18 May 2016 17:43:22 +0100 Subject: [PATCH 08/12] Clarified that `let(mut x, y) =` only makes x mutable, not y --- src/doc/book/mutability.md | 2 ++ 1 file changed, 2 insertions(+) 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 From c9517189d7f0e851347859e437fc796411008e66 Mon Sep 17 00:00:00 2001 From: Steven Burns Date: Wed, 18 May 2016 11:30:50 -0600 Subject: [PATCH 09/12] Rust syntax coloring for some ignore, should-panic and no-run snippets. --- src/doc/book/advanced-linking.md | 4 ++-- src/doc/book/closures.md | 2 +- src/doc/book/compiler-plugins.md | 10 +++++----- src/doc/book/concurrency.md | 8 ++++---- src/doc/book/documentation.md | 12 ++++++------ src/doc/book/ffi.md | 12 ++++++------ src/doc/book/functions.md | 4 ++-- src/doc/book/inline-assembly.md | 2 +- src/doc/book/loops.md | 2 +- src/doc/book/macros.md | 10 +++++----- src/doc/book/operators-and-overloading.md | 2 +- src/doc/book/trait-objects.md | 2 +- src/doc/book/traits.md | 2 +- src/doc/book/vectors.md | 4 ++-- 14 files changed, 38 insertions(+), 38 deletions(-) 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..4828acb97b4 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -344,7 +344,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/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]); ``` From a50c82bc3bde5988a8f32ef2b593f0b051545e8a Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 18 May 2016 13:09:25 -0500 Subject: [PATCH 10/12] Simplify report_elision_failure a little bit. --- src/librustc_typeck/astconv.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c3633625436..8fc6b552e14 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -222,12 +222,6 @@ fn report_elision_failure( let elided_len = elided_params.len(); - let any_lifetimes = if elided_len > 0 { - true - } else { - false - }; - for (i, info) in elided_params.into_iter().enumerate() { let ElisionFailureInfo { name, lifetime_count: n, have_bound_regions @@ -262,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 \ From f8e9c150278c5f70c4e9c337f53cb66d077e1bc3 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 19 May 2016 00:19:57 +0000 Subject: [PATCH 11/12] Fix macro expansion backtrace diagnostics --- src/libsyntax/errors/emitter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index e7007fb0568..529da2538e9 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -422,7 +422,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(()) From 352a70b3a066eb02bd7738014700f467655c4ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=CC=81my=20Rakic?= Date: Wed, 18 May 2016 03:54:52 +0200 Subject: [PATCH 12/12] Make the #[stable(since)] version attribute clearer with a tooltip --- src/librustdoc/html/render.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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)? } }