about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-28 20:22:42 +0000
committerbors <bors@rust-lang.org>2019-07-28 20:22:42 +0000
commitc7312fe4ff85ada30103cea58db25d83e0bec4b0 (patch)
treec45aed285c4e04591ea7d6e8bc6c90b3461671a6
parent4560cb830fce63fcffdc4558f4281aaac6a3a1ba (diff)
parent29c377882f545e24b9cc6e1198ee4f72c20d5449 (diff)
downloadrust-c7312fe4ff85ada30103cea58db25d83e0bec4b0.tar.gz
rust-c7312fe4ff85ada30103cea58db25d83e0bec4b0.zip
Auto merge of #63090 - Centril:rollup-xnjwm2h, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #61856 (Lint attributes on function arguments)
 - #62360 (Document that ManuallyDrop::drop should not called more than once)
 - #62392 (Update minifier-rs version)
 - #62871 (Explicit error message for async recursion.)
 - #62995 (Avoid ICE when suggestion span is at Eof)
 - #63053 (SystemTime docs: recommend Instant for elapsed time)
 - #63081 (tidy: Cleanup the directory whitelist)
 - #63088 (Remove anonymous_parameters from unrelated test)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock6
-rw-r--r--src/libcore/mem/manually_drop.rs2
-rw-r--r--src/librustc/hir/intravisit.rs15
-rw-r--r--src/librustc/hir/lowering.rs43
-rw-r--r--src/librustc/hir/map/collector.rs8
-rw-r--r--src/librustc/hir/map/mod.rs7
-rw-r--r--src/librustc/hir/mod.rs5
-rw-r--r--src/librustc/hir/print.rs5
-rw-r--r--src/librustc/lint/context.rs14
-rw-r--r--src/librustc/lint/mod.rs10
-rw-r--r--src/librustc_data_structures/owning_ref/mod.rs12
-rw-r--r--src/librustc_data_structures/owning_ref/tests.rs20
-rw-r--r--src/librustc_errors/lib.rs3
-rw-r--r--src/librustc_mir/build/mod.rs47
-rw-r--r--src/librustc_passes/hir_stats.rs5
-rw-r--r--src/librustc_typeck/check/_match.rs25
-rw-r--r--src/librustc_typeck/check/demand.rs82
-rw-r--r--src/librustc_typeck/check/mod.rs40
-rw-r--r--src/librustc_typeck/error_codes.rs46
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/render.rs8
-rw-r--r--src/libstd/time.rs10
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ext/build.rs1
-rw-r--r--src/libsyntax/mut_visit.rs3
-rw-r--r--src/libsyntax/parse/diagnostics.rs2
-rw-r--r--src/libsyntax/parse/parser.rs8
-rw-r--r--src/libsyntax/visit.rs15
-rw-r--r--src/test/ui/async-await/recursive-async-impl-trait-type.stderr8
-rw-r--r--src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs2
-rw-r--r--src/test/ui/lint/lint-unused-mut-variables.rs64
-rw-r--r--src/test/ui/lint/lint-unused-mut-variables.stderr112
-rw-r--r--src/test/ui/lint/lint-unused-variables.rs64
-rw-r--r--src/test/ui/lint/lint-unused-variables.stderr56
-rw-r--r--src/test/ui/mismatched_types/issue-38371.stderr6
-rw-r--r--src/test/ui/parser/issue-62973.rs8
-rw-r--r--src/test/ui/parser/issue-62973.stderr61
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs179
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs40
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr46
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs4
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr10
-rw-r--r--src/tools/tidy/src/lib.rs20
-rw-r--r--src/tools/tidy/src/style.rs16
44 files changed, 794 insertions, 348 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 312f05d6e73..c08d7444d14 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1700,7 +1700,7 @@ dependencies = [
 
 [[package]]
 name = "minifier"
-version = "0.0.30"
+version = "0.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3195,7 +3195,7 @@ dependencies = [
 name = "rustdoc"
 version = "0.0.0"
 dependencies = [
- "minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "minifier 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4442,7 +4442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
 "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
 "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
-"checksum minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "4c909e78edf61f3aa0dd2086da168cdf304329044bbf248768ca3d20253ec8c0"
+"checksum minifier 0.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "70bf0db2475f5e627787da77ca52fe33c294063f49f4134b8bc662eedb5e7332"
 "checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649"
 "checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c"
 "checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e"
diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs
index 3ad1223e331..bb353993236 100644
--- a/src/libcore/mem/manually_drop.rs
+++ b/src/libcore/mem/manually_drop.rs
@@ -119,6 +119,8 @@ impl<T: ?Sized> ManuallyDrop<T> {
     /// This function runs the destructor of the contained value and thus the wrapped value
     /// now represents uninitialized data. It is up to the user of this method to ensure the
     /// uninitialized data is not actually used.
+    /// In particular, this function can only be called called at most once
+    /// for a given instance of `ManuallyDrop<T>`.
     ///
     /// [`ManuallyDrop::into_inner`]: #method.into_inner
     #[stable(feature = "manually_drop", since = "1.20.0")]
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 2d82314f86a..3781d7df176 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -210,6 +210,10 @@ pub trait Visitor<'v> : Sized {
         }
     }
 
+    fn visit_arg(&mut self, arg: &'v Arg) {
+        walk_arg(self, arg)
+    }
+
     /// Visits the top-level item and (optionally) nested items / impl items. See
     /// `visit_nested_item` for details.
     fn visit_item(&mut self, i: &'v Item) {
@@ -396,10 +400,7 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id
 }
 
 pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
-    for argument in &body.arguments {
-        visitor.visit_id(argument.hir_id);
-        visitor.visit_pat(&argument.pat);
-    }
+    walk_list!(visitor, visit_arg, &body.arguments);
     visitor.visit_expr(&body.value);
 }
 
@@ -452,6 +453,12 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
     visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
 }
 
+pub fn walk_arg<'v, V: Visitor<'v>>(visitor: &mut V, arg: &'v Arg) {
+    visitor.visit_id(arg.hir_id);
+    visitor.visit_pat(&arg.pat);
+    walk_list!(visitor, visit_attribute, &arg.attrs);
+}
+
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
     visitor.visit_vis(&item.vis);
     visitor.visit_ident(item.ident);
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 7121f87d79d..4ddd7818bb1 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2461,8 +2461,10 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
         hir::Arg {
+            attrs: self.lower_attrs(&arg.attrs),
             hir_id: self.lower_node_id(arg.id),
             pat: self.lower_pat(&arg.pat),
+            span: arg.span,
         }
     }
 
@@ -3279,19 +3281,29 @@ impl<'a> LoweringContext<'a> {
                 //
                 // If this is the simple case, this argument will end up being the same as the
                 // original argument, but with a different pattern id.
+                let mut stmt_attrs = ThinVec::new();
+                stmt_attrs.extend(argument.attrs.iter().cloned());
                 let (new_argument_pat, new_argument_id) = this.pat_ident(desugared_span, ident);
                 let new_argument = hir::Arg {
+                    attrs: argument.attrs,
                     hir_id: argument.hir_id,
                     pat: new_argument_pat,
+                    span: argument.span,
                 };
 
+
                 if is_simple_argument {
                     // If this is the simple case, then we only insert one statement that is
                     // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
                     // `HirId`s are densely assigned.
                     let expr = this.expr_ident(desugared_span, ident, new_argument_id);
                     let stmt = this.stmt_let_pat(
-                        desugared_span, Some(P(expr)), argument.pat, hir::LocalSource::AsyncFn);
+                        stmt_attrs,
+                        desugared_span,
+                        Some(P(expr)),
+                        argument.pat,
+                        hir::LocalSource::AsyncFn
+                    );
                     statements.push(stmt);
                 } else {
                     // If this is not the simple case, then we construct two statements:
@@ -3313,14 +3325,23 @@ impl<'a> LoweringContext<'a> {
                         desugared_span, ident, hir::BindingAnnotation::Mutable);
                     let move_expr = this.expr_ident(desugared_span, ident, new_argument_id);
                     let move_stmt = this.stmt_let_pat(
-                        desugared_span, Some(P(move_expr)), move_pat, hir::LocalSource::AsyncFn);
+                        ThinVec::new(),
+                        desugared_span,
+                        Some(P(move_expr)),
+                        move_pat,
+                        hir::LocalSource::AsyncFn
+                    );
 
                     // Construct the `let <pat> = __argN;` statement. We re-use the original
                     // argument's pattern so that `HirId`s are densely assigned.
                     let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
                     let pattern_stmt = this.stmt_let_pat(
-                        desugared_span, Some(P(pattern_expr)), argument.pat,
-                        hir::LocalSource::AsyncFn);
+                        stmt_attrs,
+                        desugared_span,
+                        Some(P(pattern_expr)),
+                        argument.pat,
+                        hir::LocalSource::AsyncFn
+                    );
 
                     statements.push(move_stmt);
                     statements.push(pattern_stmt);
