diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index b94b8c87216..550c66e3d3b 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -75,12 +75,11 @@ impl NestedMetaItem {
     pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> {
         self.meta_item().and_then(|meta_item| {
             meta_item.meta_item_list().and_then(|meta_item_list| {
-                if meta_item_list.len() == 1 {
-                    if let Some(ident) = meta_item.ident() {
-                        if let Some(lit) = meta_item_list[0].literal() {
-                            return Some((ident.name, lit));
-                        }
-                    }
+                if meta_item_list.len() == 1
+                    && let Some(ident) = meta_item.ident()
+                    && let Some(lit) = meta_item_list[0].literal()
+                {
+                    return Some((ident.name, lit));
                 }
                 None
             })
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 21183121e15..538bfc21290 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -12,11 +12,12 @@
 #![feature(crate_visibility_modifier)]
 #![feature(if_let_guard)]
 #![feature(label_break_value)]
-#![feature(nll)]
+#![feature(let_chains)]
 #![feature(min_specialization)]
-#![recursion_limit = "256"]
+#![feature(nll)]
 #![feature(slice_internals)]
 #![feature(stmt_expr_attributes)]
+#![recursion_limit = "256"]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index db066d7c6a5..c367573de8a 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -504,10 +504,8 @@ impl Token {
 
     /// Returns `true` if the token is an interpolated path.
     fn is_path(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
-            if let NtPath(..) = **nt {
-                return true;
-            }
+        if let Interpolated(ref nt) = self.kind && let NtPath(..) = **nt {
+            return true;
         }
         false
     }
@@ -516,10 +514,10 @@ impl Token {
     /// That is, is this a pre-parsed expression dropped into the token stream
     /// (which happens while parsing the result of macro expansion)?
     pub fn is_whole_expr(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
-            if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt {
-                return true;
-            }
+        if let Interpolated(ref nt) = self.kind
+            && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt
+        {
+            return true;
         }
 
         false
@@ -527,10 +525,8 @@ impl Token {
 
     // Is the token an interpolated block (`$b:block`)?
     pub fn is_whole_block(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
-            if let NtBlock(..) = **nt {
-                return true;
-            }
+        if let Interpolated(ref nt) = self.kind && let NtBlock(..) = **nt {
+            return true;
         }
         false
     }
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 2174378a560..a67e7b1215b 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -497,42 +497,40 @@ impl TokenStreamBuilder {
 
         // If `self` is not empty and the last tree within the last stream is a
         // token tree marked with `Joint`...
-        if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() {
-            if let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last() {
-                // ...and `stream` is not empty and the first tree within it is
-                // a token tree...
-                let TokenStream(ref mut stream_lrc) = stream;
-                if let Some((TokenTree::Token(token), spacing)) = stream_lrc.first() {
-                    // ...and the two tokens can be glued together...
-                    if let Some(glued_tok) = last_token.glue(&token) {
-                        // ...then do so, by overwriting the last token
-                        // tree in `self` and removing the first token tree
-                        // from `stream`. This requires using `make_mut()`
-                        // on the last stream in `self` and on `stream`,
-                        // and in practice this doesn't cause cloning 99.9%
-                        // of the time.
+        if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut()
+            && let Some((TokenTree::Token(last_token), Spacing::Joint)) = last_stream_lrc.last()
+            // ...and `stream` is not empty and the first tree within it is
+            // a token tree...
+            && let TokenStream(ref mut stream_lrc) = stream
+            && let Some((TokenTree::Token(token), spacing)) = stream_lrc.first()
+            // ...and the two tokens can be glued together...
+            && let Some(glued_tok) = last_token.glue(&token)
+        {
+            // ...then do so, by overwriting the last token
+            // tree in `self` and removing the first token tree
+            // from `stream`. This requires using `make_mut()`
+            // on the last stream in `self` and on `stream`,
+            // and in practice this doesn't cause cloning 99.9%
+            // of the time.
 
-                        // Overwrite the last token tree with the merged
-                        // token.
-                        let last_vec_mut = Lrc::make_mut(last_stream_lrc);
-                        *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing);
+            // Overwrite the last token tree with the merged
+            // token.
+            let last_vec_mut = Lrc::make_mut(last_stream_lrc);
+            *last_vec_mut.last_mut().unwrap() = (TokenTree::Token(glued_tok), *spacing);
 
-                        // Remove the first token tree from `stream`. (This
-                        // is almost always the only tree in `stream`.)
-                        let stream_vec_mut = Lrc::make_mut(stream_lrc);
-                        stream_vec_mut.remove(0);
+            // Remove the first token tree from `stream`. (This
+            // is almost always the only tree in `stream`.)
+            let stream_vec_mut = Lrc::make_mut(stream_lrc);
+            stream_vec_mut.remove(0);
 
-                        // Don't push `stream` if it's empty -- that could
-                        // block subsequent token gluing, by getting
-                        // between two token trees that should be glued
-                        // together.
-                        if !stream.is_empty() {
-                            self.0.push(stream);
-                        }
-                        return;
-                    }
-                }
+            // Don't push `stream` if it's empty -- that could
+            // block subsequent token gluing, by getting
+            // between two token trees that should be glued
+            // together.
+            if !stream.is_empty() {
+                self.0.push(stream);
             }
+            return;
         }
         self.0.push(stream);
     }
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 224afbd553f..231dd72af2c 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -222,10 +222,10 @@ impl Lit {
             }
             token::Literal(lit) => lit,
             token::Interpolated(ref nt) => {
-                if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt {
-                    if let ast::ExprKind::Lit(lit) = &expr.kind {
-                        return Ok(lit.clone());
-                    }
+                if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt
+                    && let ast::ExprKind::Lit(lit) = &expr.kind
+                {
+                    return Ok(lit.clone());
                 }
                 return Err(LitError::NotLiteral);
             }