about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-17 05:52:35 +0000
committerbors <bors@rust-lang.org>2015-04-17 05:52:35 +0000
commitb7fb57529aded92c4f470568e6b5ea7a5a28f6a4 (patch)
treea906315439fb7dcdab8d025229a0e5e2028af7da
parent7fbedc58e3b0e102ece926a7f99041fc3ad3037a (diff)
parenta4be1ec140e7c61b8f73834ab722f7b056ad21b9 (diff)
downloadrust-b7fb57529aded92c4f470568e6b5ea7a5a28f6a4.tar.gz
rust-b7fb57529aded92c4f470568e6b5ea7a5a28f6a4.zip
Auto merge of #24512 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #23782, #24455, #24490, #24493, #24494, #24496, #24498, #24499, #24501, #24502, #24506, #24507, #24508, #24509, #24510
- Failed merges: #24488
-rw-r--r--src/doc/complement-design-faq.md4
-rw-r--r--src/doc/reference.md18
-rw-r--r--src/doc/trpl/closures.md6
-rw-r--r--src/doc/trpl/concurrency.md4
-rw-r--r--src/doc/trpl/documentation.md15
-rw-r--r--src/doc/trpl/error-handling.md35
-rw-r--r--src/doc/trpl/installing-rust.md4
-rw-r--r--src/doc/trpl/macros.md2
-rw-r--r--src/doc/trpl/primitive-types.md32
-rw-r--r--src/libcore/iter.rs10
-rw-r--r--src/libcore/raw.rs4
-rw-r--r--src/libcore/result.rs4
-rw-r--r--src/librustc/diagnostics.rs82
-rw-r--r--src/librustc/middle/ty.rs2
-rw-r--r--src/librustc/plugin/mod.rs2
-rw-r--r--src/librustdoc/html/render.rs7
-rw-r--r--src/libstd/collections/hash/map.rs1
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax/parse/obsolete.rs3
19 files changed, 175 insertions, 62 deletions
diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md
index 0f2c37a5abf..678c3970fe2 100644
--- a/src/doc/complement-design-faq.md
+++ b/src/doc/complement-design-faq.md
@@ -56,7 +56,7 @@ Types which are [`Sync`][sync] are thread-safe when multiple shared
 references to them are used concurrently. Types which are not `Sync` are not
 thread-safe, and thus when used in a global require unsafe code to use.
 
-[sync]: core/kinds/trait.Sync.html
+[sync]: core/marker/trait.Sync.html
 
 ### If mutable static items that implement `Sync` are safe, why is taking &mut SHARABLE unsafe?
 
@@ -139,7 +139,7 @@ and explicitly calling the `clone` method. Making user-defined copy operators
 explicit surfaces the underlying complexity, forcing the developer to opt-in
 to potentially expensive operations.
 
-[copy]: core/kinds/trait.Copy.html
+[copy]: core/marker/trait.Copy.html
 [clone]: core/clone/trait.Clone.html
 
 ## No move constructors
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 0ed23dae9b5..57110df0f9e 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2177,6 +2177,14 @@ The following configurations must be defined by the implementation:
 * `unix`. See `target_family`.
 * `windows`. See `target_family`.
 
+You can also set another attribute based on a `cfg` variable with `cfg_attr`:
+
+```rust,ignore
+#[cfg_attr(a, b)]
+```
+
+Will be the same as `#[b]` if `a` is set by `cfg`, and nothing otherwise.
+
 ### Lint check attributes
 
 A lint check names a potentially undesirable coding pattern, such as
@@ -2368,7 +2376,7 @@ The currently implemented features of the reference compiler are:
                     removed entirely for something more wholesome.
 
 * `custom_attribute` - Allows the usage of attributes unknown to the compiler
-                       so that new attributes can be added in a bacwards compatible
+                       so that new attributes can be added in a backwards compatible
                        manner (RFC 572).
 
 * `custom_derive` - Allows the use of `#[derive(Foo,Bar)]` as sugar for
@@ -2397,7 +2405,7 @@ The currently implemented features of the reference compiler are:
                  nasty hack that will certainly be removed.
 
 * `main` - Allows use of the `#[main]` attribute, which changes the entry point
-           into a Rust program. This capabiilty is subject to change.
+           into a Rust program. This capability is subject to change.
 
 * `macro_reexport` - Allows macros to be re-exported from one crate after being imported
                      from another. This feature was originally designed with the sole
@@ -2444,7 +2452,9 @@ The currently implemented features of the reference compiler are:
 * `simd_ffi` - Allows use of SIMD vectors in signatures for foreign functions.
                The SIMD interface is subject to change.
 
