about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-29 08:40:39 +0000
committerbors <bors@rust-lang.org>2017-06-29 08:40:39 +0000
commit7acce3724d6ba5cb84d6eef6d6847f8573a1fe5a (patch)
tree1cdd6109e4d61790d67fb50fa25a88a8da01fdee
parentdc2003b7cc1af7d7beee0b1ceec3d811c28cb35e (diff)
parentd3329d7102db78a408bc059600c48fc7f99a0e67 (diff)
downloadrust-7acce3724d6ba5cb84d6eef6d6847f8573a1fe5a.tar.gz
rust-7acce3724d6ba5cb84d6eef6d6847f8573a1fe5a.zip
Auto merge of #42964 - arielb1:rollup, r=arielb1
Rollup of 12 pull requests

- Successful merges: #42219, #42831, #42832, #42884, #42886, #42901, #42919, #42920, #42946, #42953, #42955, #42958
- Failed merges:
-rw-r--r--.travis.yml14
-rw-r--r--src/doc/unstable-book/src/language-features/compile-error.md2
-rw-r--r--src/liballoc/allocator.rs2
-rw-r--r--src/liballoc/fmt.rs8
-rw-r--r--src/libcore/cmp.rs10
-rw-r--r--src/libcore/fmt/mod.rs11
-rw-r--r--src/librustc/lint/context.rs26
-rw-r--r--src/librustc/session/mod.rs60
-rw-r--r--src/librustc_lint/builtin.rs10
-rw-r--r--src/librustc_passes/ast_validation.rs26
-rw-r--r--src/librustdoc/html/markdown.rs45
-rw-r--r--src/librustdoc/test.rs3
-rw-r--r--src/libstd/env.rs82
-rw-r--r--src/libstd/path.rs13
-rw-r--r--src/libsyntax/feature_gate.rs8
-rw-r--r--src/libsyntax/parse/parser.rs4
-rw-r--r--src/libsyntax/test.rs14
-rw-r--r--src/libtest/lib.rs58
-rw-r--r--src/test/compile-fail/feature-gate-allow_fail.rs17
-rw-r--r--src/test/compile-fail/patkind-litrange-no-expr.rs36
-rw-r--r--src/test/run-pass/allocator-alloc-one.rs27
-rw-r--r--src/test/run-pass/env.rs98
-rw-r--r--src/test/run-pass/macro-pat-neg-lit.rs35
-rw-r--r--src/test/run-pass/test-allow-fail-attr.rs24
-rw-r--r--src/test/ui/lint/lint-group-style.stderr10
-rw-r--r--src/test/ui/path-lookahead.stderr2
-rw-r--r--src/test/ui/shadowed-type-parameter.rs (renamed from src/test/compile-fail/shadowed-type-parameter.rs)0
-rw-r--r--src/test/ui/shadowed-type-parameter.stderr28
-rw-r--r--src/test/ui/span/issue-24690.stderr6
-rw-r--r--src/tools/compiletest/src/main.rs1
30 files changed, 492 insertions, 188 deletions
diff --git a/.travis.yml b/.travis.yml
index b95196da356..21877ecb43e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -171,16 +171,22 @@ before_script:
       if [[ "$SKIP_BUILD" == true ]]; then
           export RUN_SCRIPT="echo 'skipping, not a full build'";
       else
-          RUN_SCRIPT="stamp src/ci/init_repo.sh . $HOME/rustsrc";
+          RUN_SCRIPT="src/ci/init_repo.sh . $HOME/rustsrc";
           if [ "$TRAVIS_OS_NAME" = "osx" ]; then
-              export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/run.sh";
+              export RUN_SCRIPT="$RUN_SCRIPT && src/ci/run.sh";
           else
-              export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/docker/run.sh $IMAGE";
+              export RUN_SCRIPT="$RUN_SCRIPT && src/ci/docker/run.sh $IMAGE";
           fi
       fi
 
+# Log time information from this machine and an external machine for insight into possible
+# clock drift. Timezones don't matter since relative deltas give all the necessary info.
 script:
-  - sh -x -c "$RUN_SCRIPT"
+  - >
+      date && curl -s --head https://google.com | grep ^Date: | sed 's/Date: //g'
+  - stamp sh -x -c "$RUN_SCRIPT"
+  - >
+      date && curl -s --head https://google.com | grep ^Date: | sed 's/Date: //g'
 
 after_success:
   - >
