diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index a9b4e3e4706b8..8efacf108fc2f 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -959,7 +959,7 @@ impl<T> LinkedList<T> {
         let it = self.head;
         let old_len = self.len;
 
-        DrainFilter { list: self, it: it, pred: filter, idx: 0, old_len: old_len }
+        DrainFilter { list: self, it, pred: filter, idx: 0, old_len }
     }
 }
 
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 3fd7be06fd4fc..7523d9c5ba3b1 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1659,7 +1659,7 @@ struct SetLenOnDrop<'a> {
 impl<'a> SetLenOnDrop<'a> {
     #[inline]
     fn new(len: &'a mut usize) -> Self {
-        SetLenOnDrop { local_len: *len, len: len }
+        SetLenOnDrop { local_len: *len, len }
     }
 
     #[inline]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 1670c8418421f..0e12e6360da95 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -103,7 +103,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn first(&self) -> Option<&T> {
-        self.get(0)
+        if let [first, ..] = self { Some(first) } else { None }
     }
 
     /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty.
@@ -121,7 +121,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn first_mut(&mut self) -> Option<&mut T> {
-        self.get_mut(0)
+        if let [first, ..] = self { Some(first) } else { None }
     }
 
     /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -139,7 +139,7 @@ impl<T> [T] {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_first(&self) -> Option<(&T, &[T])> {
-        if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
+        if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
     }
 
     /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -159,12 +159,7 @@ impl<T> [T] {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        if self.is_empty() {
-            None
-        } else {
-            let split = self.split_at_mut(1);
-            Some((&mut split.0[0], split.1))
-        }
+        if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
     }
 
     /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -182,8 +177,7 @@ impl<T> [T] {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_last(&self) -> Option<(&T, &[T])> {
-        let len = self.len();
-        if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
+        if let [init @ .., last] = self { Some((last, init)) } else { None }
     }
 
     /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -203,13 +197,7 @@ impl<T> [T] {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        let len = self.len();
-        if len == 0 {
-            None
-        } else {
-            let split = self.split_at_mut(len - 1);
-            Some((&mut split.1[0], split.0))
-        }
+        if let [init @ .., last] = self { Some((last, init)) } else { None }
     }
 
     /// Returns the last element of the slice, or `None` if it is empty.
@@ -226,8 +214,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn last(&self) -> Option<&T> {
-        let last_idx = self.len().checked_sub(1)?;
-        self.get(last_idx)
+        if let [.., last] = self { Some(last) } else { None }
     }
 
     /// Returns a mutable pointer to the last item in the slice.
@@ -245,8 +232,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn last_mut(&mut self) -> Option<&mut T> {
-        let last_idx = self.len().checked_sub(1)?;
-        self.get_mut(last_idx)
+        if let [.., last] = self { Some(last) } else { None }
     }
 
     /// Returns a reference to an element or subslice depending on the type of
diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs
index fdf252e53387e..7495468a05b6c 100644
--- a/src/libproc_macro/diagnostic.rs
+++ b/src/libproc_macro/diagnostic.rs
@@ -55,13 +55,15 @@ pub struct Diagnostic {
 }
 
 macro_rules! diagnostic_child_methods {
-    ($spanned:ident, $regular:ident, $level:expr) => (
+    ($spanned:ident, $regular:ident, $level:expr) => {
         /// Adds a new child diagnostic message to `self` with the level
         /// identified by this method's name with the given `spans` and
         /// `message`.
         #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
         pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
-            where S: MultiSpan, T: Into<String>
+        where
+            S: MultiSpan,
+            T: Into<String>,
         {
             self.children.push(Diagnostic::spanned(spans, $level, message));
             self
@@ -74,7 +76,7 @@ macro_rules! diagnostic_child_methods {
             self.children.push(Diagnostic::new($level, message));
             self
         }
-    )
+    };
 }
 
 /// Iterator over the children diagnostics of a `Diagnostic`.
@@ -96,7 +98,7 @@ impl Diagnostic {
     /// Creates a new diagnostic with the given `level` and `message`.
     #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
     pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
-        Diagnostic { level: level, message: message.into(), spans: vec![], children: vec![] }
+        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
     }
 
     /// Creates a new diagnostic with the given `level` and `message` pointing to
@@ -107,12 +109,7 @@ impl Diagnostic {
         S: MultiSpan,
         T: Into<String>,
     {
-        Diagnostic {
-            level: level,
-            message: message.into(),
-            spans: spans.into_spans(),
-            children: vec![],
-        }
+        Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
     }
 
     diagnostic_child_methods!(span_error, error, Level::Error);
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 047ce8b8445fd..e1b5ec041db06 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -192,7 +192,7 @@ impl DefPath {
             }
         }
         data.reverse();
-        DefPath { data: data, krate: krate }
+        DefPath { data, krate }
     }
 
     /// Returns a string representation of the `DefPath` without
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 51718592fd9db..18bdecafecd3c 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1446,7 +1446,7 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
         match successor_count {
             0 => Ok(()),
 
-            1 => write!(fmt, " -> {:?}", self.successors().nth(0).unwrap()),
+            1 => write!(fmt, " -> {:?}", self.successors().next().unwrap()),
 
             _ => {
                 write!(fmt, " -> [")?;
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 9a3ddfb0e82c9..4f8efc1607eaa 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -258,7 +258,7 @@ pub enum Visibility {
 
 impl<'tcx> CodegenUnit<'tcx> {
     pub fn new(name: Symbol) -> CodegenUnit<'tcx> {
-        CodegenUnit { name: name, items: Default::default(), size_estimate: None }
+        CodegenUnit { name, items: Default::default(), size_estimate: None }
     }
 
     pub fn name(&self) -> Symbol {
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 63d7124ee91f9..a5efea9e5fa4d 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -532,9 +532,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
                 nested,
             }) => tcx.lift(&substs).map(|substs| {
                 traits::VtableGenerator(traits::VtableGeneratorData {
-                    generator_def_id: generator_def_id,
-                    substs: substs,
-                    nested: nested,
+                    generator_def_id,
+                    substs,
+                    nested,
                 })
             }),
             traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 20736b50831bb..48ef81c1d5bf7 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2256,22 +2256,22 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut { ty: ty, mutbl: hir::Mutability::Mut })
+        self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Mut })
     }
 
     #[inline]
     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut { ty: ty, mutbl: hir::Mutability::Not })
+        self.mk_ref(r, TypeAndMut { ty, mutbl: hir::Mutability::Not })
     }
 
     #[inline]
     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut { ty: ty, mutbl: hir::Mutability::Mut })
+        self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Mut })
     }
 
     #[inline]
     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut { ty: ty, mutbl: hir::Mutability::Not })
+        self.mk_ptr(TypeAndMut { ty, mutbl: hir::Mutability::Not })
     }
 
     #[inline]
@@ -2393,7 +2393,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
-        self.mk_ty(Param(ParamTy { index, name: name }))
+        self.mk_ty(Param(ParamTy { index, name }))
     }
 
     #[inline]
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 4014d1d8ae250..445df76cd32be 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -241,7 +241,7 @@ impl<'tcx> Instance<'tcx> {
             def_id,
             substs
         );
-        Instance { def: InstanceDef::Item(def_id), substs: substs }
+        Instance { def: InstanceDef::Item(def_id), substs }
     }
 
     pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index b25fd3c61fd5d..7bcd63b965534 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -370,7 +370,7 @@ pub trait DefIdTree: Copy {
 
 impl<'tcx> DefIdTree for TyCtxt<'tcx> {
     fn parent(self, id: DefId) -> Option<DefId> {
-        self.def_key(id).parent.map(|index| DefId { index: index, ..id })
+        self.def_key(id).parent.map(|index| DefId { index, ..id })
     }
 }
 
@@ -2227,7 +2227,7 @@ impl ReprOptions {
         if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
             flags.insert(ReprFlags::IS_LINEAR);
         }
-        ReprOptions { int: size, align: max_align, pack: min_pack, flags: flags }
+        ReprOptions { int: size, align: max_align, pack: min_pack, flags }
     }
 
     #[inline]
diff --git a/src/librustc/ty/normalize_erasing_regions.rs b/src/librustc/ty/normalize_erasing_regions.rs
index dc64482907f75..cbaabd8e1f137 100644
--- a/src/librustc/ty/normalize_erasing_regions.rs
+++ b/src/librustc/ty/normalize_erasing_regions.rs
@@ -34,10 +34,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if !value.has_projections() {
             value
         } else {
-            value.fold_with(&mut NormalizeAfterErasingRegionsFolder {
-                tcx: self,
-                param_env: param_env,
-            })
+            value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
         }
     }
 
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 3b9df72266f09..10f27bf66f383 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -287,7 +287,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
         } else {
             let substs = relate_substs(relation, None, a.substs, b.substs)?;
-            Ok(ty::TraitRef { def_id: a.def_id, substs: substs })
+            Ok(ty::TraitRef { def_id: a.def_id, substs })
         }
     }
 }