-* `staged_api` - Allows usage of stability markers and `#![staged_api]` in a crate
+* `staged_api` - Allows usage of stability markers and `#![staged_api]` in a
+                 crate. Stability markers are also attributes: `#[stable]`,
+                 `#[unstable]`, and `#[deprecated]` are the three levels.
 
 * `static_assert` - The `#[static_assert]` functionality is experimental and
                     unstable. The attribute can be attached to a `static` of
@@ -2453,7 +2463,7 @@ The currently implemented features of the reference compiler are:
                     is unintuitive and suboptimal.
 
 * `start` - Allows use of the `#[start]` attribute, which changes the entry point
-            into a Rust program. This capabiilty, especially the signature for the
+            into a Rust program. This capability, especially the signature for the
             annotated function, is subject to change.
 
 * `struct_inherit` - Allows using struct inheritance, which is barely
diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md
index e63331e5206..e3de8eb30be 100644
--- a/src/doc/trpl/closures.md
+++ b/src/doc/trpl/closures.md
@@ -205,11 +205,11 @@ you tons of control over what your code does, and closures are no different.
 
 Rust's implementation of closures is a bit different than other languages. They
 are effectively syntax sugar for traits. You'll want to make sure to have read
-the [traits chapter][traits] before this one, as well as the chapter on [static
-and dynamic dispatch][dispatch], which talks about trait objects.
+the [traits chapter][traits] before this one, as well as the chapter on [trait
+objects][trait-objects].
 
 [traits]: traits.html
-[dispatch]: static-and-dynamic-dispatch.html
+[trait-objects]: trait-objects.html
 
 Got all that? Good.
 
diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md
index 159e04e9429..575dfc7417a 100644
--- a/src/doc/trpl/concurrency.md
+++ b/src/doc/trpl/concurrency.md
@@ -176,8 +176,8 @@ Here's the error:
                   ^~~~~~~~~~~~~
 ```
 
-You see, [`Mutex`](std/sync/struct.Mutex.html) has a
-[`lock`](http://doc.rust-lang.org/nightly/std/sync/struct.Mutex.html#method.lock)
+You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
+[`lock`](../std/sync/struct.Mutex.html#method.lock)
 method which has this signature:
 
 ```ignore
diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md
index 06071a8f15f..732521a0c60 100644
--- a/src/doc/trpl/documentation.md
+++ b/src/doc/trpl/documentation.md
@@ -380,7 +380,10 @@ $ rustdoc --test path/to/my/crate/root.rs
 $ cargo test
 ```
 
-That's right, `cargo test` tests embedded documentation too.
+That's right, `cargo test` tests embedded documentation too. However, 
+`cargo test` will not test binary crates, only library ones. This is
+due to the way `rustdoc` works: it links against the library to be tested,
+but with a binary, there’s nothing to link to.
 
 There are a few more annotations that are useful to help `rustdoc` do the right
 thing when testing your code:
@@ -560,3 +563,13 @@ This sets a few different options, with a logo, favicon, and a root URL.
 - `--html-before-content FILE`: includes the contents of FILE directly after
   `<body>`, before the rendered content (including the search bar).
 - `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
+
+## Security note
+
+The Markdown in documentation comments is placed without processing into
+the final webpage. Be careful with literal HTML:
+
+```rust
+/// <script>alert(document.cookie)</script>
+# fn foo() {}
+```
diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md
index 491f7b0c2a0..e261eb01dba 100644
--- a/src/doc/trpl/error-handling.md
+++ b/src/doc/trpl/error-handling.md
@@ -20,18 +20,18 @@ panic. A *failure* is an error that can be recovered from in some way. A
 *panic* is an error that cannot be recovered from.
 
 What do we mean by "recover"? Well, in most cases, the possibility of an error
-is expected. For example, consider the `from_str` function:
+is expected. For example, consider the `parse` function:
 
-```{rust,ignore}
-from_str("5");
+```ignore
+"5".parse();
 ```
 
-This function takes a string argument and converts it into another type. But
-because it's a string, you can't be sure that the conversion actually works.
-For example, what should this convert to?
+This method converts a string into another type. But because it's a string, you
+can't be sure that the conversion actually works. For example, what should this
+convert to?
 
-```{rust,ignore}
-from_str("hello5world");
+```ignore
+"hello5world".parse();
 ```
 
 This won't work. So we know that this function will only work properly for some
@@ -40,7 +40,8 @@ inputs. It's expected behavior. We call this kind of error a *failure*.
 On the other hand, sometimes, there are errors that are unexpected, or which
 we cannot recover from. A classic example is an `assert!`:
 