diff --git a/src/doc/unstable-book/src/language-features/compile-error.md b/src/doc/unstable-book/src/language-features/compile-error.md
index 1b25eeda3f6..4b24c0a6a0d 100644
--- a/src/doc/unstable-book/src/language-features/compile-error.md
+++ b/src/doc/unstable-book/src/language-features/compile-error.md
@@ -2,7 +2,7 @@
 
 The tracking issue for this feature is: [#40872]
 
-[#29599]: https://github.com/rust-lang/rust/issues/40872
+[#40872]: https://github.com/rust-lang/rust/issues/40872
 
 ------------------------
 
diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs
index 9bddce29957..bf38629ed38 100644
--- a/src/liballoc/allocator.rs
+++ b/src/liballoc/allocator.rs
@@ -873,7 +873,7 @@ pub unsafe trait Alloc {
     {
         let k = Layout::new::<T>();
         if k.size() > 0 {
-            unsafe { self.alloc(k).map(|p|Unique::new(*p as *mut T)) }
+            unsafe { self.alloc(k).map(|p| Unique::new(p as *mut T)) }
         } else {
             Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
         }
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index 1bd95fb82aa..4847b21c0b3 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -498,12 +498,10 @@ pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
 
 use string;
 
-/// The format function takes a precompiled format string and a list of
-/// arguments, to return the resulting formatted string.
+/// The `format` function takes an `Arguments` struct and returns the resulting
+/// formatted string.
 ///
-/// # Arguments
-///
-///   * args - a structure of arguments generated via the `format_args!` macro.
+/// The `Arguments` instance can be created with the `format_args!` macro.
 ///
 /// # Examples
 ///
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 33d2f729e1a..7882a8ce5c8 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -379,8 +379,9 @@ impl<T: Ord> Ord for Reverse<T> {
 ///
 /// ## Derivable
 ///
-/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
-/// ordering based on the top-to-bottom declaration order of the struct's members.
+/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
+/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
+/// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
 ///
 /// ## How can I implement `Ord`?
 ///
@@ -512,8 +513,9 @@ impl PartialOrd for Ordering {
 ///
 /// ## Derivable
 ///
-/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
-/// ordering based on the top-to-bottom declaration order of the struct's members.
+/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
+/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
+/// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
 ///
 /// ## How can I implement `PartialOrd`?
 ///
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 8c3d3ce7d88..bcc6d53c81d 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -897,14 +897,11 @@ pub trait UpperExp {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// The `write` function takes an output stream, a precompiled format string,
-/// and a list of arguments. The arguments will be formatted according to the
-/// specified format string into the output stream provided.
+/// The `write` function takes an output stream, and an `Arguments` struct
+/// that can be precompiled with the `format_args!` macro.
 ///
-/// # Arguments
-///
-///   * output - the buffer to write output to
-///   * args - the precompiled arguments generated by `format_args!`
+/// The arguments will be formatted according to the specified format string
+/// into the output stream provided.
 ///
 /// # Examples
 ///
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 466d163854f..8202c6106d1 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -510,7 +510,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
     }
 
     let name = lint.name_lower();
-    let mut def = None;
 
     // Except for possible note details, forbid behaves like deny.
     let effective_level = if level == Forbid { Deny } else { level };
@@ -525,7 +524,8 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
 
     match source {
         Default => {
-            err.note(&format!("#[{}({})] on by default", level.as_str(), name));
+            sess.diag_note_once(&mut err, lint,
+                                &format!("#[{}({})] on by default", level.as_str(), name));
         },
         CommandLine(lint_flag_val) => {
             let flag = match level {
@@ -534,20 +534,24 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
             };
             let hyphen_case_lint_name = name.replace("_", "-");
             if lint_flag_val.as_str() == name {
-                err.note(&format!("requested on the command line with `{} {}`",
-                                  flag, hyphen_case_lint_name));
+                sess.diag_note_once(&mut err, lint,
+                                    &format!("requested on the command line with `{} {}`",
+                                             flag, hyphen_case_lint_name));
             } else {
                 let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
-                err.note(&format!("`{} {}` implied by `{} {}`",
-                                  flag, hyphen_case_lint_name, flag, hyphen_case_flag_val));
+                sess.diag_note_once(&mut err, lint,
+                                    &format!("`{} {}` implied by `{} {}`",
+                                             flag, hyphen_case_lint_name, flag,
+                                             hyphen_case_flag_val));
             }
         },
         Node(lint_attr_name, src) => {
-            def = Some(src);
+            sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
             if lint_attr_name.as_str() != name {
                 let level_str = level.as_str();
-                err.note(&format!("#[{}({})] implied by #[{}({})]",
-                                  level_str, name, level_str, lint_attr_name));
+                sess.diag_note_once(&mut err, lint,
+                                    &format!("#[{}({})] implied by #[{}({})]",
+                                             level_str, name, level_str, lint_attr_name));
             }
         }
     }
@@ -563,10 +567,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
         err.note(&citation);
     }
 
-    if let Some(span) = def {
-        sess.diag_span_note_once(&mut err, lint, span, "lint level defined here");
-    }
-
     err
 }
 
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 70c07982f83..fb513f573d7 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -79,10 +79,10 @@ pub struct Session {
     pub working_dir: (String, bool),
     pub lint_store: RefCell<lint::LintStore>,
     pub lints: RefCell<lint::LintTable>,
-    /// Set of (LintId, span, message) tuples tracking lint (sub)diagnostics
-    /// that have been set once, but should not be set again, in order to avoid
-    /// redundantly verbose output (Issue #24690).
-    pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Span, String)>>,
+    /// Set of (LintId, Option<Span>, message) tuples tracking lint
+    /// (sub)diagnostics that have been set once, but should not be set again,
+    /// in order to avoid redundantly verbose output (Issue #24690).
+    pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Option<Span>, String)>>,
     pub plugin_llvm_passes: RefCell<Vec<String>>,
     pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
@@ -157,6 +157,13 @@ pub struct PerfStats {
     pub decode_def_path_tables_time: Cell<Duration>,
 }
 
+/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
+enum DiagnosticBuilderMethod {
+    Note,
+    SpanNote,
+    // add more variants as needed to support one-time diagnostics
+}
+
 impl Session {
     pub fn local_crate_disambiguator(&self) -> Symbol {
         *self.crate_disambiguator.borrow()
@@ -329,34 +336,53 @@ impl Session {
         &self.parse_sess.span_diagnostic
     }
 
-    /// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
-    /// deduplicates on lint ID, span, and message for this `Session` if we're
-    /// not outputting in JSON mode.
-    //
-    // FIXME: if the need arises for one-time diagnostics other than
-    // `span_note`, we almost certainly want to generalize this
-    // "check/insert-into the one-time diagnostics map, then set message if
-    // it's not already there" code to accomodate all of them
-    pub fn diag_span_note_once<'a, 'b>(&'a self,
-                                       diag_builder: &'b mut DiagnosticBuilder<'a>,
-                                       lint: &'static lint::Lint, span: Span, message: &str) {
+    /// Analogous to calling methods on the given `DiagnosticBuilder`, but
+    /// deduplicates on lint ID, span (if any), and message for this `Session`
+    /// if we're not outputting in JSON mode.
+    fn diag_once<'a, 'b>(&'a self,
+                         diag_builder: &'b mut DiagnosticBuilder<'a>,
+                         method: DiagnosticBuilderMethod,
+                         lint: &'static lint::Lint, message: &str, span: Option<Span>) {
+        let mut do_method = || {
+            match method {
+                DiagnosticBuilderMethod::Note => {
+                    diag_builder.note(message);
+                },
+                DiagnosticBuilderMethod::SpanNote => {
+                    diag_builder.span_note(span.expect("span_note expects a span"), message);
+                }
+            }
+        };
+
         match self.opts.error_format {
             // when outputting JSON for tool consumption, the tool might want
             // the duplicates
             config::ErrorOutputType::Json => {
-                diag_builder.span_note(span, &message);
+                do_method()
             },
             _ => {
                 let lint_id = lint::LintId::of(lint);
                 let id_span_message = (lint_id, span, message.to_owned());
                 let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
                 if fresh {
-                    diag_builder.span_note(span, &message);
+                    do_method()
                 }
             }
         }
     }
 
+    pub fn diag_span_note_once<'a, 'b>(&'a self,
+                                       diag_builder: &'b mut DiagnosticBuilder<'a>,
+                                       lint: &'static lint::Lint, span: Span, message: &str) {
+        self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote, lint, message, Some(span));
+    }
+
+    pub fn diag_note_once<'a, 'b>(&'a self,
+                                  diag_builder: &'b mut DiagnosticBuilder<'a>,
+                                  lint: &'static lint::Lint, message: &str) {
+        self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, lint, message, None);
+    }
+
     pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
         self.parse_sess.codemap()
     }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index ad154f9b815..2b331509025 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -684,13 +684,9 @@ fn fl_lit_check_expr(cx: &EarlyContext, expr: &ast::Expr) {
         // These may occur in patterns
         // and can maybe contain float literals
         ExprKind::Unary(_, ref f) => fl_lit_check_expr(cx, f),
-        // These may occur in patterns
-        // and can't contain float literals
-        ExprKind::Path(..) => (),
-        // If something unhandled is encountered, we need to expand the
-        // search or ignore more ExprKinds.
-        _ => span_bug!(expr.span, "Unhandled expression {:?} in float lit pattern lint",
-                       expr.node),
+        // Other kinds of exprs can't occur in patterns so we don't have to check them
+        // (ast_validation will emit an error if they occur)
+        _ => (),
     }
 }
 
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 7c443a4ac75..6ad03186dc7 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -93,6 +93,17 @@ impl<'a> AstValidator<'a> {
             }
         }
     }
+
+    /// matches '-' lit | lit (cf. parser::Parser::parse_pat_literal_maybe_minus)
+    fn check_expr_within_pat(&self, expr: &Expr) {
+        match expr.node {
+            ExprKind::Lit(..) | ExprKind::Path(..) => {}
+            ExprKind::Unary(UnOp::Neg, ref inner)
+                if match inner.node { ExprKind::Lit(_) => true, _ => false } => {}
+            _ => self.err_handler().span_err(expr.span, "arbitrary expressions aren't allowed \
+                                                         in patterns")
+        }
+    }
 }
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
@@ -308,6 +319,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         }
         visit::walk_generics(self, g)
     }