@@ -303,7 +303,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
         } else {
             let substs = relate_substs(relation, None, a.substs, b.substs)?;
-            Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs: substs })
+            Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs })
         }
     }
 }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index ab2c98c89b4e6..47bf7822b1f55 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1193,7 +1193,7 @@ pub struct ParamTy {
 
 impl<'tcx> ParamTy {
     pub fn new(index: u32, name: Symbol) -> ParamTy {
-        ParamTy { index, name: name }
+        ParamTy { index, name }
     }
 
     pub fn for_self() -> ParamTy {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 62d2b4ae20397..fcebedb2601c2 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -357,7 +357,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut dtor_did = None;
         let ty = self.type_of(adt_did);
         self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
-            if let Some(item) = self.associated_items(impl_did).in_definition_order().nth(0) {
+            if let Some(item) = self.associated_items(impl_did).in_definition_order().next() {
                 if validate(self, impl_did).is_ok() {
                     dtor_did = Some(item.def_id);
                 }
diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs
index 311298c0f4083..e0c619fcbd378 100644
--- a/src/librustc_builtin_macros/deriving/generic/mod.rs
+++ b/src/librustc_builtin_macros/deriving/generic/mod.rs
@@ -482,7 +482,7 @@ impl<'a> TraitDef<'a> {
                         })
                         .cloned(),
                 );
-                push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
+                push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
             }
             _ => {
                 // Non-Item derive is an error, but it should have been
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index c79d9f77e654e..470a2bb8e1ea5 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -148,7 +148,7 @@ impl LlvmType for CastTarget {
             .prefix
             .iter()
             .flat_map(|option_kind| {
-                option_kind.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.llvm_type(cx))
+                option_kind.map(|kind| Reg { kind, size: self.prefix_chunk }.llvm_type(cx))
             })
             .chain((0..rest_count).map(|_| rest_ll_unit))
             .collect();
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index 9258b59f79be8..f15e626c2783b 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -4,7 +4,7 @@ use rustc_ast::ast::{self, Attribute, Name, NodeId, PatKind};
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token;
-use rustc_ast::tokenstream::{self, TokenStream};
+use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
 use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
 use rustc_data_structures::fx::FxHashMap;
@@ -118,6 +118,31 @@ impl Annotatable {
         }
     }
 
+    crate fn into_tokens(self) -> TokenStream {
+        // `Annotatable` can be converted into tokens directly, but we
+        // are packing it into a nonterminal as a piece of AST to make
+        // the produced token stream look nicer in pretty-printed form.
+        let nt = match self {
+            Annotatable::Item(item) => token::NtItem(item),
+            Annotatable::TraitItem(item) | Annotatable::ImplItem(item) => {
+                token::NtItem(P(item.and_then(ast::AssocItem::into_item)))
+            }
+            Annotatable::ForeignItem(item) => {
+                token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
+            }
+            Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
+            Annotatable::Expr(expr) => token::NtExpr(expr),
+            Annotatable::Arm(..)
+            | Annotatable::Field(..)
+            | Annotatable::FieldPat(..)
+            | Annotatable::GenericParam(..)
+            | Annotatable::Param(..)
+            | Annotatable::StructField(..)
+            | Annotatable::Variant(..) => panic!("unexpected annotatable"),
+        };
+        TokenTree::token(token::Interpolated(Lrc::new(nt)), DUMMY_SP).into()
+    }
+
     pub fn expect_item(self) -> P<ast::Item> {
         match self {
             Annotatable::Item(i) => i,
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index b16659725db73..effa89e8bfb21 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -10,12 +10,11 @@ use rustc_ast::ast::{ItemKind, MacArgs, MacStmtStyle, StmtKind};
 use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
 use rustc_ast::token;
-use rustc_ast::tokenstream::{TokenStream, TokenTree};
+use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::map_in_place::MapInPlace;
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
 use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::Features;
 use rustc_parse::configure;
@@ -668,38 +667,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 SyntaxExtensionKind::Attr(expander) => {
                     self.gate_proc_macro_input(&item);
                     self.gate_proc_macro_attr_item(span, &item);
-                    // `Annotatable` can be converted into tokens directly, but we are packing it
-                    // into a nonterminal as a piece of AST to make the produced token stream
-                    // look nicer in pretty-printed form. This may be no longer necessary.
-                    let item_tok = TokenTree::token(
-                        token::Interpolated(Lrc::new(match item {
-                            Annotatable::Item(item) => token::NtItem(item),
-                            Annotatable::TraitItem(item) | Annotatable::ImplItem(item) => {
-                                token::NtItem(P(item.and_then(ast::AssocItem::into_item)))
-                            }
-                            Annotatable::ForeignItem(item) => {
-                                token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
-                            }
-                            Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
-                            Annotatable::Expr(expr) => token::NtExpr(expr),
-                            Annotatable::Arm(..)
-                            | Annotatable::Field(..)
-                            | Annotatable::FieldPat(..)
-                            | Annotatable::GenericParam(..)
-                            | Annotatable::Param(..)
-                            | Annotatable::StructField(..)
-                            | Annotatable::Variant(..) => panic!("unexpected annotatable"),
-                        })),
-                        DUMMY_SP,
-                    )
-                    .into();
-                    let item = attr.unwrap_normal_item();
-                    if let MacArgs::Eq(..) = item.args {
+                    let tokens = item.into_tokens();
+                    let attr_item = attr.unwrap_normal_item();
+                    if let MacArgs::Eq(..) = attr_item.args {
                         self.cx.span_err(span, "key-value macro attributes are not supported");
                     }
                     let tok_result =
-                        expander.expand(self.cx, span, item.args.inner_tokens(), item_tok);
-                    self.parse_ast_fragment(tok_result, fragment_kind, &item.path, span)
+                        expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens);
+                    self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
                 }
                 SyntaxExtensionKind::LegacyAttr(expander) => {
                     match validate_attr::parse_meta(self.cx.parse_sess, &attr) {
diff --git a/src/librustc_infer/infer/at.rs b/src/librustc_infer/infer/at.rs
index 156b5a8b0b50b..04f5b03c0e15c 100644
--- a/src/librustc_infer/infer/at.rs
+++ b/src/librustc_infer/infer/at.rs
@@ -179,7 +179,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
         T: ToTrace<'tcx>,
     {
         let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
-        Trace { at: self, trace: trace, a_is_expected }
+        Trace { at: self, trace, a_is_expected }
     }
 }
 
diff --git a/src/librustc_infer/infer/equate.rs b/src/librustc_infer/infer/equate.rs
index c1eec6832b826..bb0c124a1892d 100644
--- a/src/librustc_infer/infer/equate.rs
+++ b/src/librustc_infer/infer/equate.rs
@@ -19,7 +19,7 @@ impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> {
         fields: &'combine mut CombineFields<'infcx, 'tcx>,
         a_is_expected: bool,
     ) -> Equate<'combine, 'infcx, 'tcx> {
-        Equate { fields: fields, a_is_expected: a_is_expected }
+        Equate { fields, a_is_expected }
     }
 }
 
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
index 4dc9096533b84..cab632935fd8e 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
@@ -77,11 +77,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                             if found_anon_region {
                                 let is_first = index == 0;
                                 Some(AnonymousParamInfo {
-                                    param: param,
+                                    param,
                                     param_ty: new_param_ty,
-                                    param_ty_span: param_ty_span,
-                                    bound_region: bound_region,
-                                    is_first: is_first,
+                                    param_ty_span,
+                                    bound_region,
+                                    is_first,
                                 })
                             } else {
                                 None
diff --git a/src/librustc_infer/infer/glb.rs b/src/librustc_infer/infer/glb.rs
index 2634d9cac3e99..8b26bcef57304 100644
--- a/src/librustc_infer/infer/glb.rs
+++ b/src/librustc_infer/infer/glb.rs
@@ -18,7 +18,7 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
         fields: &'combine mut CombineFields<'infcx, 'tcx>,
         a_is_expected: bool,
     ) -> Glb<'combine, 'infcx, 'tcx> {
-        Glb { fields: fields, a_is_expected: a_is_expected }
+        Glb { fields, a_is_expected }
     }
 }
 
diff --git a/src/librustc_infer/infer/lub.rs b/src/librustc_infer/infer/lub.rs
index b6d20ba1f3f12..20ddeec68503a 100644
--- a/src/librustc_infer/infer/lub.rs
+++ b/src/librustc_infer/infer/lub.rs
@@ -18,7 +18,7 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
         fields: &'combine mut CombineFields<'infcx, 'tcx>,
         a_is_expected: bool,
     ) -> Lub<'combine, 'infcx, 'tcx> {
-        Lub { fields: fields, a_is_expected: a_is_expected }
+        Lub { fields, a_is_expected }
     }
 }
 
diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/src/librustc_infer/infer/region_constraints/leak_check.rs
index bbd4f3b35508e..6ebe3f5759760 100644
--- a/src/librustc_infer/infer/region_constraints/leak_check.rs
+++ b/src/librustc_infer/infer/region_constraints/leak_check.rs
@@ -85,7 +85,7 @@ impl<'tcx> TaintSet<'tcx> {
     fn new(directions: TaintDirections, initial_region: ty::Region<'tcx>) -> Self {
         let mut regions = FxHashSet::default();
         regions.insert(initial_region);
-        TaintSet { directions: directions, regions: regions }
+        TaintSet { directions, regions }
     }
 
     fn fixed_point(
diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs
index 3f9fa6459b37f..868b95043796b 100644
--- a/src/librustc_infer/infer/region_constraints/mod.rs
+++ b/src/librustc_infer/infer/region_constraints/mod.rs
@@ -766,7 +766,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
         b: Region<'tcx>,
         origin: SubregionOrigin<'tcx>,
     ) -> Region<'tcx> {
-        let vars = TwoRegions { a: a, b: b };
+        let vars = TwoRegions { a, b };
         if let Some(&c) = self.combine_map(t).get(&vars) {
             return tcx.mk_region(ReVar(c));
         }
diff --git a/src/librustc_infer/infer/resolve.rs b/src/librustc_infer/infer/resolve.rs
index e2207d08ee61b..562fbc246f7ee 100644
--- a/src/librustc_infer/infer/resolve.rs
+++ b/src/librustc_infer/infer/resolve.rs
@@ -160,7 +160,7 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: &T) -> Fix
 where
     T: TypeFoldable<'tcx>,
 {
-    let mut full_resolver = FullTypeResolver { infcx: infcx, err: None };
+    let mut full_resolver = FullTypeResolver { infcx, err: None };
     let result = value.fold_with(&mut full_resolver);
     match full_resolver.err {
         None => Ok(result),
diff --git a/src/librustc_infer/infer/sub.rs b/src/librustc_infer/infer/sub.rs
index 2b770ced42a55..f6fc38b535887 100644
--- a/src/librustc_infer/infer/sub.rs
+++ b/src/librustc_infer/infer/sub.rs
@@ -19,7 +19,7 @@ impl<'combine, 'infcx, 'tcx> Sub<'combine, 'infcx, 'tcx> {
         f: &'combine mut CombineFields<'infcx, 'tcx>,
         a_is_expected: bool,
     ) -> Sub<'combine, 'infcx, 'tcx> {
-        Sub { fields: f, a_is_expected: a_is_expected }
+        Sub { fields: f, a_is_expected }
     }
 
     fn with_expected_switched<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 61702d74f1a91..800f8e91a7801 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -619,7 +619,7 @@ impl<'tcx> FulfillmentError<'tcx> {
         obligation: PredicateObligation<'tcx>,
         code: FulfillmentErrorCode<'tcx>,
     ) -> FulfillmentError<'tcx> {
-        FulfillmentError { obligation: obligation, code: code, points_at_arg_span: false }
+        FulfillmentError { obligation, code, points_at_arg_span: false }
     }
 }
 
diff --git a/src/librustc_infer/traits/project.rs b/src/librustc_infer/traits/project.rs
index 34889c6984bb0..78483cf6577de 100644
--- a/src/librustc_infer/traits/project.rs
+++ b/src/librustc_infer/traits/project.rs
@@ -403,7 +403,7 @@ pub type NormalizedTy<'tcx> = Normalized<'tcx, Ty<'tcx>>;
 
 impl<'tcx, T> Normalized<'tcx, T> {
     pub fn with<U>(self, value: U) -> Normalized<'tcx, U> {
-        Normalized { value: value, obligations: self.obligations }
+        Normalized { value, obligations: self.obligations }
     }
 }
 
@@ -1291,7 +1291,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
                 substs: trait_ref.substs,
                 item_def_id: obligation.predicate.item_def_id,
             },
-            ty: ty,
+            ty,
         }
     });
 
diff --git a/src/librustc_infer/traits/select.rs b/src/librustc_infer/traits/select.rs
index fd94e3b69940c..c0d8f3cfd4f86 100644
--- a/src/librustc_infer/traits/select.rs
+++ b/src/librustc_infer/traits/select.rs
@@ -2923,7 +2923,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::Predicate::ClosureKind(closure_def_id, substs, kind),
         ));
 