-```{rust,ignore}
+```rust
+# let x = 5;
 assert!(x == 5);
 ```
 
@@ -119,17 +120,19 @@ Rust calls these sorts of errors *panics*.
 # Handling errors with `Option` and `Result`
 
 The simplest way to indicate that a function may fail is to use the `Option<T>`
-type. Remember our `from_str()` example? Here's its type signature:
+type. For example, the `find` method on strings attempts to find a pattern
+in a string, and returns an `Option`:
 
-```{rust,ignore}
-pub fn from_str<A: FromStr>(s: &str) -> Option<A>
+```rust
+let s = "foo";
+
+assert_eq!(s.find('f'), Some(0));
+assert_eq!(s.find('z'), None);
 ```
 
-`from_str()` returns an `Option<A>`. If the conversion succeeds, it will return
-`Some(value)`, and if it fails, it will return `None`.
 
 This is appropriate for the simplest of cases, but doesn't give us a lot of
-information in the failure case. What if we wanted to know _why_ the conversion
+information in the failure case. What if we wanted to know _why_ the function
 failed? For this, we can use the `Result<T, E>` type. It looks like this:
 
 ```rust
@@ -297,5 +300,5 @@ It's worth noting that you can only use `try!` from a function that returns a
 `Result`, which means that you cannot use `try!` inside of `main()`, because
 `main()` doesn't return anything.
 
-`try!` makes use of [`From<Error>`](../std/convert/trait.From.hml) to determine
+`try!` makes use of [`From<Error>`](../std/convert/trait.From.html) to determine
 what to return in the error case.
diff --git a/src/doc/trpl/installing-rust.md b/src/doc/trpl/installing-rust.md
index 09b4495ffe9..58d9e57dc51 100644
--- a/src/doc/trpl/installing-rust.md
+++ b/src/doc/trpl/installing-rust.md
@@ -91,9 +91,9 @@ If not, there are a number of places where you can get help. The easiest is
 [Mibbit][mibbit]. Click that link, and you'll be chatting with other Rustaceans
 (a silly nickname we call ourselves), and we can help you out. Other great
 resources include [the user’s forum][users], and
-[Stack Overflow][stack overflow].
+[Stack Overflow][stackoverflow].
 
 [irc]: irc://irc.mozilla.org/#rust
 [mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
 [users]: http://users.rust-lang.org/ 
-[stack overflow]: http://stackoverflow.com/questions/tagged/rust
+[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md
index 6d21cb59383..713814d9147 100644
--- a/src/doc/trpl/macros.md
+++ b/src/doc/trpl/macros.md
@@ -33,7 +33,7 @@ mind.
 You may have seen the `vec!` macro, used to initialize a [vector][] with any
 number of elements.
 
-[vector]: arrays-vectors-and-slices.html
+[vector]: vectors.html
 
 ```rust
 let x: Vec<u32> = vec![1, 2, 3];
diff --git a/src/doc/trpl/primitive-types.md b/src/doc/trpl/primitive-types.md
index fcbe2b2f8bf..811080cd509 100644
--- a/src/doc/trpl/primitive-types.md
+++ b/src/doc/trpl/primitive-types.md
@@ -216,6 +216,18 @@ In systems programming languages, strings are a bit more complex than in other
 languages. For now, just read `&str` as a *string slice*, and we’ll learn more
 soon.
 
+You can assign one tuple into another, if they have the same contained types
+and [arity]. Tuples have the same arity when they have the same length.
+
+[arity]: glossary.html#arity
+
+```rust
+let mut x = (1, 2); // x: (i32, i32)
+let y = (2, 3); // y: (i32, i32)
+
+x = y;
+```
+
 You can access the fields in a tuple through a *destructuring let*. Here’s
 an example:
 
@@ -235,20 +247,24 @@ or "breaks up," the tuple, and assigns the bits to three bindings.
 
 This pattern is very powerful, and we’ll see it repeated more later.
 
-There are also a few things you can do with a tuple as a whole, without
-destructuring. You can assign one tuple into another, if they have the same
-contained types and [arity]. Tuples have the same arity when they have the same
-length.
+## Tuple Indexing
+
+You can also access fields of a tuple with indexing syntax:
 
-[arity]: glossary.html#arity
 
 ```rust
-let mut x = (1, 2); // x: (i32, i32)
-let y = (2, 3); // y: (i32, i32)
+let tuple = (1, 2, 3);
 
-x = y;
+let x = tuple.0;
+let y = tuple.1;
+let z = tuple.2;
+
+println!("x is {}", x);
 ```
 