+
+    fn visit_pat(&mut self, pat: &'a Pat) {
+        match pat.node {
+            PatKind::Lit(ref expr) => {
+                self.check_expr_within_pat(expr);
+            }
+            PatKind::Range(ref start, ref end, _) => {
+                self.check_expr_within_pat(start);
+                self.check_expr_within_pat(end);
+            }
+            _ => {}
+        }
+
+        visit::walk_pat(self, pat)
+    }
 }
 
 pub fn check_crate(session: &Session, krate: &Crate) {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index bea13397eca..03da451fd9a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -769,7 +769,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
                                block_info.should_panic, block_info.no_run,
                                block_info.ignore, block_info.test_harness,
                                block_info.compile_fail, block_info.error_codes,
-                               line, filename);
+                               line, filename, block_info.allow_fail);
             } else {
                 tests.add_old_test(text, filename);
             }
@@ -859,7 +859,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                                block_info.should_panic, block_info.no_run,
                                block_info.ignore, block_info.test_harness,
                                block_info.compile_fail, block_info.error_codes,
-                               line, filename);
+                               line, filename, block_info.allow_fail);
                 prev_offset = offset;
             }
             Event::Start(Tag::Header(level)) => {
@@ -889,6 +889,7 @@ struct LangString {
     test_harness: bool,
     compile_fail: bool,
     error_codes: Vec<String>,
+    allow_fail: bool,
 }
 
 impl LangString {
@@ -902,6 +903,7 @@ impl LangString {
             test_harness: false,
             compile_fail: false,
             error_codes: Vec::new(),
+            allow_fail: false,
         }
     }
 
@@ -930,6 +932,7 @@ impl LangString {
                 }
                 "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; }
                 "ignore" => { data.ignore = true; seen_rust_tags = !seen_other_tags; }
+                "allow_fail" => { data.allow_fail = true; seen_rust_tags = !seen_other_tags; }
                 "rust" => { data.rust = true; seen_rust_tags = true; }
                 "test_harness" => {
                     data.test_harness = true;
@@ -1118,7 +1121,7 @@ mod tests {
     fn test_lang_string_parse() {
         fn t(s: &str,
             should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool,
-            compile_fail: bool, error_codes: Vec<String>) {
+            compile_fail: bool, allow_fail: bool, error_codes: Vec<String>) {
             assert_eq!(LangString::parse(s), LangString {
                 should_panic: should_panic,
                 no_run: no_run,
@@ -1128,25 +1131,31 @@ mod tests {
                 compile_fail: compile_fail,
                 error_codes: error_codes,
                 original: s.to_owned(),
+                allow_fail: allow_fail,
             })
         }
 
+        fn v() -> Vec<String> {
+            Vec::new()
+        }
+
         // marker                | should_panic| no_run| ignore| rust | test_harness| compile_fail
-        //                       | error_codes
-        t("",                      false,        false,  false,  true,  false, false, Vec::new());
-        t("rust",                  false,        false,  false,  true,  false, false, Vec::new());
-        t("sh",                    false,        false,  false,  false, false, false, Vec::new());
-        t("ignore",                false,        false,  true,   true,  false, false, Vec::new());
-        t("should_panic",          true,         false,  false,  true,  false, false, Vec::new());
-        t("no_run",                false,        true,   false,  true,  false, false, Vec::new());
-        t("test_harness",          false,        false,  false,  true,  true,  false, Vec::new());
-        t("compile_fail",          false,        true,   false,  true,  false, true,  Vec::new());
-        t("{.no_run .example}",    false,        true,   false,  true,  false, false, Vec::new());
-        t("{.sh .should_panic}",   true,         false,  false,  false, false, false, Vec::new());
-        t("{.example .rust}",      false,        false,  false,  true,  false, false, Vec::new());
-        t("{.test_harness .rust}", false,        false,  false,  true,  true,  false, Vec::new());
-        t("text, no_run",          false,        true,   false,  false, false, false, Vec::new());
-        t("text,no_run",           false,        true,   false,  false, false, false, Vec::new());
+        //                       | allow_fail | error_codes
+        t("",                      false,        false,  false,  true,  false, false, false, v());
+        t("rust",                  false,        false,  false,  true,  false, false, false, v());
+        t("sh",                    false,        false,  false,  false, false, false, false, v());
+        t("ignore",                false,        false,  true,   true,  false, false, false, v());
+        t("should_panic",          true,         false,  false,  true,  false, false, false, v());
+        t("no_run",                false,        true,   false,  true,  false, false, false, v());
+        t("test_harness",          false,        false,  false,  true,  true,  false, false, v());
+        t("compile_fail",          false,        true,   false,  true,  false, true,  false, v());
+        t("allow_fail",            false,        false,  false,  true,  false, false, true,  v());
+        t("{.no_run .example}",    false,        true,   false,  true,  false, false, false, v());
+        t("{.sh .should_panic}",   true,         false,  false,  false, false, false, false, v());
+        t("{.example .rust}",      false,        false,  false,  true,  false, false, false, v());
+        t("{.test_harness .rust}", false,        false,  false,  true,  true,  false, false, v());
+        t("text, no_run",          false,        true,   false,  false, false, false, false, v());
+        t("text,no_run",           false,        true,   false,  false, false, false, false, v());
     }
 
     #[test]
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index cfe2fad0fa4..4766778eed1 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -467,7 +467,7 @@ impl Collector {
     pub fn add_test(&mut self, test: String,
                     should_panic: bool, no_run: bool, should_ignore: bool,
                     as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
-                    line: usize, filename: String) {
+                    line: usize, filename: String, allow_fail: bool) {
         let name = self.generate_name(line, &filename);
         // to be removed when hoedown is removed
         if self.render_type == RenderType::Pulldown {
@@ -499,6 +499,7 @@ impl Collector {
                 ignore: should_ignore,
                 // compiler failures are test failures
                 should_panic: testing::ShouldPanic::No,
+                allow_fail: allow_fail,
             },
             testfn: testing::DynTestFn(box move |()| {
                 let panic = io::set_panic(None);
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 1dfae0ce83f..f81adad3ebe 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -949,63 +949,9 @@ mod arch {
 mod tests {
     use super::*;
 
-    use iter::repeat;
-    use rand::{self, Rng};
-    use ffi::{OsString, OsStr};
+    use ffi::OsStr;
     use path::{Path, PathBuf};
 
-    fn make_rand_name() -> OsString {
-        let mut rng = rand::thread_rng();
-        let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
-                                     .collect::<String>());
-        let n = OsString::from(n);
-        assert!(var_os(&n).is_none());
-        n
-    }
-
-    fn eq(a: Option<OsString>, b: Option<&str>) {
-        assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
-    }
-
-    #[test]
-    fn test_set_var() {
-        let n = make_rand_name();
-        set_var(&n, "VALUE");
-        eq(var_os(&n), Some("VALUE"));
-    }
-
-    #[test]
-    fn test_remove_var() {
-        let n = make_rand_name();
-        set_var(&n, "VALUE");
-        remove_var(&n);
-        eq(var_os(&n), None);
-    }
-
-    #[test]
-    fn test_set_var_overwrite() {
-        let n = make_rand_name();
-        set_var(&n, "1");
-        set_var(&n, "2");
-        eq(var_os(&n), Some("2"));
-        set_var(&n, "");
-        eq(var_os(&n), Some(""));
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn test_var_big() {
-        let mut s = "".to_string();
-        let mut i = 0;
-        while i < 100 {
-            s.push_str("aaaaaaaaaa");
-            i += 1;
-        }
-        let n = make_rand_name();
-        set_var(&n, &s);
-        eq(var_os(&n), Some(&s));
-    }
-
     #[test]
     #[cfg_attr(target_os = "emscripten", ignore)]
     fn test_self_exe_path() {
@@ -1018,32 +964,6 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "emscripten", ignore)]
-    fn test_env_set_get_huge() {
-        let n = make_rand_name();
-        let s = repeat("x").take(10000).collect::<String>();
-        set_var(&n, &s);
-        eq(var_os(&n), Some(&s));
-        remove_var(&n);
-        eq(var_os(&n), None);
-    }
-
-    #[test]
-    fn test_env_set_var() {
-        let n = make_rand_name();
-
-        let mut e = vars_os();
-        set_var(&n, "VALUE");
-        assert!(!e.any(|(k, v)| {
-            &*k == &*n && &*v == "VALUE"
-        }));
-
-        assert!(vars_os().any(|(k, v)| {
-            &*k == &*n && &*v == "VALUE"
-        }));
-    }
-
-    #[test]
     fn test() {
         assert!((!Path::new("test-path").is_absolute()));
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 42a54ed6d75..472ce6bc4fe 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -276,7 +276,7 @@ impl<'a> Prefix<'a> {
 /// ```
 /// use std::path;
 ///
-/// assert!(path::is_separator('/'));
+/// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
 /// assert!(!path::is_separator('❤'));
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1499,9 +1499,9 @@ impl AsRef<OsStr> for PathBuf {
 /// A slice of a path (akin to [`str`]).
 ///
 /// This type supports a number of operations for inspecting a path, including
-/// breaking the path into its components (separated by `/` or `\`, depending on
-/// the platform), extracting the file name, determining whether the path is
-/// absolute, and so on.
+/// breaking the path into its components (separated by `/` on Unix and by either
+/// `/` or `\` on Windows), extracting the file name, determining whether the path
+/// is absolute, and so on.
 ///
 /// This is an *unsized* type, meaning that it must always be used behind a
 /// pointer like `&` or [`Box`]. For an owned version of this type,
@@ -1520,10 +1520,11 @@ impl AsRef<OsStr> for PathBuf {
 /// use std::path::Path;
 /// use std::ffi::OsStr;
 ///
-/// let path = Path::new("/tmp/foo/bar.txt");
+/// // Note: this example does work on Windows
+/// let path = Path::new("./foo/bar.txt");
 ///
 /// let parent = path.parent();
-/// assert_eq!(parent, Some(Path::new("/tmp/foo")));
+/// assert_eq!(parent, Some(Path::new("./foo")));
 ///
 /// let file_stem = path.file_stem();
 /// assert_eq!(file_stem, Some(OsStr::new("bar")));
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index d7d3a70f3c7..74bf19b841e 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -354,6 +354,9 @@ declare_features! (
 
     // rustc internal
     (active, abi_thiscall, "1.19.0", None),
+
+    // Allows a test to fail without failing the whole suite
+    (active, allow_fail, "1.19.0", Some(42219)),
 );
 
 declare_features! (
@@ -812,6 +815,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                              "used internally by rustc",
                                              cfg_fn!(rustc_attrs))),
 
+    ("allow_fail", Normal, Gated(Stability::Unstable,
+                                 "allow_fail",
+                                 "allow_fail attribute is currently unstable",
+                                 cfg_fn!(allow_fail))),
+
     // Crate level attributes
     ("crate_name", CrateLevel, Ungated),
     ("crate_type", CrateLevel, Ungated),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 851a638e148..5b0031b2f17 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1659,8 +1659,10 @@ impl<'a> Parser<'a> {
         Ok(codemap::Spanned { node: lit, span: lo.to(self.prev_span) })
     }
 
-    /// matches '-' lit | lit
+    /// matches '-' lit | lit (cf. ast_validation::AstValidator::check_expr_within_pat)
     pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
+        maybe_whole_expr!(self);
+
         let minus_lo = self.span;
         let minus_present = self.eat(&token::BinOp(token::Minus));
         let lo = self.span;
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index a0d1785c6ff..86f5f42eac7 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -52,7 +52,8 @@ struct Test {
     path: Vec<Ident> ,
     bench: bool,
     ignore: bool,
-    should_panic: ShouldPanic
+    should_panic: ShouldPanic,
+    allow_fail: bool,
 }
 
 struct TestCtxt<'a> {
@@ -133,7 +134,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
                         path: self.cx.path.clone(),
                         bench: is_bench_fn(&self.cx, &i),
                         ignore: is_ignored(&i),
-                        should_panic: should_panic(&i, &self.cx)
+                        should_panic: should_panic(&i, &self.cx),
+                        allow_fail: is_allowed_fail(&i),
                     };
                     self.cx.testfns.push(test);
                     self.tests.push(i.ident);
@@ -383,6 +385,10 @@ fn is_ignored(i: &ast::Item) -> bool {
     i.attrs.iter().any(|attr| attr.check_name("ignore"))
 }
 
+fn is_allowed_fail(i: &ast::Item) -> bool {
+    i.attrs.iter().any(|attr| attr.check_name("allow_fail"))
+}
+
 fn should_panic(i: &ast::Item, cx: &TestCtxt) -> ShouldPanic {
     match i.attrs.iter().find(|attr| attr.check_name("should_panic")) {
         Some(attr) => {
@@ -668,6 +674,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
             }
         }
     };
+    let allow_fail_expr = ecx.expr_bool(span, test.allow_fail);
 
     // self::test::TestDesc { ... }
     let desc_expr = ecx.expr_struct(
@@ -675,7 +682,8 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
         test_path("TestDesc"),
         vec![field("name", name_expr),
              field("ignore", ignore_expr),
-             field("should_panic", fail_expr)]);
+             field("should_panic", fail_expr),
+             field("allow_fail", allow_fail_expr)]);
 
 
     let mut visible_path = match cx.toplevel_reexport {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 2094fd8898d..92cfb862b16 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -212,6 +212,7 @@ pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
     pub should_panic: ShouldPanic,
+    pub allow_fail: bool,
 }
 
 #[derive(Clone)]
@@ -523,6 +524,7 @@ pub enum TestResult {
     TrFailed,
     TrFailedMsg(String),
     TrIgnored,
+    TrAllowedFail,
     TrMetrics(MetricMap),
     TrBench(BenchSamples),
 }
@@ -543,6 +545,7 @@ struct ConsoleTestState<T> {
     passed: usize,
     failed: usize,
     ignored: usize,
+    allowed_fail: usize,
     filtered_out: usize,
     measured: usize,
     metrics: MetricMap,
@@ -572,6 +575,7 @@ impl<T: Write> ConsoleTestState<T> {
             passed: 0,
             failed: 0,
             ignored: 0,
+            allowed_fail: 0,
             filtered_out: 0,
             measured: 0,
             metrics: MetricMap::new(),
@@ -594,6 +598,10 @@ impl<T: Write> ConsoleTestState<T> {
         self.write_short_result("ignored", "i", term::color::YELLOW)
     }
 
+    pub fn write_allowed_fail(&mut self) -> io::Result<()> {
+        self.write_short_result("FAILED (allowed)", "a", term::color::YELLOW)
+    }
+
     pub fn write_metric(&mut self) -> io::Result<()> {
         self.write_pretty("metric", term::color::CYAN)
     }
@@ -669,6 +677,7 @@ impl<T: Write> ConsoleTestState<T> {
             TrOk => self.write_ok(),
             TrFailed | TrFailedMsg(_) => self.write_failed(),
             TrIgnored => self.write_ignored(),
+            TrAllowedFail => self.write_allowed_fail(),
             TrMetrics(ref mm) => {
                 self.write_metric()?;
                 self.write_plain(&format!(": {}\n", mm.fmt_metrics()))
@@ -702,6 +711,7 @@ impl<T: Write> ConsoleTestState<T> {
                         TrFailed => "failed".to_owned(),
                         TrFailedMsg(ref msg) => format!("failed: {}", msg),
                         TrIgnored => "ignored".to_owned(),
+                        TrAllowedFail => "failed (allowed)".to_owned(),
                         TrMetrics(ref mm) => mm.fmt_metrics(),
                         TrBench(ref bs) => fmt_bench_samples(bs),
                     },
@@ -761,7 +771,8 @@ impl<T: Write> ConsoleTestState<T> {
     }
 
     pub fn write_run_finish(&mut self) -> io::Result<bool> {
-        assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
+        assert!(self.passed + self.failed + self.ignored + self.measured +
+                    self.allowed_fail == self.total);
 
         if self.options.display_output {
             self.write_outputs()?;
@@ -778,12 +789,24 @@ impl<T: Write> ConsoleTestState<T> {
         } else {
             self.write_pretty("FAILED", term::color::RED)?;
         }
-        let s = format!(". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
-                        self.passed,
-                        self.failed,
-                        self.ignored,
-                        self.measured,
-                        self.filtered_out);
+        let s = if self.allowed_fail > 0 {
+            format!(
+                ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out\n\n",
+                self.passed,
+                self.failed + self.allowed_fail,
+                self.allowed_fail,
+                self.ignored,
+                self.measured,
+                self.filtered_out)
+        } else {
+            format!(
+                ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
+                self.passed,
+                self.failed,
+                self.ignored,
+                self.measured,
+                self.filtered_out)
+        };
         self.write_plain(&s)?;
         return Ok(success);
     }
@@ -891,6 +914,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
                         st.not_failures.push((test, stdout));
                     }
                     TrIgnored => st.ignored += 1,
+                    TrAllowedFail => st.allowed_fail += 1,
                     TrMetrics(mm) => {
                         let tname = test.name;
                         let MetricMap(mm) = mm;
@@ -945,12 +969,14 @@ fn should_sort_failures_before_printing_them() {
         name: StaticTestName("a"),
         ignore: false,
         should_panic: ShouldPanic::No,
+        allow_fail: false,
     };
 
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
         should_panic: ShouldPanic::No,
+        allow_fail: false,
     };
 
     let mut st = ConsoleTestState {
@@ -962,6 +988,7 @@ fn should_sort_failures_before_printing_them() {
         passed: 0,
         failed: 0,
         ignored: 0,
+        allowed_fail: 0,
         filtered_out: 0,
         measured: 0,
         max_name_len: 10,
@@ -1471,8 +1498,13 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any + Send>>) -> Tes
                   .unwrap_or(false) {
                 TrOk
             } else {
-                TrFailedMsg(format!("Panic did not include expected string '{}'", msg))
+                if desc.allow_fail {
+                    TrAllowedFail
+                } else {
+                    TrFailedMsg(format!("Panic did not include expected string '{}'", msg))
+                }
             },
+        _ if desc.allow_fail => TrAllowedFail,
         _ => TrFailed,
     }
 }
@@ -1706,6 +1738,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: true,
                 should_panic: ShouldPanic::No,
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1723,6 +1756,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: true,
                 should_panic: ShouldPanic::No,
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1742,6 +1776,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: false,
                 should_panic: ShouldPanic::Yes,
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1761,6 +1796,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: false,
                 should_panic: ShouldPanic::YesWithMessage("error message"),
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1782,6 +1818,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: false,
                 should_panic: ShouldPanic::YesWithMessage(expected),
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1799,6 +1836,7 @@ mod tests {
                 name: StaticTestName("whatever"),
                 ignore: false,
                 should_panic: ShouldPanic::Yes,
+                allow_fail: false,
             },
             testfn: DynTestFn(Box::new(move |()| f())),
         };
@@ -1832,6 +1870,7 @@ mod tests {
                                  name: StaticTestName("1"),
                                  ignore: true,
                                  should_panic: ShouldPanic::No,
+                                 allow_fail: false,
                              },
                              testfn: DynTestFn(Box::new(move |()| {})),
                          },
@@ -1840,6 +1879,7 @@ mod tests {
                                  name: StaticTestName("2"),
                                  ignore: false,
                                  should_panic: ShouldPanic::No,
+                                 allow_fail: false,
                              },
                              testfn: DynTestFn(Box::new(move |()| {})),
                          }];
@@ -1863,6 +1903,7 @@ mod tests {
                     name: StaticTestName(name),
                     ignore: false,
                     should_panic: ShouldPanic::No,
+                    allow_fail: false,
                 },
                 testfn: DynTestFn(Box::new(move |()| {}))
             })
@@ -1944,6 +1985,7 @@ mod tests {
                         name: DynTestName((*name).clone()),
                         ignore: false,
                         should_panic: ShouldPanic::No,
+                        allow_fail: false,
                     },
                     testfn: DynTestFn(Box::new(move |()| testfn())),
                 };
diff --git a/src/test/compile-fail/feature-gate-allow_fail.rs b/src/test/compile-fail/feature-gate-allow_fail.rs
new file mode 100644
index 00000000000..11247402809
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-allow_fail.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// check that #[allow_fail] is feature-gated
+
+#[allow_fail] //~ ERROR allow_fail attribute is currently unstable
+fn ok_to_fail() {
+    assert!(false);
+}
+
diff --git a/src/test/compile-fail/patkind-litrange-no-expr.rs b/src/test/compile-fail/patkind-litrange-no-expr.rs
new file mode 100644
index 00000000000..afb2cbb7db3
--- /dev/null
+++ b/src/test/compile-fail/patkind-litrange-no-expr.rs
@@ -0,0 +1,36 @@
+// Copyright 2017 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.
+
+macro_rules! enum_number {
+    ($name:ident { $($variant:ident = $value:expr, )* }) => {
+        enum $name {
+            $($variant = $value,)*
+        }
+
+        fn foo(value: i32) -> Option<$name> {
+            match value {
+                $( $value => Some($name::$variant), )* // PatKind::Lit
+                $( $value ... 42 => Some($name::$variant), )* // PatKind::Range
+                _ => None
+            }
+        }
+    }
+}
+
+enum_number!(Change {
+    Pos = 1,
+    Neg = -1,
+    Arith = 1 + 1, //~ ERROR arbitrary expressions aren't allowed in patterns
+                   //~^ ERROR arbitrary expressions aren't allowed in patterns
+                   //~^^ ERROR only char and numeric types are allowed in range patterns
+});
+
+fn main() {}
+
diff --git a/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs
new file mode 100644
index 00000000000..7cc547dcc04
--- /dev/null
+++ b/src/test/run-pass/allocator-alloc-one.rs
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+#![feature(alloc, allocator_api, heap_api, unique)]
+
+extern crate alloc;
+
+use alloc::heap::HeapAlloc;
+use alloc::allocator::Alloc;
+
+fn main() {
+    unsafe {
+        let ptr = HeapAlloc.alloc_one::<i32>().unwrap_or_else(|e| {
+            HeapAlloc.oom(e)
+        });
+        *ptr.as_ptr() = 4;
+        assert_eq!(*ptr.as_ptr(), 4);
+        HeapAlloc.dealloc_one(ptr);
+    }
+}
diff --git a/src/test/run-pass/env.rs b/src/test/run-pass/env.rs
new file mode 100644
index 00000000000..e602fb2d7d2
--- /dev/null
+++ b/src/test/run-pass/env.rs
@@ -0,0 +1,98 @@
+// Copyright 2017 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.
+
+// compile-flags: --test
+
+#![feature(rand, std_panic)]
+
+use std::env::*;
+use std::__rand as rand;
+use std::__rand::Rng;
+use std::iter::repeat;
+use std::ffi::{OsString, OsStr};
+
+
+fn make_rand_name() -> OsString {
+    let mut rng = rand::thread_rng();
+    let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
+                                 .collect::<String>());
+    let n = OsString::from(n);
+    assert!(var_os(&n).is_none());
+    n
+}
+
+fn eq(a: Option<OsString>, b: Option<&str>) {
+    assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
+}
+
+#[test]
+fn test_set_var() {
+    let n = make_rand_name();
+    set_var(&n, "VALUE");
+    eq(var_os(&n), Some("VALUE"));
+}
+
+#[test]
+fn test_remove_var() {
+    let n = make_rand_name();
+    set_var(&n, "VALUE");
+    remove_var(&n);
+    eq(var_os(&n), None);
+}
+
+#[test]
+fn test_set_var_overwrite() {
+    let n = make_rand_name();
+    set_var(&n, "1");
+    set_var(&n, "2");
+    eq(var_os(&n), Some("2"));
+    set_var(&n, "");
+    eq(var_os(&n), Some(""));
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_var_big() {
+    let mut s = "".to_string();
+    let mut i = 0;
+    while i < 100 {
+        s.push_str("aaaaaaaaaa");
+        i += 1;
+    }
+    let n = make_rand_name();
+    set_var(&n, &s);
+    eq(var_os(&n), Some(&s));
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_env_set_get_huge() {
+    let n = make_rand_name();
+    let s = repeat("x").take(10000).collect::<String>();
+    set_var(&n, &s);
+    eq(var_os(&n), Some(&s));
+    remove_var(&n);
+    eq(var_os(&n), None);
+}
+
+#[test]
+fn test_env_set_var() {
+    let n = make_rand_name();
+
+    let mut e = vars_os();
+    set_var(&n, "VALUE");
+    assert!(!e.any(|(k, v)| {
+        &*k == &*n && &*v == "VALUE"
+    }));
+
+    assert!(vars_os().any(|(k, v)| {
+        &*k == &*n && &*v == "VALUE"
+    }));
+}
diff --git a/src/test/run-pass/macro-pat-neg-lit.rs b/src/test/run-pass/macro-pat-neg-lit.rs
new file mode 100644
index 00000000000..43ac697edce
--- /dev/null
+++ b/src/test/run-pass/macro-pat-neg-lit.rs
@@ -0,0 +1,35 @@
+// Copyright 2017 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.
+
+macro_rules! enum_number {
+    ($name:ident { $($variant:ident = $value:expr, )* }) => {
+        enum $name {
+            $($variant = $value,)*
+        }
+
+        fn foo(value: i32) -> Option<$name> {
+            match value {
+                $( $value => Some($name::$variant), )*
+                _ => None
+            }
+        }
+    }
+}
+
+enum_number!(Change {
+    Down = -1,
+    None = 0,
+    Up = 1,
+});
+
+fn main() {
+    if let Some(Change::Down) = foo(-1) {} else { panic!() }
+}
+
diff --git a/src/test/run-pass/test-allow-fail-attr.rs b/src/test/run-pass/test-allow-fail-attr.rs
new file mode 100644
index 00000000000..aa9cf76617f
--- /dev/null
+++ b/src/test/run-pass/test-allow-fail-attr.rs
@@ -0,0 +1,24 @@
+// 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.
+
+// compile-flags: --test
+#![feature(allow_fail)]
+
+#[test]
+#[allow_fail]
+fn test1() {
+    panic!();
+}
+
+#[test]
+#[allow_fail]
+fn test2() {
+    assert!(true);
+}
diff --git a/src/test/ui/lint/lint-group-style.stderr b/src/test/ui/lint/lint-group-style.stderr
index dec44c317e4..636370de302 100644
--- a/src/test/ui/lint/lint-group-style.stderr
+++ b/src/test/ui/lint/lint-group-style.stderr
@@ -4,12 +4,12 @@ error: function `CamelCase` should have a snake case name such as `camel_case`
 14 | fn CamelCase() {}
    | ^^^^^^^^^^^^^^^^^
    |
-   = note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
 note: lint level defined here
   --> $DIR/lint-group-style.rs:11:9
    |
 11 | #![deny(bad_style)]
    |         ^^^^^^^^^
+   = note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
 
 error: function `CamelCase` should have a snake case name such as `camel_case`
   --> $DIR/lint-group-style.rs:22:9
@@ -17,12 +17,12 @@ error: function `CamelCase` should have a snake case name such as `camel_case`
 22 |         fn CamelCase() {}
    |         ^^^^^^^^^^^^^^^^^
    |
-   = note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
 note: lint level defined here
   --> $DIR/lint-group-style.rs:20:14
    |
 20 |     #[forbid(bad_style)]
    |              ^^^^^^^^^
+   = note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
 
 error: static variable `bad` should have an upper case name such as `BAD`
   --> $DIR/lint-group-style.rs:24:9
@@ -30,12 +30,12 @@ error: static variable `bad` should have an upper case name such as `BAD`
 24 |         static bad: isize = 1;
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
 note: lint level defined here
   --> $DIR/lint-group-style.rs:20:14
    |
 20 |     #[forbid(bad_style)]
    |              ^^^^^^^^^
+   = note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
 
 warning: function `CamelCase` should have a snake case name such as `camel_case`
   --> $DIR/lint-group-style.rs:30:9
@@ -43,12 +43,12 @@ warning: function `CamelCase` should have a snake case name such as `camel_case`
 30 |         fn CamelCase() {}
    |         ^^^^^^^^^^^^^^^^^
    |
-   = note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
 note: lint level defined here
   --> $DIR/lint-group-style.rs:28:17
    |
 28 |         #![warn(bad_style)]
    |                 ^^^^^^^^^
+   = note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
 
 warning: type `snake_case` should have a camel case name such as `SnakeCase`
   --> $DIR/lint-group-style.rs:32:9
@@ -56,12 +56,12 @@ warning: type `snake_case` should have a camel case name such as `SnakeCase`
 32 |         struct snake_case;
    |         ^^^^^^^^^^^^^^^^^^
    |
-   = note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
 note: lint level defined here
   --> $DIR/lint-group-style.rs:28:17
    |
 28 |         #![warn(bad_style)]
    |                 ^^^^^^^^^
+   = note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
 
 error: aborting due to previous error(s)
 
diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr
index 1e19977e84a..8fd1b8de687 100644
--- a/src/test/ui/path-lookahead.stderr
+++ b/src/test/ui/path-lookahead.stderr
@@ -23,6 +23,4 @@ warning: function is never used: `no_parens`
 20 | |   return <T as ToString>::to_string(&arg);
 21 | | }
    | |_^
-   |
-   = note: #[warn(dead_code)] on by default
 
diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/ui/shadowed-type-parameter.rs
index 1f72db1e894..1f72db1e894 100644
--- a/src/test/compile-fail/shadowed-type-parameter.rs
+++ b/src/test/ui/shadowed-type-parameter.rs
diff --git a/src/test/ui/shadowed-type-parameter.stderr b/src/test/ui/shadowed-type-parameter.stderr
new file mode 100644
index 00000000000..d77523299bc
--- /dev/null
+++ b/src/test/ui/shadowed-type-parameter.stderr
@@ -0,0 +1,28 @@
+error[E0194]: type parameter `T` shadows another type parameter of the same name
+  --> $DIR/shadowed-type-parameter.rs:30:27
+   |
+27 | trait Bar<T> {
+   |           - first `T` declared here
+...
+30 |     fn shadow_in_required<T>(&self);
+   |                           ^ shadows another type parameter
+
+error[E0194]: type parameter `T` shadows another type parameter of the same name
+  --> $DIR/shadowed-type-parameter.rs:33:27
+   |
+27 | trait Bar<T> {
+   |           - first `T` declared here
+...
+33 |     fn shadow_in_provided<T>(&self) {}
+   |                           ^ shadows another type parameter
+
+error[E0194]: type parameter `T` shadows another type parameter of the same name
+  --> $DIR/shadowed-type-parameter.rs:18:25
+   |
+17 | impl<T> Foo<T> {
+   |      - first `T` declared here
+18 |     fn shadow_in_method<T>(&self) {}
+   |                         ^ shadows another type parameter
+
+error: aborting due to previous error(s)
+
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
index 598f9f51307..edc150f65ea 100644
--- a/src/test/ui/span/issue-24690.stderr
+++ b/src/test/ui/span/issue-24690.stderr
@@ -4,20 +4,18 @@ error: variable `theTwo` should have a snake case name such as `the_two`
 19 |     let theTwo = 2;
    |         ^^^^^^
    |
-   = note: #[deny(non_snake_case)] implied by #[deny(warnings)]
 note: lint level defined here
   --> $DIR/issue-24690.rs:16:9
    |
 16 | #![deny(warnings)]
    |         ^^^^^^^^
+   = note: #[deny(non_snake_case)] implied by #[deny(warnings)]
 
 error: variable `theOtherTwo` should have a snake case name such as `the_other_two`
   --> $DIR/issue-24690.rs:20:9
    |
 20 |     let theOtherTwo = 2;
    |         ^^^^^^^^^^^
-   |
-   = note: #[deny(non_snake_case)] implied by #[deny(warnings)]
 
 error: unused variable: `theOtherTwo`
   --> $DIR/issue-24690.rs:20:9
@@ -25,12 +23,12 @@ error: unused variable: `theOtherTwo`
 20 |     let theOtherTwo = 2;
    |         ^^^^^^^^^^^
    |
-   = note: #[deny(unused_variables)] implied by #[deny(warnings)]
 note: lint level defined here
   --> $DIR/issue-24690.rs:16:9
    |
 16 | #![deny(warnings)]
    |         ^^^^^^^^
+   = note: #[deny(unused_variables)] implied by #[deny(warnings)]
 
 error: aborting due to previous error(s)
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index c88ffba357a..b4663b0ee6c 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -476,6 +476,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
             name: make_test_name(config, testpaths),
             ignore: ignore,
             should_panic: should_panic,
+            allow_fail: false,
         },
         testfn: make_test_closure(config, testpaths),
     }