-        Ok(VtableClosureData { closure_def_id, substs: substs, nested: obligations })
+        Ok(VtableClosureData { closure_def_id, substs, nested: obligations })
     }
 
     /// In the case of closure types and fn pointers,
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index 1dca01b3468ae..cd4595e76ccec 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -55,7 +55,7 @@ struct PredicateSet<'tcx> {
 
 impl PredicateSet<'tcx> {
     fn new(tcx: TyCtxt<'tcx>) -> Self {
-        Self { tcx: tcx, set: Default::default() }
+        Self { tcx, set: Default::default() }
     }
 
     fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs
index 7da69f3ed26f2..e0db2ae64ff21 100644
--- a/src/librustc_lint/levels.rs
+++ b/src/librustc_lint/levels.rs
@@ -377,10 +377,10 @@ impl<'s> LintLevelsBuilder<'s> {
         let prev = self.cur;
         if !specs.is_empty() {
             self.cur = self.sets.list.len() as u32;
-            self.sets.list.push(LintSet::Node { specs: specs, parent: prev });
+            self.sets.list.push(LintSet::Node { specs, parent: prev });
         }
 
-        BuilderPush { prev: prev, changed: prev != self.cur }
+        BuilderPush { prev, changed: prev != self.cur }
     }
 
     /// Called after `push` when the scope of a set of attributes are exited.
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index ea0cc2f0c8bf2..7624b1d562f08 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -493,7 +493,7 @@ impl<'tcx> EncodeContext<'tcx> {
             edition: tcx.sess.edition(),
             has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
             has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
-            has_default_lib_allocator: has_default_lib_allocator,
+            has_default_lib_allocator,
             plugin_registrar_fn: tcx.plugin_registrar_fn(LOCAL_CRATE).map(|id| id.index),
             proc_macro_decls_static: if is_proc_macro {
                 let id = tcx.proc_macro_decls_static(LOCAL_CRATE).unwrap();
diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs
index cd6834a5a4d00..fefef69d63cbd 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mod.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs
@@ -175,7 +175,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 if self.body.local_decls[local].is_ref_for_guard() =>
             {
                 self.append_place_to_string(
-                    PlaceRef { local: local, projection: &[] },
+                    PlaceRef { local, projection: &[] },
                     buf,
                     autoderef,
                     &including_downcast,
diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs
index 3126d44014b4e..675463cb1c1f9 100644
--- a/src/librustc_mir/borrow_check/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/region_infer/values.rs
@@ -140,7 +140,7 @@ impl<N: Idx> LivenessValues<N> {
     /// Each of the regions in num_region_variables will be initialized with an
     /// empty set of points and no causal information.
     crate fn new(elements: Rc<RegionValueElements>) -> Self {
-        Self { points: SparseBitMatrix::new(elements.num_points), elements: elements }
+        Self { points: SparseBitMatrix::new(elements.num_points), elements }
     }
 
     /// Iterate through each region that has a value in this set.
diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs
index af4ea759f4f8b..67b00e9ffdd5f 100644
--- a/src/librustc_mir/borrow_check/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/universal_regions.rs
@@ -486,7 +486,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             defining_ty,
             unnormalized_output_ty,
             unnormalized_input_tys,
-            yield_ty: yield_ty,
+            yield_ty,
         }
     }
 
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
index 45d2b1a71f0f2..a9ef7ef6c528a 100644
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ b/src/librustc_mir/dataflow/graphviz.rs
@@ -72,7 +72,7 @@ pub struct Edge {
 
 fn outgoing(body: &Body<'_>, bb: BasicBlock) -> Vec<Edge> {
     (0..body[bb].terminator().successors().count())
-        .map(|index| Edge { source: bb, index: index })
+        .map(|index| Edge { source: bb, index })
         .collect()
 }
 
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 57aa5de7f7a31..7e36a3cf2bfec 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -474,7 +474,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     }
 
     fn record_move(&mut self, place: &Place<'tcx>, path: MovePathIndex) {
-        let move_out = self.builder.data.moves.push(MoveOut { path: path, source: self.loc });
+        let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc });
         debug!(
             "gather_move({:?}, {:?}): adding move {:?} of {:?}",
             self.loc, place, move_out, path
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 721766cc932d3..fff9c740f7e49 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -655,7 +655,7 @@ where
             }
             local => PlaceTy {
                 // This works even for dead/uninitialized locals; we check further when writing
-                place: Place::Local { frame: self.cur_frame(), local: local },
+                place: Place::Local { frame: self.cur_frame(), local },
                 layout: self.layout_of_local(self.frame(), local, None)?,
             },
         };
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 3dff06967e50e..7177bf726d403 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -13,7 +13,7 @@ pub fn custom_coerce_unsize_info<'tcx>(
     let def_id = tcx.lang_items().coerce_unsized_trait().unwrap();
 
     let trait_ref = ty::Binder::bind(ty::TraitRef {
-        def_id: def_id,
+        def_id,
         substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
     });
 
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index a5b467c1e101f..45cecc1b125d8 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -75,8 +75,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         {
             let source_info = SourceInfo {
                 scope: OUTERMOST_SOURCE_SCOPE,
-                span: span, // FIXME: Consider using just the span covering the function
-                            // argument declaration.
+                span, // FIXME: Consider using just the span covering the function
+                      // argument declaration.
             };
             // Gather all arguments, skip return value.
             let places = local_decls
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 3107be1b62207..d060a0eab3db0 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -506,7 +506,7 @@ fn locals_live_across_suspend_points(
 
     for (block, data) in body.basic_blocks().iter_enumerated() {
         if let TerminatorKind::Yield { .. } = data.terminator().kind {
-            let loc = Location { block: block, statement_index: data.statements.len() };
+            let loc = Location { block, statement_index: data.statements.len() };
 
             if !movable {
                 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 2ae7bd4d72729..22ac3410a75ab 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -34,7 +34,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
         let attributes = tcx.get_attrs(def_id);
         let param_env = tcx.param_env(def_id);
         let move_data = MoveData::gather_moves(body, tcx, param_env).unwrap();
-        let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
+        let mdpe = MoveDataParamEnv { move_data, param_env };
 
         let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe)
             .into_engine(tcx, body, def_id)
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index ddf8d73e5481f..597d3f0237a71 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -230,7 +230,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
         };
 
         let first_succ = {
-            if let Some(&first_succ) = terminator.successors().nth(0) {
+            if let Some(&first_succ) = terminator.successors().next() {
                 if terminator.successors().all(|s| *s == first_succ) {
                     let count = terminator.successors().count();
                     self.pred_count[first_succ] -= (count - 1) as u32;
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index f7239ae55faa2..0b303e230e287 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -549,7 +549,7 @@ where
         debug!("destructor_call_block({:?}, {:?})", self, succ);
         let tcx = self.tcx();
         let drop_trait = tcx.lang_items().drop_trait().unwrap();
-        let drop_fn = tcx.associated_items(drop_trait).in_definition_order().nth(0).unwrap();
+        let drop_fn = tcx.associated_items(drop_trait).in_definition_order().next().unwrap();
         let ty = self.place_ty(self.place);
         let substs = tcx.mk_substs_trait(ty, &[]);
 
@@ -872,7 +872,7 @@ where
         debug!("drop_flag_reset_block({:?},{:?})", self, mode);
 
         let block = self.new_block(unwind, TerminatorKind::Goto { target: succ });
-        let block_start = Location { block: block, statement_index: 0 };
+        let block_start = Location { block, statement_index: 0 };
         self.elaborator.clear_drop_flag(block_start, self.path, mode);
         block
     }
@@ -921,7 +921,7 @@ where
 
         let call = TerminatorKind::Call {
             func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
-            args: args,
+            args,
             destination: Some((unit_temp, target)),
             cleanup: None,
             from_hir_call: false,
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 6fd8f06fe8f25..1fd5f3c439587 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -297,7 +297,7 @@ where
     writeln!(w, "{}{:?}{}: {{", INDENT, block, cleanup_text)?;
 
     // List of statements in the middle.
-    let mut current_location = Location { block: block, statement_index: 0 };
+    let mut current_location = Location { block, statement_index: 0 };
     for statement in &data.statements {
         extra_data(PassWhere::BeforeLocation(current_location), w)?;
         let indented_body = format!("{0}{0}{1:?};", INDENT, statement);
diff --git a/src/librustc_mir_build/build/matches/simplify.rs b/src/librustc_mir_build/build/matches/simplify.rs
index 56aa150dd37d2..80fa0c44860e4 100644
--- a/src/librustc_mir_build/build/matches/simplify.rs
+++ b/src/librustc_mir_build/build/matches/simplify.rs
@@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // value being matched, taking the variance field into account.
                 candidate.ascriptions.push(Ascription {
                     span: user_ty_span,
-                    user_ty: user_ty,
+                    user_ty,
                     source: match_pair.place,
                     variance,
                 });
diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs
index 9f450f8fc7b77..d23a2708dc478 100644
--- a/src/librustc_mir_build/build/matches/test.rs
+++ b/src/librustc_mir_build/build/matches/test.rs
@@ -64,10 +64,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatKind::Slice { ref prefix, ref slice, ref suffix } => {
                 let len = prefix.len() + suffix.len();
                 let op = if slice.is_some() { BinOp::Ge } else { BinOp::Eq };
-                Test {
-                    span: match_pair.pattern.span,
-                    kind: TestKind::Len { len: len as u64, op: op },
-                }
+                Test { span: match_pair.pattern.span, kind: TestKind::Len { len: len as u64, op } }
             }
 
             PatKind::Or { .. } => bug!("or-patterns should have already been handled"),
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index 830877f713e4b..b60a637471e13 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -418,7 +418,7 @@ struct GuardFrameLocal {
 
 impl GuardFrameLocal {
     fn new(id: hir::HirId, _binding_mode: BindingMode) -> Self {
-        GuardFrameLocal { id: id }
+        GuardFrameLocal { id }
     }
 }
 
diff --git a/src/librustc_mir_build/hair/cx/block.rs b/src/librustc_mir_build/hair/cx/block.rs
index a883b84f8fe2f..8d7225c8c7b51 100644
--- a/src/librustc_mir_build/hair/cx/block.rs
+++ b/src/librustc_mir_build/hair/cx/block.rs
@@ -84,7 +84,7 @@ fn mirror_stmts<'a, 'tcx>(
 
                 result.push(StmtRef::Mirror(Box::new(Stmt {
                     kind: StmtKind::Let {
-                        remainder_scope: remainder_scope,
+                        remainder_scope,
                         init_scope: region::Scope {
                             id: hir_id.local_id,
                             data: region::ScopeData::Node,
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 5b054c0452243..ecf0bed6a6e31 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -1000,7 +1000,7 @@ impl<'tcx> Constructor<'tcx> {
                         PatKind::Leaf { subpatterns }
                     }
                 }
-                ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() },
+                ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.next().unwrap() },
                 ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
                 _ => PatKind::Wild,
             },
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 18ddd23588e48..505c6139ad63b 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -544,8 +544,8 @@ impl<'a> Parser<'a> {
         // Save the state of the parser before parsing type normally, in case there is a
         // LessThan comparison after this cast.
         let parser_snapshot_before_type = self.clone();
-        match self.parse_ty_no_plus() {
-            Ok(rhs) => Ok(mk_expr(self, rhs)),
+        let cast_expr = match self.parse_ty_no_plus() {
+            Ok(rhs) => mk_expr(self, rhs),
             Err(mut type_err) => {
                 // Rewind to before attempting to parse the type with generics, to recover
                 // from situations like `x as usize < y` in which we first tried to parse
@@ -599,17 +599,70 @@ impl<'a> Parser<'a> {
                             )
                             .emit();
 
-                        Ok(expr)
+                        expr
                     }
                     Err(mut path_err) => {
                         // Couldn't parse as a path, return original error and parser state.
                         path_err.cancel();
                         mem::replace(self, parser_snapshot_after_type);
-                        Err(type_err)
+                        return Err(type_err);
                     }
                 }
             }
-        }
+        };
+
+        self.parse_and_disallow_postfix_after_cast(cast_expr)
+    }
+
+    /// Parses a postfix operators such as `.`, `?`, or index (`[]`) after a cast,
+    /// then emits an error and returns the newly parsed tree.
+    /// The resulting parse tree for `&x as T[0]` has a precedence of `((&x) as T)[0]`.
+    fn parse_and_disallow_postfix_after_cast(
+        &mut self,
+        cast_expr: P<Expr>,
+    ) -> PResult<'a, P<Expr>> {
+        // Save the memory location of expr before parsing any following postfix operators.
+        // This will be compared with the memory location of the output expression.
+        // If they different we can assume we parsed another expression because the existing expression is not reallocated.
+        let addr_before = &*cast_expr as *const _ as usize;
+        let span = cast_expr.span;
+        let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
+        let changed = addr_before != &*with_postfix as *const _ as usize;
+
+        // Check if an illegal postfix operator has been added after the cast.
+        // If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
+        if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed {
+            let msg = format!(
+                "casts cannot be followed by {}",
+                match with_postfix.kind {
+                    ExprKind::Index(_, _) => "indexing",
+                    ExprKind::Try(_) => "?",
+                    ExprKind::Field(_, _) => "a field access",
+                    ExprKind::MethodCall(_, _) => "a method call",
+                    ExprKind::Call(_, _) => "a function call",
+                    ExprKind::Await(_) => "`.await`",
+                    _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
+                }
+            );
+            let mut err = self.struct_span_err(span, &msg);
+            // If type ascription is "likely an error", the user will already be getting a useful
+            // help message, and doesn't need a second.
+            if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
+                self.maybe_annotate_with_ascription(&mut err, false);
+            } else {
+                let suggestions = vec![
+                    (span.shrink_to_lo(), "(".to_string()),
+                    (span.shrink_to_hi(), ")".to_string()),
+                ];
+                err.multipart_suggestion(
+                    "try surrounding the expression in parentheses",
+                    suggestions,
+                    Applicability::MachineApplicable,
+                );
+            }
+            err.emit();
+        };
+        Ok(with_postfix)
     }
 
     fn parse_assoc_op_ascribe(&mut self, lhs: P<Expr>, lhs_span: Span) -> PResult<'a, P<Expr>> {
@@ -955,7 +1008,7 @@ impl<'a> Parser<'a> {
         };
         let kind = if es.len() == 1 && !trailing_comma {
             // `(e)` is parenthesized `e`.
-            ExprKind::Paren(es.into_iter().nth(0).unwrap())
+            ExprKind::Paren(es.into_iter().next().unwrap())
         } else {
             // `(e,)` is a tuple with only one field, `e`.
             ExprKind::Tup(es)
diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index 45d1aacdd3cc6..4c041fd669d67 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -479,7 +479,7 @@ impl<'a> Parser<'a> {
         // Here, `(pat,)` is a tuple pattern.
         // For backward compatibility, `(..)` is a tuple pattern as well.
         Ok(if fields.len() == 1 && !(trailing_comma || fields[0].is_rest()) {
-            PatKind::Paren(fields.into_iter().nth(0).unwrap())
+            PatKind::Paren(fields.into_iter().next().unwrap())
         } else {
             PatKind::Tuple(fields)
         })
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index 3d2b0c014ac49..c4469331b6669 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -198,7 +198,7 @@ impl<'a> Parser<'a> {
         })?;
 
         if ts.len() == 1 && !trailing {
-            let ty = ts.into_iter().nth(0).unwrap().into_inner();
+            let ty = ts.into_iter().next().unwrap().into_inner();
             let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
             match ty.kind {
                 // `(TY_BOUND_NOPAREN) + BOUND + ...`.
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index a3554ea2ee0a3..6b5e927214f5a 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -2102,7 +2102,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 .is_ok()
             {
                 let def_id = module.def_id().unwrap();
-                found_traits.push(TraitCandidate { def_id: def_id, import_ids: smallvec![] });
+                found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
             }
         }
 
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index 193b6d75935b2..7281173e9db78 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -1032,13 +1032,13 @@ struct Shadower {
 }
 
 fn original_label(span: Span) -> Original {
-    Original { kind: ShadowKind::Label, span: span }
+    Original { kind: ShadowKind::Label, span }
 }
 fn shadower_label(span: Span) -> Shadower {
-    Shadower { kind: ShadowKind::Label, span: span }
+    Shadower { kind: ShadowKind::Label, span }
 }
 fn original_lifetime(span: Span) -> Original {
-    Original { kind: ShadowKind::Lifetime, span: span }
+    Original { kind: ShadowKind::Lifetime, span }
 }
 fn shadower_lifetime(param: &hir::GenericParam<'_>) -> Shadower {
     Shadower { kind: ShadowKind::Lifetime, span: param.span }
@@ -1347,7 +1347,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
         let mut this = LifetimeContext {
             tcx: *tcx,
-            map: map,
+            map,
             scope: &wrap_scope,
             trait_ref_hack: self.trait_ref_hack,
             is_in_fn_syntax: self.is_in_fn_syntax,
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 9da8ee548fddd..ec251c224b690 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -334,7 +334,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                                     Some(_) => ImplKind::Direct,
                                     None => ImplKind::Inherent,
                                 },
-                                span: span,
+                                span,
                                 value: String::new(),
                                 parent: None,
                                 children: items
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index a295e1637aa4c..2005366f83986 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -793,7 +793,7 @@ impl Sig for ast::ForeignItem {
                 text.push_str(&name);
                 text.push(';');
 
-                Ok(Signature { text: text, defs: defs, refs: vec![] })
+                Ok(Signature { text, defs, refs: vec![] })
             }
             ast::ForeignItemKind::Macro(..) => Err("macro"),
         }
diff --git a/src/librustc_session/code_stats.rs b/src/librustc_session/code_stats.rs
index 9b89c7ae32abc..c263da69c3521 100644
--- a/src/librustc_session/code_stats.rs
+++ b/src/librustc_session/code_stats.rs
@@ -70,7 +70,7 @@ impl CodeStats {
             type_description: type_desc.to_string(),
             align: align.bytes(),
             overall_size: overall_size.bytes(),
-            packed: packed,
+            packed,
             opt_discr_size: opt_discr_size.map(|s| s.bytes()),
             variants,
         };
diff --git a/src/librustc_span/def_id.rs b/src/librustc_span/def_id.rs
index 6cdfd0500ca84..66cdf46bd4e5f 100644
--- a/src/librustc_span/def_id.rs
+++ b/src/librustc_span/def_id.rs
@@ -130,7 +130,7 @@ impl DefId {
     /// Makes a local `DefId` from the given `DefIndex`.
     #[inline]
     pub fn local(index: DefIndex) -> DefId {
-        DefId { krate: LOCAL_CRATE, index: index }
+        DefId { krate: LOCAL_CRATE, index }
     }
 
     #[inline]
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index e0bbaf730a537..cd2d2c4c3d768 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -620,7 +620,7 @@ impl SourceMap {
     /// if no character could be found or if an error occurred while retrieving the code snippet.
     pub fn span_extend_to_prev_char(&self, sp: Span, c: char) -> Span {
         if let Ok(prev_source) = self.span_to_prev_source(sp) {
-            let prev_source = prev_source.rsplit(c).nth(0).unwrap_or("").trim_start();
+            let prev_source = prev_source.rsplit(c).next().unwrap_or("").trim_start();
             if !prev_source.is_empty() && !prev_source.contains('\n') {
                 return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
             }
@@ -640,7 +640,7 @@ impl SourceMap {
         for ws in &[" ", "\t", "\n"] {
             let pat = pat.to_owned() + ws;
             if let Ok(prev_source) = self.span_to_prev_source(sp) {
-                let prev_source = prev_source.rsplit(&pat).nth(0).unwrap_or("").trim_start();
+                let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start();
                 if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) {
                     return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
                 }
@@ -655,7 +655,7 @@ impl SourceMap {
     pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         match self.span_to_snippet(sp) {
             Ok(snippet) => {
-                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_end();
+                let snippet = snippet.split(c).next().unwrap_or("").trim_end();
                 if !snippet.is_empty() && !snippet.contains('\n') {
                     sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32))
                 } else {
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index c2b2196e74c61..8b1ba57e81945 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -47,7 +47,7 @@ pub fn resolve_instance<'tcx>(
                 }
             }
         };
-        Some(Instance { def: def, substs: substs })
+        Some(Instance { def, substs })
     };
     debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
     result
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 816de5dadbc15..8689db1b1eb56 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -675,7 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // The `Future` trait has only one associted item, `Output`,
         // so check that this is what we see.
         let output_assoc_item =
-            self.tcx.associated_items(future_trait).in_definition_order().nth(0).unwrap().def_id;
+            self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id;
         if output_assoc_item != predicate.projection_ty.item_def_id {
             span_bug!(
                 cause_span,
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index ff9fec004bbb5..7570d9d4b28ac 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let needs = Needs::maybe_mut_place(mutbl);
         let ty = self.check_expr_with_expectation_and_needs(&oprnd, hint, needs);
 
-        let tm = ty::TypeAndMut { ty: ty, mutbl: mutbl };
+        let tm = ty::TypeAndMut { ty, mutbl };
         match kind {
             _ if tm.ty.references_error() => self.tcx.types.err,
             hir::BorrowKind::Raw => {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 95faa353e9b65..084601fbde1d4 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -547,10 +547,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 (&self_ty.kind, parent_pred)
                             {
                                 if let ty::Adt(def, _) = p.skip_binder().trait_ref.self_ty().kind {
-                                    let id = self.tcx.hir().as_local_hir_id(def.did).unwrap();
-                                    let node = self.tcx.hir().get(id);
+                                    let node = self
+                                        .tcx
+                                        .hir()
+                                        .as_local_hir_id(def.did)
+                                        .map(|id| self.tcx.hir().get(id));
                                     match node {
-                                        hir::Node::Item(hir::Item { kind, .. }) => {
+                                        Some(hir::Node::Item(hir::Item { kind, .. })) => {
                                             if let Some(g) = kind.generics() {
                                                 let key = match &g.where_clause.predicates[..] {
                                                     [.., pred] => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d8b23998e727f..60c5bcbb78df5 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4234,7 +4234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let substs = self.fresh_substs_for_item(span, did);
         let substd_ty = self.instantiate_type_scheme(span, &substs, &ity);
 
-        TypeAndSubsts { substs: substs, ty: substd_ty }
+        TypeAndSubsts { substs, ty: substd_ty }
     }
 
     /// Unifies the output type with the expected type early, for more coercions
@@ -5244,7 +5244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .tcx
                     .associated_items(future_trait)
                     .in_definition_order()
-                    .nth(0)
+                    .next()
                     .unwrap()
                     .def_id;
                 let predicate =
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index b7aac707a9838..dd4b407ac52cb 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -63,6 +63,22 @@ struct TopInfo<'tcx> {
     ///              found type `std::result::Result<_, _>`
     /// ```
     span: Option<Span>,
+    /// This refers to the parent pattern. Used to provide extra diagnostic information on errors.
+    /// ```text
+    /// error[E0308]: mismatched types
+    ///   --> $DIR/const-in-struct-pat.rs:8:17
+    ///   |
+    /// L | struct f;
+    ///   | --------- unit struct defined here
+    /// ...
+    /// L |     let Thing { f } = t;
+    ///   |                 ^
+    ///   |                 |
+    ///   |                 expected struct `std::string::String`, found struct `f`
+    ///   |                 `f` is interpreted as a unit struct, not a new binding
+    ///   |                 help: bind the struct field to a different name instead: `f: other_f`
+    /// ```
+    parent_pat: Option<&'tcx Pat<'tcx>>,
 }
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
@@ -120,7 +136,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Option<Span>,
         origin_expr: bool,
     ) {
-        self.check_pat(pat, expected, INITIAL_BM, TopInfo { expected, origin_expr, span });
+        let info = TopInfo { expected, origin_expr, span, parent_pat: None };
+        self.check_pat(pat, expected, INITIAL_BM, info);
     }
 
     /// Type check the given `pat` against the `expected` type
@@ -161,8 +178,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
             }
             PatKind::Or(pats) => {
+                let parent_pat = Some(pat);
                 for pat in pats {
-                    self.check_pat(pat, expected, def_bm, ti);
+                    self.check_pat(pat, expected, def_bm, TopInfo { parent_pat, ..ti });
                 }
                 expected
             }
@@ -501,7 +519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ident(
         &self,
-        pat: &Pat<'_>,
+        pat: &'tcx Pat<'tcx>,
         ba: hir::BindingAnnotation,
         var_id: HirId,
         sub: Option<&'tcx Pat<'tcx>>,
@@ -546,7 +564,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if let Some(p) = sub {
-            self.check_pat(&p, expected, def_bm, ti);
+            self.check_pat(&p, expected, def_bm, TopInfo { parent_pat: Some(&pat), ..ti });
         }
 
         local_ty
@@ -647,6 +665,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             variant_ty
         } else {
             for field in fields {
+                let ti = TopInfo { parent_pat: Some(&pat), ..ti };
                 self.check_pat(&field.pat, self.tcx.types.err, def_bm, ti);
             }
             return self.tcx.types.err;
@@ -656,9 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
 
         // Type-check subpatterns.
-        if self
-            .check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm, ti)
-        {
+        if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, etc, def_bm, ti) {
             pat_ty
         } else {
             self.tcx.types.err
@@ -696,18 +713,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // Type-check the path.
-        let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
-        if let Some(mut err) =
+        let (pat_ty, pat_res) =
+            self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
+        if let Some(err) =
             self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
         {
-            err.emit();
+            self.emit_bad_pat_path(err, pat.span, res, pat_res, segments, ti.parent_pat);
         }
         pat_ty
     }
 
+    fn emit_bad_pat_path(
+        &self,
+        mut e: DiagnosticBuilder<'_>,
+        pat_span: Span,
+        res: Res,
+        pat_res: Res,
+        segments: &'b [hir::PathSegment<'b>],
+        parent_pat: Option<&Pat<'_>>,
+    ) {
+        if let Some(span) = self.tcx.hir().res_span(pat_res) {
+            e.span_label(span, &format!("{} defined here", res.descr()));
+            if let [hir::PathSegment { ident, .. }] = &*segments {
+                e.span_label(
+                    pat_span,
+                    &format!(
+                        "`{}` is interpreted as {} {}, not a new binding",
+                        ident,
+                        res.article(),
+                        res.descr(),
+                    ),
+                );
+                let (msg, sugg) = match parent_pat {
+                    Some(Pat { kind: hir::PatKind::Struct(..), .. }) => (
+                        "bind the struct field to a different name instead",
+                        format!("{}: other_{}", ident, ident.as_str().to_lowercase()),
+                    ),
+                    _ => (
+                        "introduce a new binding instead",
+                        format!("other_{}", ident.as_str().to_lowercase()),
+                    ),
+                };
+                e.span_suggestion(ident.span, msg, sugg, Applicability::HasPlaceholders);
+            }
+        }
+        e.emit();
+    }
+
     fn check_pat_tuple_struct(
         &self,
-        pat: &Pat<'_>,
+        pat: &'tcx Pat<'tcx>,
         qpath: &hir::QPath<'_>,
         subpats: &'tcx [&'tcx Pat<'tcx>],
         ddpos: Option<usize>,
@@ -717,8 +772,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let on_error = || {
+            let parent_pat = Some(pat);
             for pat in subpats {
-                self.check_pat(&pat, tcx.types.err, def_bm, ti);
+                self.check_pat(&pat, tcx.types.err, def_bm, TopInfo { parent_pat, ..ti });
             }
         };
         let report_unexpected_res = |res: Res| {
@@ -793,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
-                self.check_pat(&subpat, field_ty, def_bm, ti);
+                self.check_pat(&subpat, field_ty, def_bm, TopInfo { parent_pat: Some(&pat), ..ti });
 
                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
             }
@@ -938,8 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_struct_pat_fields(
         &self,
         adt_ty: Ty<'tcx>,
-        pat_id: HirId,
-        span: Span,
+        pat: &'tcx Pat<'tcx>,
         variant: &'tcx ty::VariantDef,
         fields: &'tcx [hir::FieldPat<'tcx>],
         etc: bool,
@@ -950,7 +1005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (substs, adt) = match adt_ty.kind {
             ty::Adt(adt, substs) => (substs, adt),
-            _ => span_bug!(span, "struct pattern is not an ADT"),
+            _ => span_bug!(pat.span, "struct pattern is not an ADT"),
         };
         let kind_name = adt.variant_descr();
 
@@ -983,7 +1038,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .get(&ident)
                         .map(|(i, f)| {
                             self.write_field_index(field.hir_id, *i);
-                            self.tcx.check_stability(f.did, Some(pat_id), span);
+                            self.tcx.check_stability(f.did, Some(pat.hir_id), span);
                             self.field_ty(span, f, substs)
                         })
                         .unwrap_or_else(|| {
@@ -994,7 +1049,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             };
 
-            self.check_pat(&field.pat, field_ty, def_bm, ti);
+            self.check_pat(&field.pat, field_ty, def_bm, TopInfo { parent_pat: Some(&pat), ..ti });
         }
 
         let mut unmentioned_fields = variant
@@ -1017,7 +1072,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
             struct_span_err!(
                 tcx.sess,
-                span,
+                pat.span,
                 E0638,
                 "`..` required with {} marked as non-exhaustive",
                 kind_name
@@ -1029,14 +1084,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if kind_name == "union" {
             if fields.len() != 1 {
                 tcx.sess
-                    .struct_span_err(span, "union patterns should have exactly one field")
+                    .struct_span_err(pat.span, "union patterns should have exactly one field")
                     .emit();
             }
             if etc {
-                tcx.sess.struct_span_err(span, "`..` cannot be used in union patterns").emit();
+                tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
             }
         } else if !etc && !unmentioned_fields.is_empty() {
-            self.error_unmentioned_fields(span, &unmentioned_fields, variant);
+            self.error_unmentioned_fields(pat.span, &unmentioned_fields, variant);
         }
         no_field_errors
     }
@@ -1196,7 +1251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ref(
         &self,
-        pat: &Pat<'_>,
+        pat: &'tcx Pat<'tcx>,
         inner: &'tcx Pat<'tcx>,
         mutbl: hir::Mutability,
         expected: Ty<'tcx>,
@@ -1236,7 +1291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             (tcx.types.err, tcx.types.err)
         };
-        self.check_pat(&inner, inner_ty, def_bm, ti);
+        self.check_pat(&inner, inner_ty, def_bm, TopInfo { parent_pat: Some(&pat), ..ti });
         rptr_ty
     }
 
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index fcbeb5b210dec..44473fee643c6 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -31,10 +31,10 @@ pub fn infer_predicates<'tcx>(
         predicates_added = false;
 
         let mut visitor = InferVisitor {
-            tcx: tcx,
+            tcx,
             global_inferred_outlives: &mut global_inferred_outlives,
             predicates_added: &mut predicates_added,
-            explicit_map: explicit_map,
+            explicit_map,
         };
 
         // Visit all the crates and infer predicates
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index becdeaba50f78..41b8e66d26592 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -44,7 +44,7 @@ impl Module<'hir> {
         vis: &'hir hir::Visibility<'hir>,
     ) -> Module<'hir> {
         Module {
-            name: name,
+            name,
             id: hir::CRATE_HIR_ID,
             vis,
             where_outer: rustc_span::DUMMY_SP,
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index d0e1a01b00654..44f8e8bd1717a 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -2461,7 +2461,7 @@ impl RandomState {
         KEYS.with(|keys| {
             let (k0, k1) = keys.get();
             keys.set((k0.wrapping_add(1), k1));
-            RandomState { k0: k0, k1: k1 }
+            RandomState { k0, k1 }
         })
     }
 }
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index b480581e21ba9..3f6501bc7b4f6 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -135,7 +135,7 @@ pub trait Error: Debug + Display {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_deprecated(since = "1.41.0", reason = "use the Display impl or to_string()")]
+    #[rustc_deprecated(since = "1.42.0", reason = "use the Display impl or to_string()")]
     fn description(&self) -> &str {
         "description() is deprecated; use Display"
     }
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 9787cbb556bd2..f36aa1846a16c 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -96,7 +96,7 @@ impl<T> Cursor<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: T) -> Cursor<T> {
-        Cursor { pos: 0, inner: inner }
+        Cursor { pos: 0, inner }
     }
 
     /// Consumes this cursor, returning the underlying value.
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index a50dd9575de32..0103e4bd628d7 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -371,7 +371,7 @@ where
     F: FnMut(&R) -> usize,
 {
     let start_len = buf.len();
-    let mut g = Guard { len: buf.len(), buf: buf };
+    let mut g = Guard { len: buf.len(), buf };
     let ret;
     loop {
         if g.len == g.buf.len() {
@@ -939,7 +939,7 @@ pub trait Read {
     where
         Self: Sized,
     {
-        Take { inner: self, limit: limit }
+        Take { inner: self, limit }
     }
 }
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 6eeddc28512d9..0cb16b19d7326 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -416,7 +416,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
 
 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
     unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
-        poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock: lock, poison: guard })
+        poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock, poison: guard })
     }
 }
 
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index fdd29af858185..50f54dbf14306 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -465,16 +465,13 @@ impl<T> From<T> for RwLock<T> {
 
 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
     unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
-        poison::map_result(lock.poison.borrow(), |_| RwLockReadGuard { lock: lock })
+        poison::map_result(lock.poison.borrow(), |_| RwLockReadGuard { lock })
     }
 }
 
 impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
     unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
-        poison::map_result(lock.poison.borrow(), |guard| RwLockWriteGuard {
-            lock: lock,
-            poison: guard,
-        })
+        poison::map_result(lock.poison.borrow(), |guard| RwLockWriteGuard { lock, poison: guard })
     }
 }
 
diff --git a/src/test/ui/blind/blind-item-block-middle.stderr b/src/test/ui/blind/blind-item-block-middle.stderr
index 264e7fc8e73a2..d8d15615d7c33 100644
--- a/src/test/ui/blind/blind-item-block-middle.stderr
+++ b/src/test/ui/blind/blind-item-block-middle.stderr
@@ -1,8 +1,15 @@
 error[E0308]: mismatched types
   --> $DIR/blind-item-block-middle.rs:6:9
    |
+LL | mod foo { pub struct bar; }
+   |           --------------- unit struct defined here
+...
 LL |     let bar = 5;
-   |         ^^^ expected integer, found struct `foo::bar`
+   |         ^^^
+   |         |
+   |         expected integer, found struct `foo::bar`
+   |         `bar` is interpreted as a unit struct, not a new binding
+   |         help: introduce a new binding instead: `other_bar`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/auxiliary/issue-69725.rs b/src/test/ui/issues/auxiliary/issue-69725.rs
new file mode 100644
index 0000000000000..13606e498ef7d
--- /dev/null
+++ b/src/test/ui/issues/auxiliary/issue-69725.rs
@@ -0,0 +1,8 @@
+#[derive(Clone)]
+pub struct Struct<A>(A);
+
+impl<A> Struct<A> {
+    pub fn new() -> Self {
+        todo!()
+    }
+}
diff --git a/src/test/ui/issues/issue-33504.stderr b/src/test/ui/issues/issue-33504.stderr
index 522df6a07c2c6..1e61178f42edb 100644
--- a/src/test/ui/issues/issue-33504.stderr
+++ b/src/test/ui/issues/issue-33504.stderr
@@ -1,8 +1,15 @@
 error[E0308]: mismatched types
   --> $DIR/issue-33504.rs:7:13
    |
+LL | struct Test;
+   | ------------ unit struct defined here
+...
 LL |         let Test = 1;
-   |             ^^^^ expected integer, found struct `Test`
+   |             ^^^^
+   |             |
+   |             expected integer, found struct `Test`
+   |             `Test` is interpreted as a unit struct, not a new binding
+   |             help: introduce a new binding instead: `other_test`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-4968.stderr b/src/test/ui/issues/issue-4968.stderr
index 35435d0e61819..5451cf423559e 100644
--- a/src/test/ui/issues/issue-4968.stderr
+++ b/src/test/ui/issues/issue-4968.stderr
@@ -1,8 +1,15 @@
 error[E0308]: mismatched types
   --> $DIR/issue-4968.rs:5:16
    |
+LL | const A: (isize,isize) = (4,2);
+   | ------------------------------- constant defined here
+LL | fn main() {
 LL |     match 42 { A => () }
-   |                ^ expected integer, found tuple
+   |                ^
+   |                |
+   |                expected integer, found tuple
+   |                `A` is interpreted as a constant, not a new binding
+   |                help: introduce a new binding instead: `other_a`
    |
    = note: expected type `{integer}`
              found tuple `(isize, isize)`
diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr
index c81d6dcaf0217..a89980964ca0a 100644
--- a/src/test/ui/issues/issue-5100.stderr
+++ b/src/test/ui/issues/issue-5100.stderr
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/issue-5100.rs:8:9
    |
+LL | enum A { B, C }
+   |          - unit variant defined here
+...
 LL |     match (true, false) {
    |           ------------- this expression has type `(bool, bool)`
 LL |         A::B => (),
diff --git a/src/test/ui/issues/issue-69725.rs b/src/test/ui/issues/issue-69725.rs
new file mode 100644
index 0000000000000..b8130b41f2167
--- /dev/null
+++ b/src/test/ui/issues/issue-69725.rs
@@ -0,0 +1,11 @@
+// aux-build:issue-69725.rs
+
+extern crate issue_69725;
+use issue_69725::Struct;
+
+fn crash<A>() {
+    let _ = Struct::<A>::new().clone();
+    //~^ ERROR: no method named `clone` found
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr
new file mode 100644
index 0000000000000..667383e072a54
--- /dev/null
+++ b/src/test/ui/issues/issue-69725.stderr
@@ -0,0 +1,18 @@
+error[E0599]: no method named `clone` found for struct `issue_69725::Struct<A>` in the current scope
+  --> $DIR/issue-69725.rs:7:32
+   |
+LL |     let _ = Struct::<A>::new().clone();
+   |                                ^^^^^ method not found in `issue_69725::Struct<A>`
+   | 
+  ::: $DIR/auxiliary/issue-69725.rs:2:1
+   |
+LL | pub struct Struct<A>(A);
+   | ------------------------ doesn't satisfy `issue_69725::Struct<A>: std::clone::Clone`
+   |
+   = note: the method `clone` exists but the following trait bounds were not satisfied:
+           `A: std::clone::Clone`
+           which is required by `issue_69725::Struct<A>: std::clone::Clone`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-7867.stderr b/src/test/ui/issues/issue-7867.stderr
index 4a29464aebd2b..0d3121d60455d 100644
--- a/src/test/ui/issues/issue-7867.stderr
+++ b/src/test/ui/issues/issue-7867.stderr
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/issue-7867.rs:7:9
    |
+LL | enum A { B, C }
+   |          - unit variant defined here
+...
 LL |     match (true, false) {
    |           ------------- this expression has type `(bool, bool)`
 LL |         A::B => (),
diff --git a/src/test/ui/match/match-tag-nullary.stderr b/src/test/ui/match/match-tag-nullary.stderr
index 3703a59edb836..723c7fa92b10d 100644
--- a/src/test/ui/match/match-tag-nullary.stderr
+++ b/src/test/ui/match/match-tag-nullary.stderr
@@ -1,6 +1,9 @@
 error[E0308]: mismatched types
   --> $DIR/match-tag-nullary.rs:4:40
    |
+LL | enum B { B }
+   |          - unit variant defined here
+LL | 
 LL | fn main() { let x: A = A::A; match x { B::B => { } } }
    |                                    -   ^^^^ expected enum `A`, found enum `B`
    |                                    |
diff --git a/src/test/ui/or-patterns/box-patterns.rs b/src/test/ui/or-patterns/box-patterns.rs
new file mode 100644
index 0000000000000..aafd47993836c
--- /dev/null
+++ b/src/test/ui/or-patterns/box-patterns.rs
@@ -0,0 +1,37 @@
+// Test or-patterns with box-patterns
+
+// run-pass
+
+#![feature(or_patterns)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(x: Option<Box<Test>>) -> MatchArm {
+    match x {
+        Some(box Test::Foo | box Test::Bar) => MatchArm::Arm(0),
+        Some(box Test::Baz) => MatchArm::Arm(1),
+        Some(_) => MatchArm::Arm(2),
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1));
+    assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(2));
+    assert_eq!(test(None), MatchArm::Wild);
+}
diff --git a/src/test/ui/or-patterns/slice-patterns.rs b/src/test/ui/or-patterns/slice-patterns.rs
new file mode 100644
index 0000000000000..05c907e824679
--- /dev/null
+++ b/src/test/ui/or-patterns/slice-patterns.rs
@@ -0,0 +1,53 @@
+// Test or-patterns with slice-patterns
+
+// run-pass
+
+#![feature(or_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(foo: &[Option<Test>]) -> MatchArm {
+    match foo {
+        [.., Some(Test::Qux | Test::Foo)] => MatchArm::Arm(0),
+        [Some(Test::Foo), .., Some(Test::Baz | Test::Bar)] => MatchArm::Arm(1),
+        [.., Some(Test::Bar | Test::Baz), _] => MatchArm::Arm(2),
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    let foo = vec![
+        Some(Test::Foo),
+        Some(Test::Bar),
+        Some(Test::Baz),
+        Some(Test::Qux),
+    ];
+
+    // path 1a
+    assert_eq!(test(&foo), MatchArm::Arm(0));
+    // path 1b
+    assert_eq!(test(&[Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0));
+    // path 2a
+    assert_eq!(test(&foo[..3]), MatchArm::Arm(1));
+    // path 2b
+    assert_eq!(test(&[Some(Test::Foo), Some(Test::Foo), Some(Test::Bar)]), MatchArm::Arm(1));
+    // path 3a
+    assert_eq!(test(&foo[1..3]), MatchArm::Arm(2));
+    // path 3b
+    assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]),
+        MatchArm::Arm(2));
+    // path 4
+    assert_eq!(test(&foo[4..]), MatchArm::Wild);
+}
diff --git a/src/test/ui/parser/issue-35813-postfix-after-cast.rs b/src/test/ui/parser/issue-35813-postfix-after-cast.rs
new file mode 100644
index 0000000000000..e725aa5d73d1f
--- /dev/null
+++ b/src/test/ui/parser/issue-35813-postfix-after-cast.rs
@@ -0,0 +1,171 @@
+// edition:2018
+#![crate_type = "lib"]
+#![feature(type_ascription)]
+use std::future::Future;
+use std::pin::Pin;
+
+// This tests the parser for "x as Y[z]". It errors, but we want to give useful
+// errors and parse such that further code gives useful errors.
+pub fn index_after_as_cast() {
+    vec![1, 2, 3] as Vec<i32>[0];
+    //~^ ERROR: casts cannot be followed by indexing
+    vec![1, 2, 3]: Vec<i32>[0];
+    //~^ ERROR: casts cannot be followed by indexing
+}
+
+pub fn index_after_cast_to_index() {
+    (&[0]) as &[i32][0];
+    //~^ ERROR: casts cannot be followed by indexing
+    (&[0i32]): &[i32; 1][0];
+    //~^ ERROR: casts cannot be followed by indexing
+}
+
+pub fn cast_after_cast() {
+    if 5u64 as i32 as u16 == 0u16 {
+
+    }
+    if 5u64: u64: u64 == 0u64 {
+
+    }
+    let _ = 5u64: u64: u64 as u8 as i8 == 9i8;
+    let _ = 0i32: i32: i32;
+    let _ = 0 as i32: i32;
+    let _ = 0i32: i32 as i32;
+    let _ = 0 as i32 as i32;
+    let _ = 0i32: i32: i32 as u32 as i32;
+}
+
+pub fn cast_cast_method_call() {
+    let _ = 0i32: i32: i32.count_ones();
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0 as i32: i32.count_ones();
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0i32: i32 as i32.count_ones();
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0 as i32 as i32.count_ones();
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0i32: i32: i32 as u32 as i32.count_ones();
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0i32: i32.count_ones(): u32;
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0 as i32.count_ones(): u32;
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0i32: i32.count_ones() as u32;
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0 as i32.count_ones() as u32;
+    //~^ ERROR: casts cannot be followed by a method call
+    let _ = 0i32: i32: i32.count_ones() as u32 as i32;
+    //~^ ERROR: casts cannot be followed by a method call
+}
+
+pub fn multiline_error() {
+    let _ = 0
+        as i32
+        .count_ones();
+    //~^^^ ERROR: casts cannot be followed by a method call
+}
+
+// this tests that the precedence for `!x as Y.Z` is still what we expect
+pub fn precedence() {
+    let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0];
+    //~^ ERROR: casts cannot be followed by indexing
+}
+
+pub fn method_calls() {
+    0 as i32.max(0);
+    //~^ ERROR: casts cannot be followed by a method call
+    0: i32.max(0);
+    //~^ ERROR: casts cannot be followed by a method call
+}
+
+pub fn complex() {
+    let _ = format!(
+        "{} and {}",
+        if true { 33 } else { 44 } as i32.max(0),
+        //~^ ERROR: casts cannot be followed by a method call
+        if true { 33 } else { 44 }: i32.max(0)
+        //~^ ERROR: casts cannot be followed by a method call
+    );
+}
+
+pub fn in_condition() {
+    if 5u64 as i32.max(0) == 0 {
+        //~^ ERROR: casts cannot be followed by a method call
+    }
+    if 5u64: u64.max(0) == 0 {
+        //~^ ERROR: casts cannot be followed by a method call
+    }
+}
+
+pub fn inside_block() {
+    let _ = if true {
+        5u64 as u32.max(0) == 0
+        //~^ ERROR: casts cannot be followed by a method call
+    } else { false };
+    let _ = if true {
+        5u64: u64.max(0) == 0
+        //~^ ERROR: casts cannot be followed by a method call
+    } else { false };
+}
+
+static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
+//~^ ERROR: casts cannot be followed by indexing
+
+static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
+//~^ ERROR: casts cannot be followed by indexing
+
+
+pub fn cast_then_try() -> Result<u64,u64> {
+    Err(0u64) as Result<u64,u64>?;
+    //~^ ERROR: casts cannot be followed by ?
+    Err(0u64): Result<u64,u64>?;
+    //~^ ERROR: casts cannot be followed by ?
+    Ok(1)
+}
+
+
+pub fn cast_then_call() {
+    type F = fn(u8);
+    // type ascription won't actually do [unique drop fn type] -> fn(u8) casts.
+    let drop_ptr = drop as fn(u8);
+    drop as F();
+    //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
+    drop_ptr: F();
+    //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait [E0214]
+}
+
+pub fn cast_to_fn_should_work() {
+    let drop_ptr = drop as fn(u8);
+    drop as fn(u8);
+    drop_ptr: fn(u8);
+}
+
+pub fn parens_after_cast_error() {
+    let drop_ptr = drop as fn(u8);
+    drop as fn(u8)(0);
+    //~^ ERROR: casts cannot be followed by a function call
+    drop_ptr: fn(u8)(0);
+    //~^ ERROR: casts cannot be followed by a function call
+}
+
+pub async fn cast_then_await() {
+    Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
+    //~^ ERROR: casts cannot be followed by `.await`
+
+    Box::pin(noop()): Pin<Box<_>>.await;
+    //~^ ERROR: casts cannot be followed by `.await`
+}
+
+pub async fn noop() {}
+
+#[derive(Default)]
+pub struct Foo {
+    pub bar: u32,
+}
+
+pub fn struct_field() {
+    Foo::default() as Foo.bar;
+    //~^ ERROR: cannot be followed by a field access
+    Foo::default(): Foo.bar;
+    //~^ ERROR: cannot be followed by a field access
+}
diff --git a/src/test/ui/parser/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr
new file mode 100644
index 0000000000000..255e9f409218b
--- /dev/null
+++ b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr
@@ -0,0 +1,392 @@
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:10:5
+   |
+LL |     vec![1, 2, 3] as Vec<i32>[0];
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (vec![1, 2, 3] as Vec<i32>)[0];
+   |     ^                         ^
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:12:5
+   |
+LL |     vec![1, 2, 3]: Vec<i32>[0];
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (vec![1, 2, 3]: Vec<i32>)[0];
+   |     ^                       ^
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:17:5
+   |
+LL |     (&[0]) as &[i32][0];
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     ((&[0]) as &[i32])[0];
+   |     ^                ^
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:19:5
+   |
+LL |     (&[0i32]): &[i32; 1][0];
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     ((&[0i32]): &[i32; 1])[0];
+   |     ^                    ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:39:13
+   |
+LL |     let _ = 0i32: i32: i32.count_ones();
+   |             ^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32: i32).count_ones();
+   |             ^              ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:41:13
+   |
+LL |     let _ = 0 as i32: i32.count_ones();
+   |             ^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0 as i32: i32).count_ones();
+   |             ^             ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:43:13
+   |
+LL |     let _ = 0i32: i32 as i32.count_ones();
+   |             ^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32 as i32).count_ones();
+   |             ^                ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:45:13
+   |
+LL |     let _ = 0 as i32 as i32.count_ones();
+   |             ^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0 as i32 as i32).count_ones();
+   |             ^               ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:47:13
+   |
+LL |     let _ = 0i32: i32: i32 as u32 as i32.count_ones();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32: i32 as u32 as i32).count_ones();
+   |             ^                            ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:49:13
+   |
+LL |     let _ = 0i32: i32.count_ones(): u32;
+   |             ^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32).count_ones(): u32;
+   |             ^         ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:51:13
+   |
+LL |     let _ = 0 as i32.count_ones(): u32;
+   |             ^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0 as i32).count_ones(): u32;
+   |             ^        ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:53:13
+   |
+LL |     let _ = 0i32: i32.count_ones() as u32;
+   |             ^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32).count_ones() as u32;
+   |             ^         ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:55:13
+   |
+LL |     let _ = 0 as i32.count_ones() as u32;
+   |             ^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0 as i32).count_ones() as u32;
+   |             ^        ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:57:13
+   |
+LL |     let _ = 0i32: i32: i32.count_ones() as u32 as i32;
+   |             ^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0i32: i32: i32).count_ones() as u32 as i32;
+   |             ^              ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:62:13
+   |
+LL |       let _ = 0
+   |  _____________^
+LL | |         as i32
+   | |______________^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let _ = (0
+LL |         as i32)
+   |
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:70:18
+   |
+LL |     let x: i32 = &vec![1, 2, 3] as &Vec<i32>[0];
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     let x: i32 = (&vec![1, 2, 3] as &Vec<i32>)[0];
+   |                  ^                           ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:75:5
+   |
+LL |     0 as i32.max(0);
+   |     ^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (0 as i32).max(0);
+   |     ^        ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:77:5
+   |
+LL |     0: i32.max(0);
+   |     ^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (0: i32).max(0);
+   |     ^      ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:92:8
+   |
+LL |     if 5u64 as i32.max(0) == 0 {
+   |        ^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     if (5u64 as i32).max(0) == 0 {
+   |        ^           ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:95:8
+   |
+LL |     if 5u64: u64.max(0) == 0 {
+   |        ^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     if (5u64: u64).max(0) == 0 {
+   |        ^         ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:102:9
+   |
+LL |         5u64 as u32.max(0) == 0
+   |         ^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |         (5u64 as u32).max(0) == 0
+   |         ^           ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:106:9
+   |
+LL |         5u64: u64.max(0) == 0
+   |         ^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |         (5u64: u64).max(0) == 0
+   |         ^         ^
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:111:24
+   |
+LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
+   |                        ^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]);
+   |                        ^                  ^
+
+error: casts cannot be followed by indexing
+  --> $DIR/issue-35813-postfix-after-cast.rs:114:25
+   |
+LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
+   |                         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]);
+   |                         ^                      ^
+
+error: casts cannot be followed by ?
+  --> $DIR/issue-35813-postfix-after-cast.rs:119:5
+   |
+LL |     Err(0u64) as Result<u64,u64>?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (Err(0u64) as Result<u64,u64>)?;
+   |     ^                            ^
+
+error: casts cannot be followed by ?
+  --> $DIR/issue-35813-postfix-after-cast.rs:121:5
+   |
+LL |     Err(0u64): Result<u64,u64>?;
+   |     ^^^^^^^^^-^^^^^^^^^^^^^^^^
+   |              |
+   |              help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+
+error: casts cannot be followed by a function call
+  --> $DIR/issue-35813-postfix-after-cast.rs:145:5
+   |
+LL |     drop as fn(u8)(0);
+   |     ^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (drop as fn(u8))(0);
+   |     ^              ^
+
+error: casts cannot be followed by a function call
+  --> $DIR/issue-35813-postfix-after-cast.rs:147:5
+   |
+LL |     drop_ptr: fn(u8)(0);
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (drop_ptr: fn(u8))(0);
+   |     ^                ^
+
+error: casts cannot be followed by `.await`
+  --> $DIR/issue-35813-postfix-after-cast.rs:152:5
+   |
+LL |     Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await;
+   |     ^                                                     ^
+
+error: casts cannot be followed by `.await`
+  --> $DIR/issue-35813-postfix-after-cast.rs:155:5
+   |
+LL |     Box::pin(noop()): Pin<Box<_>>.await;
+   |     ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^
+   |                     |
+   |                     help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+
+error: casts cannot be followed by a field access
+  --> $DIR/issue-35813-postfix-after-cast.rs:167:5
+   |
+LL |     Foo::default() as Foo.bar;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (Foo::default() as Foo).bar;
+   |     ^                     ^
+
+error: casts cannot be followed by a field access
+  --> $DIR/issue-35813-postfix-after-cast.rs:169:5
+   |
+LL |     Foo::default(): Foo.bar;
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (Foo::default(): Foo).bar;
+   |     ^                   ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:84:9
+   |
+LL |         if true { 33 } else { 44 } as i32.max(0),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |         (if true { 33 } else { 44 } as i32).max(0),
+   |         ^                                 ^
+
+error: casts cannot be followed by a method call
+  --> $DIR/issue-35813-postfix-after-cast.rs:86:9
+   |
+LL |         if true { 33 } else { 44 }: i32.max(0)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |         (if true { 33 } else { 44 }: i32).max(0)
+   |         ^                               ^
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-35813-postfix-after-cast.rs:131:13
+   |
+LL |     drop as F();
+   |             ^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-35813-postfix-after-cast.rs:133:15
+   |
+LL |     drop_ptr: F();
+   |               ^^^ only `Fn` traits may use parentheses
+
+error: aborting due to 36 previous errors
+
+For more information about this error, try `rustc --explain E0214`.
diff --git a/src/test/ui/pattern/bindings-after-at/box-patterns.rs b/src/test/ui/pattern/bindings-after-at/box-patterns.rs
new file mode 100644
index 0000000000000..ef9669a6b9e5a
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/box-patterns.rs
@@ -0,0 +1,36 @@
+// Test bindings-after-at with box-patterns
+
+// run-pass
+
+#![feature(bindings_after_at)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+fn test(x: Option<Box<i32>>) -> MatchArm {
+    match x {
+        ref bar @ Some(box n) if n > 0 => {
+            // bar is a &Option<Box<i32>>
+            assert_eq!(bar, &x);
+
+            MatchArm::Arm(0)
+        },
+        Some(ref bar @ box n) if n < 0 => {
+            // bar is a &Box<i32> here
+            assert_eq!(**bar, n);
+
+            MatchArm::Arm(1)
+        },
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    assert_eq!(test(Some(Box::new(2))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(-1))), MatchArm::Arm(1));
+    assert_eq!(test(Some(Box::new(0))), MatchArm::Wild);
+}
diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs
new file mode 100644
index 0000000000000..ca8826f03f1ad
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs
@@ -0,0 +1,45 @@
+// Test bindings-after-at with or-patterns and box-patterns
+
+// run-pass
+
+#![feature(bindings_after_at)]
+#![feature(or_patterns)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug, PartialEq)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(foo: Option<Box<Test>>) -> MatchArm {
+    match foo {
+        ref bar @ Some(box Test::Foo | box Test::Bar) => {
+            assert_eq!(bar, &foo);
+
+            MatchArm::Arm(0)
+        },
+        Some(ref bar @ box Test::Baz | ref bar @ box Test::Qux) => {
+            assert!(**bar == Test::Baz || **bar == Test::Qux);
+
+            MatchArm::Arm(1)
+        },
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1));
+    assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(1));
+    assert_eq!(test(None), MatchArm::Wild);
+}
diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs
new file mode 100644
index 0000000000000..65c2b3741b3e3
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs
@@ -0,0 +1,56 @@
+// Test bindings-after-at with or-patterns and slice-patterns
+
+// run-pass
+
+#![feature(bindings_after_at)]
+#![feature(or_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug, PartialEq)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(foo: &[Option<Test>]) -> MatchArm {
+    match foo {
+        bar @ [Some(Test::Foo), .., Some(Test::Qux | Test::Foo)] => {
+            assert_eq!(bar, foo);
+
+            MatchArm::Arm(0)
+        },
+        [.., bar @ Some(Test::Bar | Test::Qux), _] => {
+            assert!(bar == &Some(Test::Bar) || bar == &Some(Test::Qux));
+
+            MatchArm::Arm(1)
+        },
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    let foo = vec![
+        Some(Test::Foo),
+        Some(Test::Bar),
+        Some(Test::Baz),
+        Some(Test::Qux),
+    ];
+
+    // path 1a
+    assert_eq!(test(&foo), MatchArm::Arm(0));
+    // path 1b
+    assert_eq!(test(&[Some(Test::Foo), Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0));
+    // path 2a
+    assert_eq!(test(&foo[..3]), MatchArm::Arm(1));
+    // path 2b
+    assert_eq!(test(&[Some(Test::Bar), Some(Test::Qux), Some(Test::Baz)]), MatchArm::Arm(1));
+    // path 3
+    assert_eq!(test(&foo[1..2]), MatchArm::Wild);
+}
diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns.rs
new file mode 100644
index 0000000000000..a0e14004ab1b0
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/or-patterns.rs
@@ -0,0 +1,40 @@
+// Test bindings-after-at with or-patterns
+
+// run-pass
+
+#![feature(bindings_after_at)]
+#![feature(or_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(foo: Option<Test>) -> MatchArm {
+    match foo {
+        bar @ Some(Test::Foo | Test::Bar) => {
+            assert!(bar == Some(Test::Foo) || bar == Some(Test::Bar));
+
+            MatchArm::Arm(0)
+        },
+        Some(_) => MatchArm::Arm(1),
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    assert_eq!(test(Some(Test::Foo)), MatchArm::Arm(0));
+    assert_eq!(test(Some(Test::Bar)), MatchArm::Arm(0));
+    assert_eq!(test(Some(Test::Baz)), MatchArm::Arm(1));
+    assert_eq!(test(Some(Test::Qux)), MatchArm::Arm(1));
+    assert_eq!(test(None), MatchArm::Wild);
+}
diff --git a/src/test/ui/pattern/bindings-after-at/slice-patterns.rs b/src/test/ui/pattern/bindings-after-at/slice-patterns.rs
new file mode 100644
index 0000000000000..7e50527af0b97
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/slice-patterns.rs
@@ -0,0 +1,40 @@
+// Test bindings-after-at with slice-patterns
+
+// run-pass
+
+#![feature(bindings_after_at)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+fn test(foo: &[i32]) -> MatchArm {
+    match foo {
+        [bar @ .., n] if n == &5 => {
+            for i in bar {
+                assert!(i < &5);
+            }
+
+            MatchArm::Arm(0)
+        },
+        bar @ [x0, .., xn] => {
+            assert_eq!(x0, &1);
+            assert_eq!(x0, &1);
+            assert_eq!(xn, &4);
+            assert_eq!(bar, &[1, 2, 3, 4]);
+
+            MatchArm::Arm(1)
+        },
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    let foo = vec![1, 2, 3, 4, 5];
+
+    assert_eq!(test(&foo), MatchArm::Arm(0));
+    assert_eq!(test(&foo[..4]), MatchArm::Arm(1));
+    assert_eq!(test(&foo[0..1]), MatchArm::Wild);
+}
diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr
index 27efd450b9471..10d30ec1a1b18 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr
@@ -1,10 +1,17 @@
 error[E0308]: mismatched types
   --> $DIR/const.rs:14:9
    |
+LL | const FOO: Foo = Foo{bar: 5};
+   | ----------------------------- constant defined here
+...
 LL |     match &f {
    |           -- this expression has type `&Foo`
 LL |         FOO => {},
-   |         ^^^ expected `&Foo`, found struct `Foo`
+   |         ^^^
+   |         |
+   |         expected `&Foo`, found struct `Foo`
+   |         `FOO` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/const-in-struct-pat.rs b/src/test/ui/suggestions/const-in-struct-pat.rs
new file mode 100644
index 0000000000000..1cbba935402a9
--- /dev/null
+++ b/src/test/ui/suggestions/const-in-struct-pat.rs
@@ -0,0 +1,11 @@
+#[allow(non_camel_case_types)]
+struct foo;
+struct Thing {
+    foo: String,
+}
+
+fn example(t: Thing) {
+    let Thing { foo } = t; //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/const-in-struct-pat.stderr b/src/test/ui/suggestions/const-in-struct-pat.stderr
new file mode 100644
index 0000000000000..0a010dcab4c26
--- /dev/null
+++ b/src/test/ui/suggestions/const-in-struct-pat.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/const-in-struct-pat.rs:8:17
+   |
+LL | struct foo;
+   | ----------- unit struct defined here
+...
+LL |     let Thing { foo } = t;
+   |                 ^^^     - this expression has type `Thing`
+   |                 |
+   |                 expected struct `std::string::String`, found struct `foo`
+   |                 `foo` is interpreted as a unit struct, not a new binding
+   |                 help: bind the struct field to a different name instead: `foo: other_foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs
index b53bfe5df03f3..8d6fd2abb6d5f 100644
--- a/src/test/ui/type/ascription/issue-54516.rs
+++ b/src/test/ui/type/ascription/issue-54516.rs
@@ -2,5 +2,7 @@ use std::collections::BTreeMap;
 
 fn main() {
     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-    //~^ ERROR expected one of
+    //~^ ERROR casts cannot be followed by a function call
+    //~| ERROR expected value, found module `std::mem` [E0423]
+    //~| ERROR cannot find type `size_of` in this scope [E0412]
 }
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
index 7127f67cd7dde..fdf35700ef94c 100644
--- a/src/test/ui/type/ascription/issue-54516.stderr
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -1,13 +1,31 @@
-error: expected one of `!`, `,`, or `::`, found `(`
-  --> $DIR/issue-54516.rs:4:58
+error: casts cannot be followed by a function call
+  --> $DIR/issue-54516.rs:4:20
    |
 LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-   |                            -                             ^ expected one of `!`, `,`, or `::`
+   |                    ^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                            |
    |                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
    = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
-error: aborting due to previous error
+error[E0423]: expected value, found module `std::mem`
+  --> $DIR/issue-54516.rs:4:20
+   |
+LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
+   |                    ^^^^^^^^- help: maybe you meant to write a path separator here: `::`
+   |                    |
+   |                    not a value
+
+error[E0412]: cannot find type `size_of` in this scope
+  --> $DIR/issue-54516.rs:4:29
+   |
+LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
+   |                            -^^^^^^^ not found in this scope
+   |                            |
+   |                            help: maybe you meant to write a path separator here: `::`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0412, E0423.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/type/ascription/issue-60933.rs b/src/test/ui/type/ascription/issue-60933.rs
index 8fb06c887bd3e..bcf9f88cb414b 100644
--- a/src/test/ui/type/ascription/issue-60933.rs
+++ b/src/test/ui/type/ascription/issue-60933.rs
@@ -1,4 +1,6 @@
 fn main() {
     let u: usize = std::mem:size_of::<u32>();
-    //~^ ERROR expected one of
+    //~^ ERROR casts cannot be followed by a function call
+    //~| ERROR expected value, found module `std::mem` [E0423]
+    //~| ERROR cannot find type `size_of` in this scope [E0412]
 }
diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr
index 7130767b6c6f3..cd9ae8f49f4f1 100644
--- a/src/test/ui/type/ascription/issue-60933.stderr
+++ b/src/test/ui/type/ascription/issue-60933.stderr
@@ -1,13 +1,31 @@
-error: expected one of `!`, `::`, or `;`, found `(`
-  --> $DIR/issue-60933.rs:2:43
+error: casts cannot be followed by a function call
+  --> $DIR/issue-60933.rs:2:20
    |
 LL |     let u: usize = std::mem:size_of::<u32>();
-   |                            -              ^ expected one of `!`, `::`, or `;`
+   |                    ^^^^^^^^-^^^^^^^^^^^^^^
    |                            |
    |                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
    = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
-error: aborting due to previous error
+error[E0423]: expected value, found module `std::mem`
+  --> $DIR/issue-60933.rs:2:20
+   |
+LL |     let u: usize = std::mem:size_of::<u32>();
+   |                    ^^^^^^^^- help: maybe you meant to write a path separator here: `::`
+   |                    |
+   |                    not a value
+
+error[E0412]: cannot find type `size_of` in this scope
+  --> $DIR/issue-60933.rs:2:29
+   |
+LL |     let u: usize = std::mem:size_of::<u32>();
+   |                            -^^^^^^^ not found in this scope
+   |                            |
+   |                            help: maybe you meant to write a path separator here: `::`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0412, E0423.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs
index be8508e3973a2..839d914baa954 100644
--- a/src/tools/unicode-table-generator/src/main.rs
+++ b/src/tools/unicode-table-generator/src/main.rs
@@ -147,7 +147,7 @@ fn main() {
         eprintln!("Must provide path to write unicode tables to");
         eprintln!(
             "e.g. {} src/libcore/unicode/unicode_data.rs",
-            std::env::args().nth(0).unwrap_or_default()
+            std::env::args().next().unwrap_or_default()
         );
         std::process::exit(1);
     });