+Like array indexing, it starts at zero, but unlike array indexing, it uses a
+`.`, rather than `[]`s.
+
 You can find more documentation for tuples [in the standard library
 documentation][tuple].
 
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e44b0d1147c..16ee3889880 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -179,8 +179,8 @@ pub trait Iterator {
 
     /// Creates an iterator that iterates over both this and the specified
     /// iterators simultaneously, yielding the two elements as pairs. When
-    /// either iterator returns None, all further invocations of next() will
-    /// return None.
+    /// either iterator returns `None`, all further invocations of next() will
+    /// return `None`.
     ///
     /// # Examples
     ///
@@ -254,7 +254,7 @@ pub trait Iterator {
     }
 
     /// Creates an iterator that both filters and maps elements.
-    /// If the specified function returns None, the element is skipped.
+    /// If the specified function returns `None`, the element is skipped.
     /// Otherwise the option is unwrapped and the new value is yielded.
     ///
     /// # Examples
@@ -403,7 +403,7 @@ pub trait Iterator {
     /// Creates a new iterator that behaves in a similar fashion to fold.
     /// There is a state which is passed between each iteration and can be
     /// mutated as necessary. The yielded values from the closure are yielded
-    /// from the Scan instance when not None.
+    /// from the Scan instance when not `None`.
     ///
     /// # Examples
     ///
@@ -701,7 +701,7 @@ pub trait Iterator {
 
     /// Returns the index of the last element satisfying the specified predicate
     ///
-    /// If no element matches, None is returned.
+    /// If no element matches, `None` is returned.
     ///
     /// Does not consume the iterator *before* the first found element.
     ///
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index ded52ff0778..685b3e5c546 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -71,11 +71,11 @@ impl<T> Clone for Slice<T> {
 /// The representation of a trait object like `&SomeTrait`.
 ///
 /// This struct has the same layout as types like `&SomeTrait` and
-/// `Box<AnotherTrait>`. The [Static and Dynamic Dispatch chapter of the
+/// `Box<AnotherTrait>`. The [Trait Objects chapter of the
 /// Book][moreinfo] contains more details about the precise nature of
 /// these internals.
 ///
-/// [moreinfo]: ../../book/static-and-dynamic-dispatch.html#representation
+/// [moreinfo]: ../../book/trait-objects.html#representation
 ///
 /// `TraitObject` is guaranteed to match layouts, but it is not the
 /// type of trait objects (e.g. the fields are not directly accessible
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 4c74f4646ac..26bc653b26f 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -86,12 +86,12 @@
 //! useful value.
 //!
 //! Consider the `write_all` method defined for I/O types
-//! by the [`Write`](../io/trait.Write.html) trait:
+//! by the [`Write`](../../std/io/trait.Write.html) trait:
 //!
 //! ```
 //! use std::io;
 //!
-//! trait Writer {
+//! trait Write {
 //!     fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>;
 //! }
 //! ```
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 938a74382e2..e1eb8d74186 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -112,6 +112,46 @@ reference when using guards or refactor the entire expression, perhaps by
 putting the condition inside the body of the arm.
 "##,
 
+E0152: r##"
+Lang items are already implemented in the standard library. Unless you are
+writing a free-standing application (e.g. a kernel), you do not need to provide
+them yourself.
+
+You can build a free-standing crate by adding `#![no_std]` to the crate
+attributes:
+
+#![feature(no_std)]
+#![no_std]
+
+See also https://doc.rust-lang.org/book/no-stdlib.html
+"##,
+
+E0158: r##"
+`const` and `static` mean different things. A `const` is a compile-time
+constant, an alias for a literal value. This property means you can match it
+directly within a pattern.
+
+The `static` keyword, on the other hand, guarantees a fixed location in memory.
+This does not always mean that the value is constant. For example, a global
+mutex can be declared `static` as well.
+
+If you want to match against a `static`, consider using a guard instead:
+
+static FORTY_TWO: i32 = 42;
+match Some(42) {
+    Some(x) if x == FORTY_TWO => ...
+    ...
+}
+"##,
+
+E0161: r##"
+In Rust, you can only move a value when its size is known at compile time.
+
+To work around this restriction, consider "hiding" the value behind a reference:
+either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
+it around as usual.
+"##,
+
 E0162: r##"
 An if-let pattern attempts to match the pattern, and enters the body if the
 match was succesful. If the match is irrefutable (when it cannot fail to match),
@@ -151,6 +191,32 @@ loop {
 }
 "##,
 
+E0170: r##"
+Enum variants are qualified by default. For example, given this type:
+
+enum Method {
+    GET,
+    POST
+}
+
+you would match it using:
+
+match m {
+    Method::GET => ...
+    Method::POST => ...
+}
+
+If you don't qualify the names, the code will bind new variables named "GET" and
+"POST" instead. This behavior is likely not what you want, so rustc warns when
+that happens.
+
+Qualified names are good practice, and most code works well with them. But if
+you prefer them unqualified, you can import the variants into scope:
+
+use Method::*;
+enum Method { GET, POST }
+"##,
+
 E0297: r##"
 Patterns used to bind names must be irrefutable. That is, they must guarantee
 that a name will be extracted in all cases. Instead of pattern matching the
@@ -227,6 +293,16 @@ match Some(5) {
 }
 
 See also https://github.com/rust-lang/rust/issues/14587
+"##,
+
+E0306: r##"
+In an array literal `[x; N]`, `N` is the number of elements in the array. This
+number cannot be negative.
+"##,
+
+E0307: r##"
+The length of an array is part of its type. For this reason, this length must be
+a compile-time constant.
 "##
 
 }
@@ -256,10 +332,6 @@ register_diagnostics! {
     E0137,
     E0138,
     E0139,
-    E0152,
-    E0158,
-    E0161,
-    E0170,
     E0261, // use of undeclared lifetime name
     E0262, // illegal lifetime parameter name
     E0263, // lifetime name declared twice in same scope
@@ -291,8 +363,6 @@ register_diagnostics! {
     E0300, // unexpanded macro
     E0304, // expected signed integer constant
     E0305, // expected constant
-    E0306, // expected positive integer for repeat count
-    E0307, // expected constant integer for repeat count
     E0308,
     E0309, // thing may not live long enough
     E0310, // thing may not live long enough
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 1e817890440..eab87dc846d 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -437,7 +437,7 @@ pub struct MethodObject<'tcx> {
     pub vtable_index: usize,
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct MethodCallee<'tcx> {
     pub origin: MethodOrigin<'tcx>,
     pub ty: Ty<'tcx>,
diff --git a/src/librustc/plugin/mod.rs b/src/librustc/plugin/mod.rs
index 3162c4fc570..4a85e1893f0 100644
--- a/src/librustc/plugin/mod.rs
+++ b/src/librustc/plugin/mod.rs
@@ -47,7 +47,7 @@
 //! #![plugin(myplugin)]
 //! ```
 //!
-//! See the [Plugins Chapter](../../book/plugins.html) of the book
+//! See the [Plugins Chapter](../../book/compiler-plugins.html) of the book
 //! for more examples.
 
 pub use self::registry::Registry;
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f87a86eb3a6..250ec34edf7 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -37,7 +37,7 @@ pub use self::ExternalLocation::*;
 use std::ascii::OwnedAsciiExt;
 use std::cell::RefCell;
 use std::cmp::Ordering;
-use std::collections::{HashMap, HashSet};
+use std::collections::{BTreeMap, HashMap, HashSet};
 use std::default::Default;
 use std::fmt;
 use std::fs::{self, File};
@@ -1298,8 +1298,9 @@ impl Context {
         }
     }
 
-    fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
-        let mut map = HashMap::new();
+    fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc>> {
+        // BTreeMap instead of HashMap to get a sorted output
+        let mut map = BTreeMap::new();
         for item in &m.items {
             if self.ignore_private_item(item) { continue }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f554a4f4ed6..9b93066f9fb 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1469,7 +1469,6 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
 }
 
 impl<'a, K, V> Entry<'a, K, V> {
-    /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
     #[unstable(feature = "std_misc",
                reason = "will soon be replaced by or_insert")]
     #[deprecated(since = "1.0",
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 659eb343232..d0975c76e93 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -10,7 +10,7 @@
 
 //! Feature gating
 //!
-//! This modules implements the gating necessary for preventing certain compiler
+//! This module implements the gating necessary for preventing certain compiler
 //! features from being used by default. This module will crawl a pre-expanded
 //! AST to ensure that there are no features which are used that are not
 //! enabled.
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 3b21b5059da..00d9b7f4ea6 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -80,7 +80,8 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
             self.span_warn(sp, &format!("obsolete syntax: {}", kind_str));
         }
 
-        if !self.obsolete_set.contains(&kind) {
+        if !self.obsolete_set.contains(&kind) &&
+            (error || self.sess.span_diagnostic.handler().can_emit_warnings) {
             self.sess
                 .span_diagnostic
                 .handler()