@@ -5030,6 +5051,7 @@ impl<'a> LoweringContext<'a> {
 
                 // `let mut __next`
                 let next_let = self.stmt_let_pat(
+                    ThinVec::new(),
                     desugared_span,
                     None,
                     next_pat,
@@ -5039,6 +5061,7 @@ impl<'a> LoweringContext<'a> {
                 // `let <pat> = __next`
                 let pat = self.lower_pat(pat);
                 let pat_let = self.stmt_let_pat(
+                    ThinVec::new(),
                     head_sp,
                     Some(next_expr),
                     pat,
@@ -5533,19 +5556,20 @@ impl<'a> LoweringContext<'a> {
 
     fn stmt_let_pat(
         &mut self,
+        attrs: ThinVec<Attribute>,
         span: Span,
         init: Option<P<hir::Expr>>,
         pat: P<hir::Pat>,
         source: hir::LocalSource,
     ) -> hir::Stmt {
         let local = hir::Local {
-            pat,
-            ty: None,
-            init,
+            attrs,
             hir_id: self.next_id(),
-            span,
+            init,
+            pat,
             source,
-            attrs: ThinVec::new()
+            span,
+            ty: None,
         };
         self.stmt(span, hir::StmtKind::Local(P(local)))
     }
@@ -5959,6 +5983,7 @@ impl<'a> LoweringContext<'a> {
             hir::BindingAnnotation::Mutable,
         );
         let pinned_let = self.stmt_let_pat(
+            ThinVec::new(),
             span,
             Some(expr),
             pinned_pat,
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 12ea772c1fb..b6807f7d3bb 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -363,6 +363,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         self.currently_in_body = prev_in_body;
     }
 
+    fn visit_arg(&mut self, arg: &'hir Arg) {
+        let node = Node::Arg(arg);
+        self.insert(arg.pat.span, arg.hir_id, node);
+        self.with_parent(arg.hir_id, |this| {
+            intravisit::walk_arg(this, arg);
+        });
+    }
+
     fn visit_item(&mut self, i: &'hir Item) {
         debug!("visit_item: {:?}", i);
         debug_assert_eq!(i.hir_id.owner,
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 43b1dbb6216..5a28d9e7b7d 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -360,6 +360,7 @@ impl<'hir> Map<'hir> {
             Node::Pat(_) |
             Node::Binding(_) |
             Node::Local(_) |
+            Node::Arg(_) |
             Node::Arm(_) |
             Node::Lifetime(_) |
             Node::Visibility(_) |
@@ -932,6 +933,7 @@ impl<'hir> Map<'hir> {
     pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
         self.read(id); // reveals attributes on the node
         let attrs = match self.find_entry(id).map(|entry| entry.node) {
+            Some(Node::Arg(a)) => Some(&a.attrs[..]),
             Some(Node::Local(l)) => Some(&l.attrs[..]),
             Some(Node::Item(i)) => Some(&i.attrs[..]),
             Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
@@ -995,6 +997,7 @@ impl<'hir> Map<'hir> {
     pub fn span(&self, hir_id: HirId) -> Span {
         self.read(hir_id); // reveals span from node
         match self.find_entry(hir_id).map(|entry| entry.node) {
+            Some(Node::Arg(arg)) => arg.span,
             Some(Node::Item(item)) => item.span,
             Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
             Some(Node::TraitItem(trait_method)) => trait_method.span,
@@ -1197,6 +1200,7 @@ impl<'hir> print::PpAnn for Map<'hir> {
 impl<'a> print::State<'a> {
     pub fn print_node(&mut self, node: Node<'_>) {
         match node {
+            Node::Arg(a)          => self.print_arg(&a),
             Node::Item(a)         => self.print_item(&a),
             Node::ForeignItem(a)  => self.print_foreign_item(&a),
             Node::TraitItem(a)    => self.print_trait_item(a),
@@ -1338,6 +1342,9 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
         Some(Node::Pat(_)) => {
             format!("pat {}{}", map.hir_to_pretty_string(id), id_str)
         }
+        Some(Node::Arg(_)) => {
+            format!("arg {}{}", map.hir_to_pretty_string(id), id_str)
+        }
         Some(Node::Arm(_)) => {
             format!("arm {}{}", map.hir_to_pretty_string(id), id_str)
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 3708a905a4b..f9a49447801 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2010,8 +2010,10 @@ pub struct InlineAsm {
 /// Represents an argument in a function header.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arg {
-    pub pat: P<Pat>,
+    pub attrs: HirVec<Attribute>,
     pub hir_id: HirId,
+    pub pat: P<Pat>,
+    pub span: Span,
 }
 
 /// Represents the header (not the body) of a function declaration.
@@ -2701,6 +2703,7 @@ impl CodegenFnAttrs {
 
 #[derive(Copy, Clone, Debug)]
 pub enum Node<'hir> {
+    Arg(&'hir Arg),
     Item(&'hir Item),
     ForeignItem(&'hir ForeignItem),
     TraitItem(&'hir TraitItem),
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index da4a25e0860..9c32831cf88 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1767,6 +1767,11 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
+    pub fn print_arg(&mut self, arg: &hir::Arg) {
+        self.print_outer_attributes(&arg.attrs);
+        self.print_pat(&arg.pat);
+    }
+
     pub fn print_arm(&mut self, arm: &hir::Arm) {
         // I have no idea why this check is necessary, but here it
         // is :(
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 859bc86d3a0..de812410e8b 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -966,6 +966,13 @@ for LateContextAndPass<'a, 'tcx, T> {
         self.context.tables = old_tables;
     }
 
+    fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
+        self.with_lint_attrs(arg.hir_id, &arg.attrs, |cx| {
+            lint_callback!(cx, check_arg, arg);
+            hir_visit::walk_arg(cx, arg);
+        });
+    }
+
     fn visit_body(&mut self, body: &'tcx hir::Body) {
         lint_callback!(self, check_body, body);
         hir_visit::walk_body(self, body);
@@ -1156,6 +1163,13 @@ for LateContextAndPass<'a, 'tcx, T> {
 }
 
 impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
+    fn visit_arg(&mut self, arg: &'a ast::Arg) {
+        self.with_lint_attrs(arg.id, &arg.attrs, |cx| {
+            run_early_pass!(cx, check_arg, arg);
+            ast_visit::walk_arg(cx, arg);
+        });
+    }
+
     fn visit_item(&mut self, it: &'a ast::Item) {
         self.with_lint_attrs(it.id, &it.attrs, |cx| {
             run_early_pass!(cx, check_item, it);
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index dddbc31ccd4..8ddf4603490 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -206,6 +206,7 @@ macro_rules! declare_lint_pass {
 macro_rules! late_lint_methods {
     ($macro:path, $args:tt, [$hir:tt]) => (
         $macro!($args, [$hir], [
+            fn check_arg(a: &$hir hir::Arg);
             fn check_body(a: &$hir hir::Body);
             fn check_body_post(a: &$hir hir::Body);
             fn check_name(a: Span, b: ast::Name);
@@ -358,6 +359,7 @@ macro_rules! declare_combined_late_lint_pass {
 macro_rules! early_lint_methods {
     ($macro:path, $args:tt) => (
         $macro!($args, [
+            fn check_arg(a: &ast::Arg);
             fn check_ident(a: ast::Ident);
             fn check_crate(a: &ast::Crate);
             fn check_crate_post(a: &ast::Crate);
@@ -495,8 +497,6 @@ pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync +
 pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
                                                                            + sync::Sync + 'static>;
 
-
-
 /// Identifies a lint known to the compiler.
 #[derive(Clone, Copy, Debug)]
 pub struct LintId {
@@ -812,6 +812,12 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
         intravisit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
+    fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
+        self.with_lint_attrs(arg.hir_id, &arg.attrs, |builder| {
+            intravisit::walk_arg(builder, arg);
+        });
+    }
+
     fn visit_item(&mut self, it: &'tcx hir::Item) {
         self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
             intravisit::walk_item(builder, it);
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs
index 3b49ce71063..ea9c5283aee 100644
--- a/src/librustc_data_structures/owning_ref/mod.rs
+++ b/src/librustc_data_structures/owning_ref/mod.rs
@@ -10,7 +10,7 @@ This allows moving and dropping of a `OwningRef` without needing to recreate the
 This can sometimes be useful because Rust borrowing rules normally prevent
 moving a type that has been moved from. For example, this kind of code gets rejected:
 
-```rust,ignore
+```compile_fail,E0515
 fn return_owned_and_referenced<'a>() -> (Vec<u8>, &'a [u8]) {
     let v = vec![1, 2, 3, 4];
     let s = &v[1..3];
@@ -43,7 +43,8 @@ and preventing mutable access to root containers, which in practice requires hea
 as provided by `Box<T>`, `Rc<T>`, etc.
 
 Also provided are typedefs for common owner type combinations,
-which allow for less verbose type signatures. For example, `BoxRef<T>` instead of `OwningRef<Box<T>, T>`.
+which allow for less verbose type signatures.
+For example, `BoxRef<T>` instead of `OwningRef<Box<T>, T>`.
 
 The crate also provides the more advanced `OwningHandle` type,
 which allows more freedom in bundling a dependent handle object
@@ -498,7 +499,8 @@ impl<O, T: ?Sized> OwningRef<O, T> {
         }
     }
 
-    /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`.
+    /// Erases the concrete base type of the owner with a trait object
+    /// which implements `Send` and `Sync`.
     ///
     /// This allows mixing of owned references with different owner base types.
     pub fn erase_send_sync_owner<'a>(self) -> OwningRef<O::Erased, T>
@@ -510,7 +512,7 @@ impl<O, T: ?Sized> OwningRef<O, T> {
         }
     }
 
-    // TODO: wrap_owner
+    // UNIMPLEMENTED: wrap_owner
 
     // FIXME: Naming convention?
     /// A getter for the underlying owner.
@@ -756,7 +758,7 @@ impl<O, T: ?Sized> OwningRefMut<O, T> {
         }
     }
 
-    // TODO: wrap_owner
+    // UNIMPLEMENTED: wrap_owner
 
     // FIXME: Naming convention?
     /// A getter for the underlying owner.
diff --git a/src/librustc_data_structures/owning_ref/tests.rs b/src/librustc_data_structures/owning_ref/tests.rs
index d368219cab3..5bff5e035b5 100644
--- a/src/librustc_data_structures/owning_ref/tests.rs
+++ b/src/librustc_data_structures/owning_ref/tests.rs
@@ -274,7 +274,9 @@ mod owning_handle {
         use std::cell::RefCell;
         let cell = Rc::new(RefCell::new(2));
         let cell_ref = RcRef::new(cell);
-        let mut handle = OwningHandle::new_with_fn(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
+        let mut handle = OwningHandle::new_with_fn(cell_ref, |x| {
+            unsafe { x.as_ref() }.unwrap().borrow_mut()
+        });
         assert_eq!(*handle, 2);
         *handle = 3;
         assert_eq!(*handle, 3);
@@ -319,8 +321,12 @@ mod owning_handle {
         let result = {
             let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString"))));
             let curr = RcRef::new(complex);
-            let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
-            let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap());
+            let curr = OwningHandle::new_with_fn(curr, |x| {
+                unsafe { x.as_ref() }.unwrap().borrow_mut()
+            });
+            let mut curr = OwningHandle::new_with_fn(curr, |x| {
+                unsafe { x.as_ref() }.unwrap().try_write().unwrap()
+            });
             assert_eq!(*curr, "someString");
             *curr = "someOtherString";
             curr
@@ -353,8 +359,12 @@ mod owning_handle {
         let result = {
             let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString"))));
             let curr = RcRef::new(complex);
-            let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
-            let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap());
+            let curr = OwningHandle::new_with_fn(curr, |x| {
+                unsafe { x.as_ref() }.unwrap().borrow_mut()
+            });
+            let mut curr = OwningHandle::new_with_fn(curr, |x| {
+                unsafe { x.as_ref() }.unwrap().try_write().unwrap()
+            });
             assert_eq!(*curr, "someString");
             *curr = "someOtherString";
             curr
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 3f758c2521b..3b6a6a824c8 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -223,7 +223,8 @@ impl CodeSuggestion {
                         }
                     }
                     if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
-                        buf.push_str(&cur_line[..cur_lo.col.to_usize()]);
+                        let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize());
+                        buf.push_str(&cur_line[..end]);
                     }
                 }
                 buf.push_str(&part.snippet);
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 8948d1c4b36..4e970aee42c 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -121,7 +121,7 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
                             self_arg = None;
                         }
 
-                        ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&*arg.pat), self_arg)
+                        ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&arg), self_arg)
                     });
 
             let arguments = implicit_argument.into_iter().chain(explicit_arguments);
@@ -511,7 +511,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
 ///////////////////////////////////////////////////////////////////////////
 /// the main entry point for building MIR for a function
 
-struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Pat>, Option<ImplicitSelfKind>);
+struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Arg>, Option<ImplicitSelfKind>);
 
 fn construct_fn<'a, 'tcx, A>(
     hir: Cx<'a, 'tcx>,
@@ -782,13 +782,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                      -> BlockAnd<()>
     {
         // Allocate locals for the function arguments
-        for &ArgInfo(ty, _, pattern, _) in arguments.iter() {
+        for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
             // If this is a simple binding pattern, give the local a name for
             // debuginfo and so that error reporting knows that this is a user
             // variable. For any other pattern the pattern introduces new
             // variables which will be named instead.
-            let (name, span) = if let Some(pat) = pattern {
-                (pat.simple_ident().map(|ident| ident.name), pat.span)
+            let (name, span) = if let Some(arg) = arg_opt {
+                (arg.pat.simple_ident().map(|ident| ident.name), arg.pat.span)
             } else {
                 (None, self.fn_span)
             };
@@ -813,18 +813,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // Function arguments always get the first Local indices after the return place
             let local = Local::new(index + 1);
             let place = Place::from(local);
-            let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
+            let &ArgInfo(ty, opt_ty_info, arg_opt, ref self_binding) = arg_info;
 
             // Make sure we drop (parts of) the argument even when not matched on.
             self.schedule_drop(
-                pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
+                arg_opt.as_ref().map_or(ast_body.span, |arg| arg.pat.span),
                 argument_scope, local, ty, DropKind::Value,
             );
 
-            if let Some(pattern) = pattern {
-                let pattern = self.hir.pattern_from_hir(pattern);
+            if let Some(arg) = arg_opt {
+                let pattern = self.hir.pattern_from_hir(&arg.pat);
+                let original_source_scope = self.source_scope;
                 let span = pattern.span;
-
+                self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
                 match *pattern.kind {
                     // Don't introduce extra copies for simple bindings
                     PatternKind::Binding {
@@ -835,6 +836,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         ..
                     } => {
                         self.local_decls[local].mutability = mutability;
+                        self.local_decls[local].source_info.scope = self.source_scope;
                         self.local_decls[local].is_user_variable =
                             if let Some(kind) = self_binding {
                                 Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind)))
@@ -860,6 +862,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         unpack!(block = self.place_into_pattern(block, pattern, &place, false));
                     }
                 }
+                self.source_scope = original_source_scope;
             }
         }
 
@@ -872,6 +875,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.into(&Place::RETURN_PLACE, block, body)
     }
 
+    fn set_correct_source_scope_for_arg(
+        &mut self,
+        arg_hir_id: hir::HirId,
+        original_source_scope: SourceScope,
+        pattern_span: Span
+    ) {
+        let tcx = self.hir.tcx();
+        let current_root = tcx.maybe_lint_level_root_bounded(
+            arg_hir_id,
+            self.hir.root_lint_level
+        );
+        let parent_root = tcx.maybe_lint_level_root_bounded(
+            self.source_scope_local_data[original_source_scope].lint_root,
+            self.hir.root_lint_level,
+        );
+        if current_root != parent_root {
+            self.source_scope = self.new_source_scope(
+                pattern_span,
+                LintLevel::Explicit(current_root),
+                None
+            );
+        }
+    }
+
     fn get_unit_temp(&mut self) -> Place<'tcx> {
         match self.unit_temp {
             Some(ref tmp) => tmp.clone(),
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index e7f6abc410a..8fba3256ec4 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -94,6 +94,11 @@ impl<'k> StatCollector<'k> {
 }
 
 impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
+    fn visit_arg(&mut self, arg: &'v hir::Arg) {
+        self.record("Arg", Id::Node(arg.hir_id), arg);
+        hir_visit::walk_arg(self, arg)
+    }
+
     fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'v> {
         panic!("visit_nested_xxx must be manually implemented in this visitor")
     }
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index defa6fe4ce1..e4dda20c822 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -555,21 +555,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
         if let PatKind::Binding(..) = inner.node {
-            let parent_id = tcx.hir().get_parent_node(pat.hir_id);
-            let parent = tcx.hir().get(parent_id);
-            debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
-            match parent {
-                hir::Node::Item(hir::Item { node: hir::ItemKind::Fn(..), .. }) |
-                hir::Node::ForeignItem(hir::ForeignItem {
-                    node: hir::ForeignItemKind::Fn(..), ..
-                }) |
-                hir::Node::TraitItem(hir::TraitItem { node: hir::TraitItemKind::Method(..), .. }) |
-                hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => {
-                    // this pat is likely an argument
+            let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
+            let binding_parent = tcx.hir().get(binding_parent_id);
+            debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
+            match binding_parent {
+                hir::Node::Arg(hir::Arg { span, .. }) => {
                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
-                        // FIXME: turn into structured suggestion, will need a span that also
-                        // includes the the arg's type.
-                        err.help(&format!("did you mean `{}: &{}`?", snippet, expected));
+                        err.span_suggestion(
+                            *span,
+                            &format!("did you mean `{}`", snippet),
+                            format!(" &{}", expected),
+                            Applicability::MachineApplicable,
+                        );
                     }
                 }
                 hir::Node::Arm(_) |
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 14c38ae053d..3229d49841e 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -235,40 +235,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         expr: &hir::Expr,
     ) -> Option<(Span, &'static str, String)> {
-        if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node {
-            if let hir::def::Res::Local(id) = path.res {
-                let parent = self.tcx.hir().get_parent_node(id);
-                if let Some(Node::Expr(hir::Expr {
-                    hir_id,
-                    node: hir::ExprKind::Closure(_, decl, ..),
-                    ..
-                })) = self.tcx.hir().find(parent) {
-                    let parent = self.tcx.hir().get_parent_node(*hir_id);
-                    if let (Some(Node::Expr(hir::Expr {
-                        node: hir::ExprKind::MethodCall(path, span, expr),
-                        ..
-                    })), 1) = (self.tcx.hir().find(parent), decl.inputs.len()) {
-                        let self_ty = self.tables.borrow().node_type(expr[0].hir_id);
-                        let self_ty = format!("{:?}", self_ty);
-                        let name = path.ident.as_str();
-                        let is_as_ref_able = (
-                            self_ty.starts_with("&std::option::Option") ||
-                            self_ty.starts_with("&std::result::Result") ||
-                            self_ty.starts_with("std::option::Option") ||
-                            self_ty.starts_with("std::result::Result")
-                        ) && (name == "map" || name == "and_then");
-                        match (is_as_ref_able, self.sess().source_map().span_to_snippet(*span)) {
-                            (true, Ok(src)) => {
-                                return Some((*span, "consider using `as_ref` instead",
-                                             format!("as_ref().{}", src)));
-                            },
-                            _ => ()
-                        }
-                    }
-                }
-            }
+        let path = match expr.node {
+            hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => path,
+            _ => return None
+        };
+
+        let local_id = match path.res {
+            hir::def::Res::Local(id) => id,
+            _ => return None
+        };
+
+        let local_parent = self.tcx.hir().get_parent_node(local_id);
+        let arg_hir_id = match self.tcx.hir().find(local_parent) {
+            Some(Node::Arg(hir::Arg { hir_id, .. })) => hir_id,
+            _ => return None
+        };
+
+        let arg_parent = self.tcx.hir().get_parent_node(*arg_hir_id);
+        let (expr_hir_id, closure_fn_decl) = match self.tcx.hir().find(arg_parent) {
+            Some(Node::Expr(
+                hir::Expr { hir_id, node: hir::ExprKind::Closure(_, decl, ..), .. }
+            )) => (hir_id, decl),
+            _ => return None
+        };
+
+        let expr_parent = self.tcx.hir().get_parent_node(*expr_hir_id);
+        let hir = self.tcx.hir().find(expr_parent);
+        let closure_params_len = closure_fn_decl.inputs.len();
+        let (method_path, method_span, method_expr) = match (hir, closure_params_len) {
+            (Some(Node::Expr(
+                hir::Expr { node: hir::ExprKind::MethodCall(path, span, expr), .. }
+            )), 1) => (path, span, expr),
+            _ => return None
+        };
+
+        let self_ty = self.tables.borrow().node_type(method_expr[0].hir_id);
+        let self_ty = format!("{:?}", self_ty);
+        let name = method_path.ident.as_str();
+        let is_as_ref_able = (
+            self_ty.starts_with("&std::option::Option") ||
+            self_ty.starts_with("&std::result::Result") ||
+            self_ty.starts_with("std::option::Option") ||
+            self_ty.starts_with("std::result::Result")
+        ) && (name == "map" || name == "and_then");
+        match (is_as_ref_able, self.sess().source_map().span_to_snippet(*method_span)) {
+            (true, Ok(src)) => {
+                let suggestion = format!("as_ref().{}", src);
+                Some((*method_span, "consider using `as_ref` instead", suggestion))
+            },
+            _ => None
         }
-        None
     }
 
     crate fn is_hir_id_from_struct_pattern_shorthand_field(
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 66c726b2485..1b4dbfe4be6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1325,19 +1325,35 @@ fn check_union(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) {
     check_packed(tcx, span, def_id);
 }
 
-fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, span: Span) {
+fn check_opaque<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+    substs: SubstsRef<'tcx>,
+    span: Span,
+    origin: &hir::ExistTyOrigin
+) {
     if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id, substs) {
-        let mut err = struct_span_err!(
-            tcx.sess, span, E0720,
-            "opaque type expands to a recursive type",
-        );
-        err.span_label(span, "expands to a recursive type");
-        if let ty::Opaque(..) = partially_expanded_type.sty {
-            err.note("type resolves to itself");
+        if let hir::ExistTyOrigin::AsyncFn = origin {
+            struct_span_err!(
+                tcx.sess, span, E0733,
+                "recursion in an `async fn` requires boxing",
+            )
+            .span_label(span, "an `async fn` cannot invoke itself directly")
+            .note("a recursive `async fn` must be rewritten to return a boxed future.")
+            .emit();
         } else {
-            err.note(&format!("expanded type is `{}`", partially_expanded_type));
+            let mut err = struct_span_err!(
+                tcx.sess, span, E0720,
+                "opaque type expands to a recursive type",
+            );
+            err.span_label(span, "expands to a recursive type");
+            if let ty::Opaque(..) = partially_expanded_type.sty {
+                err.note("type resolves to itself");
+            } else {
+                err.note(&format!("expanded type is `{}`", partially_expanded_type));
+            }
+            err.emit();
         }
-        err.emit();
     }
 }
 
@@ -1387,11 +1403,11 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
         hir::ItemKind::Union(..) => {
             check_union(tcx, it.hir_id, it.span);
         }
-        hir::ItemKind::Existential(..) => {
+        hir::ItemKind::Existential(hir::ExistTy{origin, ..}) => {
             let def_id = tcx.hir().local_def_id(it.hir_id);
 
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
-            check_opaque(tcx, def_id, substs, it.span);
+            check_opaque(tcx, def_id, substs, it.span, &origin);
         }
         hir::ItemKind::Ty(..) => {
             let def_id = tcx.hir().local_def_id(it.hir_id);
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 4bdcb0fa291..90118a9f191 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -4763,7 +4763,53 @@ assert_eq!(1, discriminant(&Enum::Struct{a: 7, b: 11}));
 ```
 "##,
 
+E0733: r##"
+Recursion in an `async fn` requires boxing. For example, this will not compile:
+
+```edition2018,compile_fail,E0733
+#![feature(async_await)]
+async fn foo(n: usize) {
+    if n > 0 {
+        foo(n - 1).await;
+    }
+}
+```
+
+To achieve async recursion, the `async fn` needs to be desugared
+such that the `Future` is explicit in the return type:
+
+```edition2018,compile_fail,E0720
+# #![feature(async_await)]
+use std::future::Future;
+fn foo_desugered(n: usize) -> impl Future<Output = ()> {
+    async move {
+        if n > 0 {
+            foo_desugered(n - 1).await;
+        }
+    }
+}
+```
+
+Finally, the future is wrapped in a pinned box:
+
+```edition2018
+# #![feature(async_await)]
+use std::future::Future;
+use std::pin::Pin;
+fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
+    Box::pin(async move {
+        if n > 0 {
+            foo_recursive(n - 1).await;
+        }
+    })
 }
+```
+
+The `Box<...>` ensures that the result is of known size,
+and the pin is required to keep it in the same place in memory.
+"##,
+
+}  // (end of detailed error messages)
 
 register_diagnostics! {
 //  E0035, merged into E0087/E0089
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index ce0d82ec7b1..334dc74c6c8 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 
 [dependencies]
 pulldown-cmark = { version = "0.5.3", default-features = false }
-minifier = "0.0.30"
+minifier = "0.0.33"
 rayon = { version = "0.2.0", package = "rustc-rayon" }
 tempfile = "3"
 parking_lot = "0.7"
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 6270ed37859..87c6a0b4235 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1322,13 +1322,13 @@ fn write_minify_replacer<W: Write>(
                  {
                     let tokens: Tokens<'_> = simple_minify(contents)
                         .into_iter()
-                        .filter(|f| {
+                        .filter(|(f, next)| {
                             // We keep backlines.
-                            minifier::js::clean_token_except(f, &|c: &Token<'_>| {
+                            minifier::js::clean_token_except(f, next, &|c: &Token<'_>| {
                                 c.get_char() != Some(ReservedChar::Backline)
                             })
                         })
-                        .map(|f| {
+                        .map(|(f, _)| {
                             minifier::js::replace_token_with(f, &|t: &Token<'_>| {
                                 match *t {
                                     Token::Keyword(Keyword::Null) => Some(Token::Other("N")),
@@ -1363,7 +1363,7 @@ fn write_minify_replacer<W: Write>(
                             // shouldn't be aggregated.
                             |tokens, pos| {
                                 pos < 2 ||
-                                !tokens[pos - 1].is_char(ReservedChar::OpenBracket) ||
+                                !tokens[pos - 1].eq_char(ReservedChar::OpenBracket) ||
                                 tokens[pos - 2].get_other() != Some("searchIndex")
                             }
                         )
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index dc97f8c04a8..98371b9ba3d 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -396,6 +396,7 @@ impl SystemTime {
     /// This function may fail because measurements taken earlier are not
     /// guaranteed to always be before later measurements (due to anomalies such
     /// as the system clock being adjusted either forwards or backwards).
+    /// [`Instant`] can be used to measure elapsed time without this risk of failure.
     ///
     /// If successful, [`Ok`]`(`[`Duration`]`)` is returned where the duration represents
     /// the amount of time elapsed from the specified measurement to this one.
@@ -406,6 +407,7 @@ impl SystemTime {
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Instant`]: ../../std/time/struct.Instant.html
     ///
     /// # Examples
     ///
@@ -414,7 +416,7 @@ impl SystemTime {
     ///
     /// let sys_time = SystemTime::now();
     /// let difference = sys_time.duration_since(sys_time)
-    ///                          .expect("SystemTime::duration_since failed");
+    ///                          .expect("Clock may have gone backwards");
     /// println!("{:?}", difference);
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
@@ -423,7 +425,8 @@ impl SystemTime {
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
-    /// Returns the amount of time elapsed since this system time was created.
+    /// Returns the difference between the clock time when this
+    /// system time was created, and the current clock time.
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
@@ -431,12 +434,15 @@ impl SystemTime {
     /// returned where the duration represents the amount of time elapsed from
     /// this time measurement to the current time.
     ///
+    /// To measure elapsed time reliably, use [`Instant`] instead.
+    ///
     /// Returns an [`Err`] if `self` is later than the current system time, and
     /// the error contains how far from the current system time `self` is.
     ///
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Instant`]: ../../std/time/struct.Instant.html
     ///
     /// # Examples
     ///
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a7453f4f9da..58a1c4aee9a 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1796,6 +1796,7 @@ pub struct Arg {
     pub ty: P<Ty>,
     pub pat: P<Pat>,
     pub id: NodeId,
+    pub span: Span,
 }
 
 /// Alternative representation for `Arg`s describing `self` parameter of methods.
@@ -1854,6 +1855,7 @@ impl Arg {
                 node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
                 span,
             }),
+            span,
             ty,
             id: DUMMY_NODE_ID,
         };
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 528b27d6153..b30fefe5b96 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -966,6 +966,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             attrs: ThinVec::default(),
             id: ast::DUMMY_NODE_ID,
             pat: arg_pat,
+            span,
             ty,
         }
     }
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 86525406718..43b6bea69d9 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -558,10 +558,11 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_visit_arg<T: MutVisitor>(Arg { attrs, id, pat, ty }: &mut Arg, vis: &mut T) {
+pub fn noop_visit_arg<T: MutVisitor>(Arg { attrs, id, pat, span, ty }: &mut Arg, vis: &mut T) {
     vis.visit_id(id);
     visit_thin_attrs(attrs, vis);
     vis.visit_pat(pat);
+    vis.visit_span(span);
     vis.visit_ty(ty);
 }
 
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index f4fc87506f3..39cb5042fbc 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -30,7 +30,7 @@ crate fn dummy_arg(ident: Ident) -> Arg {
         span: ident.span,
         id: ast::DUMMY_NODE_ID
     };
-    Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, ty: P(ty) }
+    Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, span: ident.span, ty: P(ty) }
 }
 
 pub enum Error {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8f8ed411180..6cb965bf817 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1515,6 +1515,7 @@ impl<'a> Parser<'a> {
     where
         F: Fn(&token::Token) -> bool
     {
+        let lo = self.token.span;
         let attrs = self.parse_arg_attributes()?;
         if let Some(mut arg) = self.parse_self_arg()? {
             arg.attrs = attrs.into();
@@ -1578,11 +1579,14 @@ impl<'a> Parser<'a> {
             }
         };
 
-        Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, ty })
+        let span = lo.to(self.token.span);
+
+        Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, span, ty })
     }
 
     /// Parses an argument in a lambda header (e.g., `|arg, arg|`).
     fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
+        let lo = self.token.span;
         let attrs = self.parse_arg_attributes()?;
         let pat = self.parse_pat(Some("argument name"))?;
         let t = if self.eat(&token::Colon) {
@@ -1594,10 +1598,12 @@ impl<'a> Parser<'a> {
                 span: self.prev_span,
             })
         };
+        let span = lo.to(self.token.span);
         Ok(Arg {
             attrs: attrs.into(),
             ty: t,
             pat,
+            span,
             id: ast::DUMMY_NODE_ID
         })
     }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ff6440fb9dc..50be8c68f7f 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -66,6 +66,7 @@ pub trait Visitor<'ast>: Sized {
     fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) }
     fn visit_block(&mut self, b: &'ast Block) { walk_block(self, b) }
     fn visit_stmt(&mut self, s: &'ast Stmt) { walk_stmt(self, s) }
+    fn visit_arg(&mut self, arg: &'ast Arg) { walk_arg(self, arg) }
     fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) }
     fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) }
     fn visit_anon_const(&mut self, c: &'ast AnonConst) { walk_anon_const(self, c) }
@@ -547,12 +548,10 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
 }
 
 pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
-    for argument in &function_declaration.inputs {
-        walk_list!(visitor, visit_attribute, argument.attrs.iter());
-        visitor.visit_pat(&argument.pat);
-        visitor.visit_ty(&argument.ty);
+    for arg in &function_declaration.inputs {
+        visitor.visit_arg(arg);
     }
-    visitor.visit_fn_ret_ty(&function_declaration.output)
+    visitor.visit_fn_ret_ty(&function_declaration.output);
 }
 
 pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl, _span: Span)
@@ -822,6 +821,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
     visitor.visit_expr_post(expression)
 }
 
+pub fn walk_arg<'a, V: Visitor<'a>>(visitor: &mut V, arg: &'a Arg) {
+    walk_list!(visitor, visit_attribute, arg.attrs.iter());
+    visitor.visit_pat(&arg.pat);
+    visitor.visit_ty(&arg.ty);
+}
+
 pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
     walk_list!(visitor, visit_pat, &arm.pats);
     if let Some(ref e) = &arm.guard {
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
index 69914b6a791..64f6eccd547 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
@@ -1,11 +1,11 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0733]: recursion in an `async fn` requires boxing
   --> $DIR/recursive-async-impl-trait-type.rs:7:40
    |
 LL | async fn recursive_async_function() -> () {
-   |                                        ^^ expands to a recursive type
+   |                                        ^^ an `async fn` cannot invoke itself directly
    |
-   = note: expanded type is `std::future::GenFuture<[static generator@$DIR/recursive-async-impl-trait-type.rs:7:43: 9:2 {impl std::future::Future, ()}]>`
+   = note: a recursive `async fn` must be rewritten to return a boxed future.
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0720`.
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs b/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs
index 4e85bcc4ba6..141f363694a 100644
--- a/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs
+++ b/src/test/ui/error-codes/e0119/auxiliary/issue-23563-a.rs
@@ -9,7 +9,7 @@ pub trait LolInto<T>: Sized {
 }
 
 pub trait LolFrom<T> {
-    fn from(T) -> Self;
+    fn from(_: T) -> Self;
 }
 
 impl<'a, T: ?Sized, U> LolInto<U> for &'a T where T: LolTo<U> {
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs
index 78609a6e24b..2957f931110 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/lint-unused-mut-variables.rs
@@ -1,12 +1,70 @@
+// edition:2018
+
 // Exercise the unused_mut attribute in some positive and negative cases
 
-#![allow(unused_assignments)]
-#![allow(unused_variables)]
-#![allow(dead_code)]
 #![deny(unused_mut)]
+#![feature(async_await, async_closure, param_attrs)]
+
+async fn baz_async(
+    mut a: i32,
+    //~^ ERROR: variable does not need to be mutable
+    #[allow(unused_mut)] mut b: i32,
+) {}
+fn baz(
+    mut a: i32,
+    //~^ ERROR: variable does not need to be mutable
+    #[allow(unused_mut)] mut b: i32,
+    #[allow(unused_mut)] (mut c, d): (i32, i32)
+) {}
+
+struct RefStruct {}
+impl RefStruct {
+    async fn baz_async(
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+    ) {}
+    fn baz(
+        &self,
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+        #[allow(unused_mut)] (mut c, d): (i32, i32)
+    ) {}
+}
 
+trait RefTrait {
+    fn baz(
+        &self,
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+        #[allow(unused_mut)] (mut c, d): (i32, i32)
+    ) {}
+}
+impl RefTrait for () {
+    fn baz(
+        &self,
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+        #[allow(unused_mut)] (mut c, d): (i32, i32)
+    ) {}
+}
 
 fn main() {
+    let _ = async move |
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+    | {};
+    let _ = |
+        mut a: i32,
+        //~^ ERROR: variable does not need to be mutable
+        #[allow(unused_mut)] mut b: i32,
+        #[allow(unused_mut)] (mut c, d): (i32, i32)
+    | {};
+
     // negative cases
     let mut a = 3; //~ ERROR: variable does not need to be mutable
 
diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/lint-unused-mut-variables.stderr
index 1a175c9683e..92c2b68652d 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.stderr
+++ b/src/test/ui/lint/lint-unused-mut-variables.stderr
@@ -1,19 +1,83 @@
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:46:14
+  --> $DIR/lint-unused-mut-variables.rs:9:5
    |
-LL |     let x = |mut y: isize| 10;
-   |              ----^
-   |              |
-   |              help: remove this `mut`
+LL |     mut a: i32,
+   |     ----^
+   |     |
+   |     help: remove this `mut`
    |
 note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:6:9
+  --> $DIR/lint-unused-mut-variables.rs:5:9
    |
 LL | #![deny(unused_mut)]
    |         ^^^^^^^^^^
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:11:9
+  --> $DIR/lint-unused-mut-variables.rs:14:5
+   |
+LL |     mut a: i32,
+   |     ----^
+   |     |
+   |     help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:23:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:29:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:39:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:48:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:57:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:62:9
+   |
+LL |         mut a: i32,
+   |         ----^
+   |         |
+   |         help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:104:14
+   |
+LL |     let x = |mut y: isize| 10;
+   |              ----^
+   |              |
+   |              help: remove this `mut`
+
+error: variable does not need to be mutable
+  --> $DIR/lint-unused-mut-variables.rs:69:9
    |
 LL |     let mut a = 3;
    |         ----^
@@ -21,7 +85,7 @@ LL |     let mut a = 3;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:13:9
+  --> $DIR/lint-unused-mut-variables.rs:71:9
    |
 LL |     let mut a = 2;
    |         ----^
@@ -29,7 +93,7 @@ LL |     let mut a = 2;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:15:9
+  --> $DIR/lint-unused-mut-variables.rs:73:9
    |
 LL |     let mut b = 3;
    |         ----^
@@ -37,7 +101,7 @@ LL |     let mut b = 3;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:17:9
+  --> $DIR/lint-unused-mut-variables.rs:75:9
    |
 LL |     let mut a = vec![3];
    |         ----^
@@ -45,7 +109,7 @@ LL |     let mut a = vec![3];
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:19:10
+  --> $DIR/lint-unused-mut-variables.rs:77:10
    |
 LL |     let (mut a, b) = (1, 2);
    |          ----^
@@ -53,7 +117,7 @@ LL |     let (mut a, b) = (1, 2);
    |          help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:21:9
+  --> $DIR/lint-unused-mut-variables.rs:79:9
    |
 LL |     let mut a;
    |         ----^
@@ -61,7 +125,7 @@ LL |     let mut a;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:25:9
+  --> $DIR/lint-unused-mut-variables.rs:83:9
    |
 LL |     let mut b;
    |         ----^
@@ -69,7 +133,7 @@ LL |     let mut b;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:34:9
+  --> $DIR/lint-unused-mut-variables.rs:92:9
    |
 LL |         mut x => {}
    |         ----^
@@ -77,7 +141,7 @@ LL |         mut x => {}
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:38:8
+  --> $DIR/lint-unused-mut-variables.rs:96:8
    |
 LL |       (mut x, 1) |
    |        ----^
@@ -85,7 +149,7 @@ LL |       (mut x, 1) |
    |        help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:51:9
+  --> $DIR/lint-unused-mut-variables.rs:109:9
    |
 LL |     let mut a = &mut 5;
    |         ----^
@@ -93,7 +157,7 @@ LL |     let mut a = &mut 5;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:56:9
+  --> $DIR/lint-unused-mut-variables.rs:114:9
    |
 LL |     let mut b = (&mut a,);
    |         ----^
@@ -101,7 +165,7 @@ LL |     let mut b = (&mut a,);
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:59:9
+  --> $DIR/lint-unused-mut-variables.rs:117:9
    |
 LL |     let mut x = &mut 1;
    |         ----^
@@ -109,7 +173,7 @@ LL |     let mut x = &mut 1;
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:71:9
+  --> $DIR/lint-unused-mut-variables.rs:129:9
    |
 LL |     let mut v : &mut Vec<()> = &mut vec![];
    |         ----^
@@ -117,7 +181,7 @@ LL |     let mut v : &mut Vec<()> = &mut vec![];
    |         help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:48:13
+  --> $DIR/lint-unused-mut-variables.rs:106:13
    |
 LL |     fn what(mut foo: isize) {}
    |             ----^^^
@@ -125,7 +189,7 @@ LL |     fn what(mut foo: isize) {}
    |             help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:66:20
+  --> $DIR/lint-unused-mut-variables.rs:124:20
    |
 LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
    |                    ----^^^
@@ -133,7 +197,7 @@ LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
    |                    help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:138:9
+  --> $DIR/lint-unused-mut-variables.rs:196:9
    |
 LL |     let mut b = vec![2];
    |         ----^
@@ -141,10 +205,10 @@ LL |     let mut b = vec![2];
    |         help: remove this `mut`
    |
 note: lint level defined here
-  --> $DIR/lint-unused-mut-variables.rs:134:8
+  --> $DIR/lint-unused-mut-variables.rs:192:8
    |
 LL | #[deny(unused_mut)]
    |        ^^^^^^^^^^
 
-error: aborting due to 17 previous errors
+error: aborting due to 25 previous errors
 
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
new file mode 100644
index 00000000000..a1660d23511
--- /dev/null
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -0,0 +1,64 @@
+// compile-flags: --cfg something
+// edition:2018
+
+#![feature(async_await, async_closure, param_attrs)]
+#![deny(unused_variables)]
+
+async fn foo_async(
+    a: i32,
+    //~^ ERROR unused variable: `a`
+    #[allow(unused_variables)] b: i32,
+) {}
+fn foo(
+    #[allow(unused_variables)] a: i32,
+    b: i32,
+    //~^ ERROR unused variable: `b`
+) {}
+
+struct RefStruct {}
+impl RefStruct {
+    async fn bar_async(
+        &self,
+        a: i32,
+        //~^ ERROR unused variable: `a`
+        #[allow(unused_variables)] b: i32,
+    ) {}
+    fn bar(
+        &self,
+        #[allow(unused_variables)] a: i32,
+        b: i32,
+        //~^ ERROR unused variable: `b`
+    ) {}
+}
+trait RefTrait {
+    fn bar(
+        &self,
+        #[allow(unused_variables)] a: i32,
+        b: i32,
+        //~^ ERROR unused variable: `b`
+    ) {}
+}
+impl RefTrait for RefStruct {
+    fn bar(
+        &self,
+        #[allow(unused_variables)] a: i32,
+        b: i32,
+        //~^ ERROR unused variable: `b`
+    ) {}
+}
+
+fn main() {
+    let _: fn(_, _) = foo;
+    let a = async move |
+        a: i32,
+        //~^ ERROR unused variable: `a`
+        #[allow(unused_variables)] b: i32,
+    | {};
+    let b = |
+        #[allow(unused_variables)] a: i32,
+        b: i32,
+        //~^ ERROR unused variable: `b`
+    | {};
+    let _ = a(1, 2);
+    let _ = b(1, 2);
+}
diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/lint-unused-variables.stderr
new file mode 100644
index 00000000000..7ed5669e33c
--- /dev/null
+++ b/src/test/ui/lint/lint-unused-variables.stderr
@@ -0,0 +1,56 @@
+error: unused variable: `a`
+  --> $DIR/lint-unused-variables.rs:8:5
+   |
+LL |     a: i32,
+   |     ^ help: consider prefixing with an underscore: `_a`
+   |
+note: lint level defined here
+  --> $DIR/lint-unused-variables.rs:5:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unused variable: `b`
+  --> $DIR/lint-unused-variables.rs:14:5
+   |
+LL |     b: i32,
+   |     ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/lint-unused-variables.rs:53:9
+   |
+LL |         a: i32,
+   |         ^ help: consider prefixing with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/lint-unused-variables.rs:59:9
+   |
+LL |         b: i32,
+   |         ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+  --> $DIR/lint-unused-variables.rs:37:9
+   |
+LL |         b: i32,
+   |         ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `a`
+  --> $DIR/lint-unused-variables.rs:22:9
+   |
+LL |         a: i32,
+   |         ^ help: consider prefixing with an underscore: `_a`
+
+error: unused variable: `b`
+  --> $DIR/lint-unused-variables.rs:29:9
+   |
+LL |         b: i32,
+   |         ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+  --> $DIR/lint-unused-variables.rs:45:9
+   |
+LL |         b: i32,
+   |         ^ help: consider prefixing with an underscore: `_b`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr
index a9347926bda..79a0807c337 100644
--- a/src/test/ui/mismatched_types/issue-38371.stderr
+++ b/src/test/ui/mismatched_types/issue-38371.stderr
@@ -2,11 +2,13 @@ error[E0308]: mismatched types
   --> $DIR/issue-38371.rs:4:8
    |
 LL | fn foo(&foo: Foo) {
-   |        ^^^^ expected struct `Foo`, found reference
+   |        ^^^^------
+   |        |
+   |        expected struct `Foo`, found reference
+   |        help: did you mean `foo`: `&Foo`
    |
    = note: expected type `Foo`
               found type `&_`
-   = help: did you mean `foo: &Foo`?
 
 error[E0308]: mismatched types
   --> $DIR/issue-38371.rs:18:9
diff --git a/src/test/ui/parser/issue-62973.rs b/src/test/ui/parser/issue-62973.rs
new file mode 100644
index 00000000000..18bc51e7ba7
--- /dev/null
+++ b/src/test/ui/parser/issue-62973.rs
@@ -0,0 +1,8 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 6 previous errors
+
+fn main() {}
+
+fn p() { match s { v, E { [) {) }
+
+
diff --git a/src/test/ui/parser/issue-62973.stderr b/src/test/ui/parser/issue-62973.stderr
new file mode 100644
index 00000000000..141076bf6b6
--- /dev/null
+++ b/src/test/ui/parser/issue-62973.stderr
@@ -0,0 +1,61 @@
+error: this file contains an un-closed delimiter
+  --> $DIR/issue-62973.rs:8:2
+   |
+LL | fn p() { match s { v, E { [) {) }
+   |        -         - un-closed delimiter
+   |        |
+   |        un-closed delimiter
+LL | 
+LL | 
+   |  ^
+
+error: expected one of `,` or `}`, found `{`
+  --> $DIR/issue-62973.rs:6:25
+   |
+LL | fn p() { match s { v, E { [) {) }
+   |                -        ^ expected one of `,` or `}` here
+   |                |
+   |                while parsing this struct
+
+error: struct literals are not allowed here
+  --> $DIR/issue-62973.rs:6:16
+   |
+LL |   fn p() { match s { v, E { [) {) }
+   |  ________________^
+LL | |
+LL | |
+   | |_^
+help: surround the struct literal with parentheses
+   |
+LL | fn p() { match (s { v, E { [) {) }
+LL | 
+LL | )
+   |
+
+error: expected one of `.`, `?`, `{`, or an operator, found `}`
+  --> $DIR/issue-62973.rs:8:1
+   |
+LL | fn p() { match s { v, E { [) {) }
+   |          ----- while parsing this match expression
+LL | 
+LL | 
+   | ^ expected one of `.`, `?`, `{`, or an operator here
+
+error: incorrect close delimiter: `)`
+  --> $DIR/issue-62973.rs:6:28
+   |
+LL | fn p() { match s { v, E { [) {) }
+   |                           -^ incorrect close delimiter
+   |                           |
+   |                           un-closed delimiter
+
+error: incorrect close delimiter: `)`
+  --> $DIR/issue-62973.rs:6:31
+   |
+LL | fn p() { match s { v, E { [) {) }
+   |                              -^ incorrect close delimiter
+   |                              |
+   |                              un-closed delimiter
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
index e796e37bbaa..5eeda66173d 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
@@ -1,189 +1,66 @@
+// check-pass
 // compile-flags: --cfg something
-// build-pass (FIXME(62277): could be check-pass?)
 
+#![deny(unused_mut)]
 #![feature(param_attrs)]
 
 extern "C" {
     fn ffi(
-        #[allow(C)] a: i32,
+        #[allow(unused_mut)] a: i32,
         #[cfg(something)] b: i32,
         #[cfg_attr(something, cfg(nothing))] c: i32,
-        #[deny(C)] d: i32,
-        #[forbid(C)] #[warn(C)] ...
+        #[deny(unused_mut)] d: i32,
+        #[forbid(unused_mut)] #[warn(unused_mut)] ...
     );
 }
 
 type FnType = fn(
-    #[allow(C)] a: i32,
+    #[allow(unused_mut)] a: i32,
     #[cfg(something)] b: i32,
     #[cfg_attr(something, cfg(nothing))] c: i32,
-    #[deny(C)] d: i32,
-    #[forbid(C)] #[warn(C)] e: i32
+    #[deny(unused_mut)] d: i32,
+    #[forbid(unused_mut)] #[warn(unused_mut)] e: i32
 );
 
 pub fn foo(
-    #[allow(C)] a: i32,
+    #[allow(unused_mut)] a: i32,
     #[cfg(something)] b: i32,
     #[cfg_attr(something, cfg(nothing))] c: i32,
-    #[deny(C)] d: i32,
-    #[forbid(C)] #[warn(C)] e: i32
+    #[deny(unused_mut)] d: i32,
+    #[forbid(unused_mut)] #[warn(unused_mut)] _e: i32
 ) {}
 
-// self, &self and &mut self
+// self
 
 struct SelfStruct {}
 impl SelfStruct {
     fn foo(
-        #[allow(C)] self,
+        #[allow(unused_mut)] self,
         #[cfg(something)] a: i32,
         #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
+        #[deny(unused_mut)] b: i32,
     ) {}
 }
 
 struct RefStruct {}
 impl RefStruct {
     fn foo(
-        #[allow(C)] &self,
+        #[allow(unused_mut)] &self,
         #[cfg(something)] a: i32,
         #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
+        #[deny(unused_mut)] b: i32,
     ) {}
 }
 trait RefTrait {
     fn foo(
-        #[forbid(C)] &self,
-        #[warn(C)] a: i32
+        #[forbid(unused_mut)] &self,
+        #[warn(unused_mut)] a: i32
     ) {}
 }
 impl RefTrait for RefStruct {
     fn foo(
-        #[forbid(C)] &self,
-        #[warn(C)] a: i32
-    ) {}
-}
-
-struct MutStruct {}
-impl MutStruct {
-    fn foo(
-        #[allow(C)] &mut self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-trait MutTrait {
-    fn foo(
-        #[forbid(C)] &mut self,
-        #[warn(C)] a: i32
-    ) {}
-}
-impl MutTrait for MutStruct {
-    fn foo(
-        #[forbid(C)] &mut self,
-        #[warn(C)] a: i32
-    ) {}
-}
-
-// self: Self, self: &Self and self: &mut Self
-
-struct NamedSelfSelfStruct {}
-impl NamedSelfSelfStruct {
-    fn foo(
-        #[allow(C)] self: Self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-
-struct NamedSelfRefStruct {}
-impl NamedSelfRefStruct {
-    fn foo(
-        #[allow(C)] self: &Self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-trait NamedSelfRefTrait {
-    fn foo(
-        #[forbid(C)] self: &Self,
-        #[warn(C)] a: i32
-    ) {}
-}
-impl NamedSelfRefTrait for NamedSelfRefStruct {
-    fn foo(
-        #[forbid(C)] self: &Self,
-        #[warn(C)] a: i32
-    ) {}
-}
-
-struct NamedSelfMutStruct {}
-impl NamedSelfMutStruct {
-    fn foo(
-        #[allow(C)] self: &mut Self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-trait NamedSelfMutTrait {
-    fn foo(
-        #[forbid(C)] self: &mut Self,
-        #[warn(C)] a: i32
-    ) {}
-}
-impl NamedSelfMutTrait for NamedSelfMutStruct {
-    fn foo(
-        #[forbid(C)] self: &mut Self,
-        #[warn(C)] a: i32
-    ) {}
-}
-
-// &'a self and &'a mut self
-
-struct NamedLifetimeRefStruct {}
-impl NamedLifetimeRefStruct {
-    fn foo<'a>(
-        #[allow(C)] self: &'a Self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-trait NamedLifetimeRefTrait {
-    fn foo<'a>(
-        #[forbid(C)] &'a self,
-        #[warn(C)] a: i32
-    ) {}
-}
-impl NamedLifetimeRefTrait for NamedLifetimeRefStruct {
-    fn foo<'a>(
-        #[forbid(C)] &'a self,
-        #[warn(C)] a: i32
-    ) {}
-}
-
-struct NamedLifetimeMutStruct {}
-impl NamedLifetimeMutStruct {
-    fn foo<'a>(
-        #[allow(C)] self: &'a mut Self,
-        #[cfg(something)] a: i32,
-        #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
-    ) {}
-}
-trait NamedLifetimeMutTrait {
-    fn foo<'a>(
-        #[forbid(C)] &'a mut self,
-        #[warn(C)] a: i32
-    ) {}
-}
-impl NamedLifetimeMutTrait for NamedLifetimeMutStruct {
-    fn foo<'a>(
-        #[forbid(C)] &'a mut self,
-        #[warn(C)] a: i32
+        #[forbid(unused_mut)] &self,
+        #[warn(unused_mut)] a: i32
     ) {}
 }
 
@@ -192,22 +69,22 @@ impl NamedLifetimeMutTrait for NamedLifetimeMutStruct {
 struct BoxSelfStruct {}
 impl BoxSelfStruct {
     fn foo(
-        #[allow(C)] self: Box<Self>,
+        #[allow(unused_mut)] self: Box<Self>,
         #[cfg(something)] a: i32,
         #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] b: i32,
+        #[deny(unused_mut)] b: i32,
     ) {}
 }
 trait BoxSelfTrait {
     fn foo(
-        #[forbid(C)] self: Box<Self>,
-        #[warn(C)] a: i32
+        #[forbid(unused_mut)] self: Box<Self>,
+        #[warn(unused_mut)] a: i32
     ) {}
 }
 impl BoxSelfTrait for BoxSelfStruct {
     fn foo(
-        #[forbid(C)] self: Box<Self>,
-        #[warn(C)] a: i32
+        #[forbid(unused_mut)] self: Box<Self>,
+        #[warn(unused_mut)] a: i32
     ) {}
 }
 
@@ -216,10 +93,10 @@ fn main() {
     let _: fn(_, _, _, _) = foo;
     let _: FnType = |_, _, _, _| {};
     let c = |
-        #[allow(C)] a: u32,
+        #[allow(unused_mut)] a: u32,
         #[cfg(something)] b: i32,
         #[cfg_attr(something, cfg(nothing))]
-        #[deny(C)] c: i32,
+        #[deny(unused_mut)] c: i32,
     | {};
     let _ = c(1, 2);
 }
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index 977b5d9ce34..069332ffa25 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -1,6 +1,7 @@
 // compile-flags: --cfg something
+// edition:2018
 
-#![feature(param_attrs)]
+#![feature(async_await, async_closure, param_attrs)]
 #![deny(unused_variables)]
 
 extern "C" {
@@ -19,24 +20,35 @@ type FnType = fn(
     #[cfg_attr(something, cfg(nothing))] d: i32,
 );
 
+async fn foo_async(
+    #[cfg(something)] a: i32,
+    //~^ ERROR unused variable: `a`
+    #[cfg(nothing)] b: i32,
+) {}
 fn foo(
     #[cfg(nothing)] a: i32,
     #[cfg(something)] b: i32,
-    //~^ ERROR unused variable: `b` [unused_variables]
+    //~^ ERROR unused variable: `b`
     #[cfg_attr(nothing, cfg(nothing))] c: i32,
-    //~^ ERROR unused variable: `c` [unused_variables]
+    //~^ ERROR unused variable: `c`
     #[cfg_attr(something, cfg(nothing))] d: i32,
 ) {}
 
 struct RefStruct {}
 impl RefStruct {
+    async fn bar_async(
+        &self,
+        #[cfg(something)] a: i32,
+        //~^ ERROR unused variable: `a`
+        #[cfg(nothing)] b: i32,
+    ) {}
     fn bar(
         &self,
         #[cfg(nothing)] a: i32,
         #[cfg(something)] b: i32,
-        //~^ ERROR unused variable: `b` [unused_variables]
+        //~^ ERROR unused variable: `b`
         #[cfg_attr(nothing, cfg(nothing))] c: i32,
-        //~^ ERROR unused variable: `c` [unused_variables]
+        //~^ ERROR unused variable: `c`
         #[cfg_attr(something, cfg(nothing))] d: i32,
     ) {}
 }
@@ -45,9 +57,9 @@ trait RefTrait {
         &self,
         #[cfg(nothing)] a: i32,
         #[cfg(something)] b: i32,
-        //~^ ERROR unused variable: `b` [unused_variables]
+        //~^ ERROR unused variable: `b`
         #[cfg_attr(nothing, cfg(nothing))] c: i32,
-        //~^ ERROR unused variable: `c` [unused_variables]
+        //~^ ERROR unused variable: `c`
         #[cfg_attr(something, cfg(nothing))] d: i32,
     ) {}
 }
@@ -56,9 +68,9 @@ impl RefTrait for RefStruct {
         &self,
         #[cfg(nothing)] a: i32,
         #[cfg(something)] b: i32,
-        //~^ ERROR unused variable: `b` [unused_variables]
+        //~^ ERROR unused variable: `b`
         #[cfg_attr(nothing, cfg(nothing))] c: i32,
-        //~^ ERROR unused variable: `c` [unused_variables]
+        //~^ ERROR unused variable: `c`
         #[cfg_attr(something, cfg(nothing))] d: i32,
     ) {}
 }
@@ -67,13 +79,19 @@ fn main() {
     let _: unsafe extern "C" fn(_, ...) = ffi;
     let _: fn(_, _) = foo;
     let _: FnType = |_, _| {};
+    let a = async move |
+        #[cfg(something)] a: i32,
+        //~^ ERROR unused variable: `a`
+        #[cfg(nothing)] b: i32,
+    | {};
     let c = |
         #[cfg(nothing)] a: i32,
         #[cfg(something)] b: i32,
-        //~^ ERROR unused variable: `b` [unused_variables]
+        //~^ ERROR unused variable: `b`
         #[cfg_attr(nothing, cfg(nothing))] c: i32,
-        //~^ ERROR unused variable: `c` [unused_variables]
+        //~^ ERROR unused variable: `c`
         #[cfg_attr(something, cfg(nothing))] d: i32,
     | {};
+    let _ = a(1);
     let _ = c(1, 2);
 }
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
index c97190324e5..3232e2a0411 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -1,68 +1,86 @@
-error: unused variable: `b`
+error: unused variable: `a`
   --> $DIR/param-attrs-cfg.rs:24:23
    |
-LL |     #[cfg(something)] b: i32,
-   |                       ^ help: consider prefixing with an underscore: `_b`
+LL |     #[cfg(something)] a: i32,
+   |                       ^ help: consider prefixing with an underscore: `_a`
    |
 note: lint level defined here
-  --> $DIR/param-attrs-cfg.rs:4:9
+  --> $DIR/param-attrs-cfg.rs:5:9
    |
 LL | #![deny(unused_variables)]
    |         ^^^^^^^^^^^^^^^^
 
+error: unused variable: `b`
+  --> $DIR/param-attrs-cfg.rs:30:23
+   |
+LL |     #[cfg(something)] b: i32,
+   |                       ^ help: consider prefixing with an underscore: `_b`
+
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:26:40
+  --> $DIR/param-attrs-cfg.rs:32:40
    |
 LL |     #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                        ^ help: consider prefixing with an underscore: `_c`
 
+error: unused variable: `a`
+  --> $DIR/param-attrs-cfg.rs:83:27
+   |
+LL |         #[cfg(something)] a: i32,
+   |                           ^ help: consider prefixing with an underscore: `_a`
+
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:72:27
+  --> $DIR/param-attrs-cfg.rs:89:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: consider prefixing with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:74:44
+  --> $DIR/param-attrs-cfg.rs:91:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: consider prefixing with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:47:27
+  --> $DIR/param-attrs-cfg.rs:59:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: consider prefixing with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:49:44
+  --> $DIR/param-attrs-cfg.rs:61:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: consider prefixing with an underscore: `_c`
 
+error: unused variable: `a`
+  --> $DIR/param-attrs-cfg.rs:41:27
+   |
+LL |         #[cfg(something)] a: i32,
+   |                           ^ help: consider prefixing with an underscore: `_a`
+
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:36:27
+  --> $DIR/param-attrs-cfg.rs:48:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: consider prefixing with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:38:44
+  --> $DIR/param-attrs-cfg.rs:50:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: consider prefixing with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:58:27
+  --> $DIR/param-attrs-cfg.rs:70:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: consider prefixing with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:60:44
+  --> $DIR/param-attrs-cfg.rs:72:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: consider prefixing with an underscore: `_c`
 
-error: aborting due to 10 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
index c5a6514efb0..a7f4855915b 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
@@ -1,12 +1,14 @@
 // gate-test-param_attrs
 
+#![deny(unused_variables)]
+
 fn foo(
     /// Foo
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
     //~| ERROR attributes on function parameters are unstable
     //~| NOTE https://github.com/rust-lang/rust/issues/60406
-    #[allow(C)] a: u8
+    #[allow(unused_variables)] a: u8
     //~^ ERROR attributes on function parameters are unstable
     //~| NOTE https://github.com/rust-lang/rust/issues/60406
 ) {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
index 704c41f0fa6..0bb9d05dca0 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
@@ -1,11 +1,11 @@
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-feature-gate.rs:4:5
+  --> $DIR/param-attrs-feature-gate.rs:6:5
    |
 LL |     /// Foo
    |     ^^^^^^^ doc comments are not allowed here
 
 error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:4:5
+  --> $DIR/param-attrs-feature-gate.rs:6:5
    |
 LL |     /// Foo
    |     ^^^^^^^
@@ -14,10 +14,10 @@ LL |     /// Foo
    = help: add `#![feature(param_attrs)]` to the crate attributes to enable
 
 error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:9:5
+  --> $DIR/param-attrs-feature-gate.rs:11:5
    |
-LL |     #[allow(C)] a: u8
-   |     ^^^^^^^^^^^
+LL |     #[allow(unused_variables)] a: u8
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/60406
    = help: add `#![feature(param_attrs)]` to the crate attributes to enable
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 3d40bdced63..eca8001a9d2 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -43,31 +43,19 @@ pub mod unstable_book;
 
 fn filter_dirs(path: &Path) -> bool {
     let skip = [
-        "src/llvm",
-        "src/llvm-project",
         "src/llvm-emscripten",
-        "src/libbacktrace",
-        "src/librustc_data_structures/owning_ref",
-        "src/vendor",
+        "src/llvm-project",
+        "src/stdarch",
         "src/tools/cargo",
-        "src/tools/clang",
-        "src/tools/rls",
         "src/tools/clippy",
+        "src/tools/miri",
+        "src/tools/rls",
         "src/tools/rust-installer",
         "src/tools/rustfmt",
-        "src/tools/miri",
-        "src/tools/lld",
-        "src/tools/lldb",
-        "src/target",
-        "src/stdarch",
-        "src/rust-sgx",
-        "target",
-        "vendor",
     ];
     skip.iter().any(|p| path.ends_with(p))
 }
 
-
 fn walk_many(
     paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&DirEntry, &str)
 ) {
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 4a159d926b7..6a0d530e236 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -152,6 +152,8 @@ pub fn check(path: &Path, bad: &mut bool) {
         let mut skip_file_length = contains_ignore_directive(can_contain, &contents, "filelength");
         let mut skip_end_whitespace =
             contains_ignore_directive(can_contain, &contents, "end-whitespace");
+        let mut skip_trailing_newlines =
+            contains_ignore_directive(can_contain, &contents, "trailing-newlines");
         let mut skip_copyright = contains_ignore_directive(can_contain, &contents, "copyright");
         let mut leading_new_lines = false;
         let mut trailing_new_lines = 0;
@@ -214,10 +216,17 @@ pub fn check(path: &Path, bad: &mut bool) {
         if leading_new_lines {
             tidy_error!(bad, "{}: leading newline", file.display());
         }
+        let mut err = |msg: &str| {
+            tidy_error!(bad, "{}: {}", file.display(), msg);
+        };
         match trailing_new_lines {
-            0 => tidy_error!(bad, "{}: missing trailing newline", file.display()),
+            0 => suppressible_tidy_err!(err, skip_trailing_newlines, "missing trailing newline"),
             1 => {}
-            n => tidy_error!(bad, "{}: too many trailing newlines ({})", file.display(), n),
+            n => suppressible_tidy_err!(
+                err,
+                skip_trailing_newlines,
+                &format!("too many trailing newlines ({})", n)
+            ),
         };
         if lines > LINES {
             let mut err = |_| {
@@ -247,6 +256,9 @@ pub fn check(path: &Path, bad: &mut bool) {
         if let Directive::Ignore(false) = skip_end_whitespace {
             tidy_error!(bad, "{}: ignoring trailing whitespace unnecessarily", file.display());
         }
+        if let Directive::Ignore(false) = skip_trailing_newlines {
+            tidy_error!(bad, "{}: ignoring trailing newlines unnecessarily", file.display());
+        }
         if let Directive::Ignore(false) = skip_copyright {
             tidy_error!(bad, "{}: ignoring copyright unnecessarily", file.display());
         }