From fde1b76b4b1d0d84f5691f4785906b31bb91f38d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= <leseulartichaut@gmail.com>
Date: Mon, 16 Aug 2021 17:29:49 +0200
Subject: [PATCH 1/2] Use if-let guards in the codebase

---
 compiler/rustc_ast/src/attr/mod.rs            | 10 +--
 compiler/rustc_ast/src/lib.rs                 |  2 +
 compiler/rustc_errors/src/lib.rs              | 16 ++--
 compiler/rustc_expand/src/config.rs           | 15 ++--
 compiler/rustc_expand/src/lib.rs              |  2 +
 compiler/rustc_expand/src/module.rs           | 11 ++-
 .../rustc_expand/src/proc_macro_server.rs     | 23 ++---
 compiler/rustc_middle/src/lib.rs              |  2 +
 compiler/rustc_middle/src/ty/error.rs         | 30 +++----
 compiler/rustc_middle/src/ty/util.rs          | 10 +--
 compiler/rustc_parse/src/lib.rs               | 25 +++---
 .../rustc_parse/src/parser/nonterminal.rs     | 17 ++--
 compiler/rustc_parse/src/parser/stmt.rs       | 20 ++---
 compiler/rustc_parse/src/validate_attr.rs     | 17 ++--
 compiler/rustc_save_analysis/src/lib.rs       | 89 ++++++++++---------
 compiler/rustc_span/src/lib.rs                |  2 +
 compiler/rustc_span/src/source_map.rs         | 35 ++++----
 compiler/rustc_typeck/src/astconv/mod.rs      | 10 +--
 .../rustc_typeck/src/check/fn_ctxt/_impl.rs   | 12 +--
 .../rustc_typeck/src/check/method/probe.rs    | 50 +++++------
 compiler/rustc_typeck/src/check/pat.rs        | 29 +++---
 compiler/rustc_typeck/src/check/wfcheck.rs    | 34 ++++---
 compiler/rustc_typeck/src/check/writeback.rs  |  8 +-
 compiler/rustc_typeck/src/collect/type_of.rs  | 12 +--
 compiler/rustc_typeck/src/lib.rs              |  2 +
 library/core/src/lib.rs                       |  2 +
 library/core/src/num/dec2flt/mod.rs           |  9 +-
 27 files changed, 241 insertions(+), 253 deletions(-)

diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 41121d095f3ed..81195f7fb5cb2 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -564,11 +564,11 @@ impl NestedMetaItem {
         I: Iterator<Item = TokenTree>,
     {
         match tokens.peek() {
-            Some(TokenTree::Token(token)) => {
-                if let Ok(lit) = Lit::from_token(token) {
-                    tokens.next();
-                    return Some(NestedMetaItem::Literal(lit));
-                }
+            Some(TokenTree::Token(token))
+                if let Ok(lit) = Lit::from_token(token) =>
+            {
+                tokens.next();
+                return Some(NestedMetaItem::Literal(lit));
             }
             Some(TokenTree::Delimited(_, token::NoDelim, inner_tokens)) => {
                 let inner_tokens = inner_tokens.clone();
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 502bd69e6a9af..ef3f6035085d3 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -11,10 +11,12 @@
 #![feature(box_patterns)]
 #![cfg_attr(bootstrap, feature(const_fn_transmute))]
 #![feature(crate_visibility_modifier)]
+#![feature(if_let_guard)]
 #![feature(iter_zip)]
 #![feature(label_break_value)]
 #![feature(nll)]
 #![feature(min_specialization)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 #![recursion_limit = "256"]
 
 #[macro_use]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index a48d4fe8bb55a..02b6179f89503 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -5,9 +5,11 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(crate_visibility_modifier)]
 #![feature(backtrace)]
+#![feature(if_let_guard)]
 #![feature(format_args_capture)]
 #![feature(iter_zip)]
 #![feature(nll)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 
 #[macro_use]
 extern crate rustc_macros;
@@ -1027,15 +1029,15 @@ impl HandlerInner {
             let mut error_codes = self
                 .emitted_diagnostic_codes
                 .iter()
-                .filter_map(|x| match &x {
-                    DiagnosticId::Error(s) => {
-                        if let Ok(Some(_explanation)) = registry.try_find_description(s) {
-                            Some(s.clone())
-                        } else {
-                            None
-                        }
+                .filter_map(|x| {
+                    match &x {
+                    DiagnosticId::Error(s)
+                        if let Ok(Some(_explanation)) = registry.try_find_description(s) =>
+                    {
+                        Some(s.clone())
                     }
                     _ => None,
+                }
                 })
                 .collect::<Vec<_>>();
             if !error_codes.is_empty() {
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index e09893f7f3884..38c099fa4f59c 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -305,15 +305,14 @@ impl<'a> StripUnconfigured<'a> {
                     Some((AttrAnnotatedTokenTree::Delimited(sp, delim, inner), *spacing))
                         .into_iter()
                 }
+                AttrAnnotatedTokenTree::Token(ref token) if let TokenKind::Interpolated(ref nt) = token.kind => {
+                    panic!(
+                        "Nonterminal should have been flattened at {:?}: {:?}",
+                        token.span, nt
+                    );
+                }
                 AttrAnnotatedTokenTree::Token(token) => {
-                    if let TokenKind::Interpolated(nt) = token.kind {
-                        panic!(
-                            "Nonterminal should have been flattened at {:?}: {:?}",
-                            token.span, nt
-                        );
-                    } else {
-                        Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter()
-                    }
+                    Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter()
                 }
             })
             .collect();
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index efed41de23a89..f38f85a462688 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -2,11 +2,13 @@
 #![feature(decl_macro)]
 #![feature(destructuring_assignment)]
 #![feature(format_args_capture)]
+#![feature(if_let_guard)]
 #![feature(iter_zip)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
 #![feature(try_blocks)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 4d777049f0d62..60d653ac8b6f9 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -86,13 +86,12 @@ crate fn mod_dir_path(
     inline: Inline,
 ) -> (PathBuf, DirOwnership) {
     match inline {
+        Inline::Yes if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) => {
+            // For inline modules file path from `#[path]` is actually the directory path
+            // for historical reasons, so we don't pop the last segment here.
+            (file_path, DirOwnership::Owned { relative: None })
+        }
         Inline::Yes => {
-            if let Some(file_path) = mod_file_path_from_attr(sess, attrs, &module.dir_path) {
-                // For inline modules file path from `#[path]` is actually the directory path
-                // for historical reasons, so we don't pop the last segment here.
-                return (file_path, DirOwnership::Owned { relative: None });
-            }
-
             // We have to push on the current module name in the case of relative
             // paths in order to ensure that any additional module paths from inline
             // `mod x { ... }` come after the relative extension.
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 42ae8e972c274..55700f7b0d495 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -178,18 +178,19 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)>
                 tt!(Punct::new('#', false))
             }
 
+            Interpolated(nt)
+                if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) =>
+            {
+                TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span))
+            }
             Interpolated(nt) => {
-                if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) {
-                    TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span))
-                } else {
-                    let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No);
-                    TokenTree::Group(Group {
-                        delimiter: Delimiter::None,
-                        stream,
-                        span: DelimSpan::from_single(span),
-                        flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess),
-                    })
-                }
+                let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No);
+                TokenTree::Group(Group {
+                    delimiter: Delimiter::None,
+                    stream,
+                    span: DelimSpan::from_single(span),
+                    flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess),
+                })
             }
 
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 0e72e916cc6ac..573fa913d680a 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -31,6 +31,7 @@
 #![feature(box_patterns)]
 #![feature(core_intrinsics)]
 #![feature(discriminant_kind)]
+#![feature(if_let_guard)]
 #![feature(never_type)]
 #![feature(extern_types)]
 #![feature(new_uninit)]
@@ -52,6 +53,7 @@
 #![feature(try_reserve)]
 #![feature(try_reserve_kind)]
 #![feature(nonzero_ops)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 #![recursion_limit = "512"]
 
 #[macro_use]
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 1aa6c84dbc414..ecbe9ca417593 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -279,13 +279,10 @@ impl<'tcx> ty::TyS<'tcx> {
             }
             ty::FnDef(..) => "fn item".into(),
             ty::FnPtr(_) => "fn pointer".into(),
-            ty::Dynamic(ref inner, ..) => {
-                if let Some(principal) = inner.principal() {
-                    format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into()
-                } else {
-                    "trait object".into()
-                }
+            ty::Dynamic(ref inner, ..) if let Some(principal) = inner.principal() => {
+                format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into()
             }
+            ty::Dynamic(..) => "trait object".into(),
             ty::Closure(..) => "closure".into(),
             ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
             ty::GeneratorWitness(..) => "generator witness".into(),
@@ -365,20 +362,19 @@ impl<'tcx> TyCtxt<'tcx> {
                         // Issue #63167
                         db.note("distinct uses of `impl Trait` result in different opaque types");
                     }
-                    (ty::Float(_), ty::Infer(ty::IntVar(_))) => {
+                    (ty::Float(_), ty::Infer(ty::IntVar(_)))
                         if let Ok(
                             // Issue #53280
                             snippet,
-                        ) = self.sess.source_map().span_to_snippet(sp)
-                        {
-                            if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
-                                db.span_suggestion(
-                                    sp,
-                                    "use a float literal",
-                                    format!("{}.0", snippet),
-                                    MachineApplicable,
-                                );
-                            }
+                        ) = self.sess.source_map().span_to_snippet(sp) =>
+                    {
+                        if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
+                            db.span_suggestion(
+                                sp,
+                                "use a float literal",
+                                format!("{}.0", snippet),
+                                MachineApplicable,
+                            );
                         }
                     }
                     (ty::Param(expected), ty::Param(found)) => {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index a78206034f08a..1b8e94260b9b5 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -225,14 +225,12 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 }
 
-                ty::Tuple(tys) => {
-                    if let Some((&last_ty, _)) = tys.split_last() {
-                        ty = last_ty.expect_ty();
-                    } else {
-                        break;
-                    }
+                ty::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
+                    ty = last_ty.expect_ty();
                 }
 
+                ty::Tuple(_) => break,
+
                 ty::Projection(_) | ty::Opaque(..) => {
                     let normalized = normalize(ty);
                     if ty == normalized {
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 07f972c2fa897..73e05a35277ec 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -2,8 +2,10 @@
 
 #![feature(array_windows)]
 #![feature(crate_visibility_modifier)]
+#![feature(if_let_guard)]
 #![cfg_attr(bootstrap, feature(bindings_after_at))]
 #![feature(box_patterns)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 #![recursion_limit = "256"]
 
 use rustc_ast as ast;
@@ -262,20 +264,17 @@ pub fn nt_to_tokenstream(
     let tokens = match *nt {
         Nonterminal::NtItem(ref item) => prepend_attrs(&item.attrs, item.tokens.as_ref()),
         Nonterminal::NtBlock(ref block) => convert_tokens(block.tokens.as_ref()),
-        Nonterminal::NtStmt(ref stmt) => {
-            if let ast::StmtKind::Empty = stmt.kind {
-                let tokens = AttrAnnotatedTokenStream::new(vec![(
-                    tokenstream::AttrAnnotatedTokenTree::Token(Token::new(
-                        TokenKind::Semi,
-                        stmt.span,
-                    )),
-                    Spacing::Alone,
-                )]);
-                prepend_attrs(&stmt.attrs(), Some(&LazyTokenStream::new(tokens)))
-            } else {
-                prepend_attrs(&stmt.attrs(), stmt.tokens())
-            }
+        Nonterminal::NtStmt(ref stmt) if let ast::StmtKind::Empty = stmt.kind => {
+            let tokens = AttrAnnotatedTokenStream::new(vec![(
+                tokenstream::AttrAnnotatedTokenTree::Token(Token::new(
+                    TokenKind::Semi,
+                    stmt.span,
+                )),
+                Spacing::Alone,
+            )]);
+            prepend_attrs(&stmt.attrs(), Some(&LazyTokenStream::new(tokens)))
         }
+        Nonterminal::NtStmt(ref stmt) => prepend_attrs(&stmt.attrs(), stmt.tokens()),
         Nonterminal::NtPat(ref pat) => convert_tokens(pat.tokens.as_ref()),
         Nonterminal::NtTy(ref ty) => convert_tokens(ty.tokens.as_ref()),
         Nonterminal::NtIdent(ident, is_raw) => {
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 313d9db58fc3f..72e6f8a1bc857 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -143,15 +143,16 @@ impl<'a> Parser<'a> {
                 token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty())?)
             }
             // this could be handled like a token, since it is one
+            NonterminalKind::Ident
+                if let Some((ident, is_raw)) = get_macro_ident(&self.token) =>
+            {
+                self.bump();
+                token::NtIdent(ident, is_raw)
+            }
             NonterminalKind::Ident => {
-                if let Some((ident, is_raw)) = get_macro_ident(&self.token) {
-                    self.bump();
-                    token::NtIdent(ident, is_raw)
-                } else {
-                    let token_str = pprust::token_to_string(&self.token);
-                    let msg = &format!("expected ident, found {}", &token_str);
-                    return Err(self.struct_span_err(self.token.span, msg));
-                }
+                let token_str = pprust::token_to_string(&self.token);
+                let msg = &format!("expected ident, found {}", &token_str);
+                return Err(self.struct_span_err(self.token.span, msg));
             }
             NonterminalKind::Path => token::NtPath(
                 self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?,
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 9ef3f61ec346b..85515bd2a6314 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -493,21 +493,19 @@ impl<'a> Parser<'a> {
                 }
             }
             StmtKind::Expr(_) | StmtKind::MacCall(_) => {}
-            StmtKind::Local(ref mut local) => {
-                if let Err(e) = self.expect_semi() {
-                    // We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
-                    match &mut local.init {
-                        Some(ref mut expr) => {
-                            self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
-                            // We found `foo<bar, baz>`, have we fully recovered?
-                            self.expect_semi()?;
-                        }
-                        None => return Err(e),
+            StmtKind::Local(ref mut local) if let Err(e) = self.expect_semi() => {
+                // We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
+                match &mut local.init {
+                    Some(ref mut expr) => {
+                        self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
+                        // We found `foo<bar, baz>`, have we fully recovered?
+                        self.expect_semi()?;
                     }
+                    None => return Err(e),
                 }
                 eat_semi = false;
             }
-            StmtKind::Empty | StmtKind::Item(_) | StmtKind::Semi(_) => eat_semi = false,
+            StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false,
         }
 
         if eat_semi && self.eat(&token::Semi) {
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 21372725a6836..67695dc285092 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -24,16 +24,15 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
         Some((name, _, template, _)) if name != sym::rustc_dummy => {
             check_builtin_attribute(sess, attr, name, template)
         }
-        _ => {
-            if let MacArgs::Eq(..) = attr.get_normal_item().args {
-                // All key-value attributes are restricted to meta-item syntax.
-                parse_meta(sess, attr)
-                    .map_err(|mut err| {
-                        err.emit();
-                    })
-                    .ok();
-            }
+        _ if let MacArgs::Eq(..) = attr.get_normal_item().args => {
+            // All key-value attributes are restricted to meta-item syntax.
+            parse_meta(sess, attr)
+                .map_err(|mut err| {
+                    err.emit();
+                })
+                .ok();
         }
+        _ => {}
     }
 }
 
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 0a8a88132e33d..41d174cde0a8c 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -1,5 +1,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(if_let_guard)]
 #![feature(nll)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 #![recursion_limit = "256"]
 
 mod dump_visitor;
@@ -326,54 +328,53 @@ impl<'tcx> SaveContext<'tcx> {
                     attributes: lower_attributes(attrs.to_vec(), self),
                 }))
             }
-            hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) => {
-                if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind {
-                    // Common case impl for a struct or something basic.
-                    if generated_code(path.span) {
-                        return None;
-                    }
-                    let sub_span = path.segments.last().unwrap().ident.span;
-                    filter!(self.span_utils, sub_span);
+            hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. })
+                if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind =>
+            {
+                // Common case impl for a struct or something basic.
+                if generated_code(path.span) {
+                    return None;
+                }
+                let sub_span = path.segments.last().unwrap().ident.span;
+                filter!(self.span_utils, sub_span);
 
-                    let impl_id = self.next_impl_id();
-                    let span = self.span_from_span(sub_span);
+                let impl_id = self.next_impl_id();
+                let span = self.span_from_span(sub_span);
 
-                    let type_data = self.lookup_def_id(self_ty.hir_id);
-                    type_data.map(|type_data| {
-                        Data::RelationData(
-                            Relation {
-                                kind: RelationKind::Impl { id: impl_id },
-                                span: span.clone(),
-                                from: id_from_def_id(type_data),
-                                to: of_trait
-                                    .as_ref()
-                                    .and_then(|t| self.lookup_def_id(t.hir_ref_id))
-                                    .map(id_from_def_id)
-                                    .unwrap_or_else(null_id),
-                            },
-                            Impl {
-                                id: impl_id,
-                                kind: match *of_trait {
-                                    Some(_) => ImplKind::Direct,
-                                    None => ImplKind::Inherent,
-                                },
-                                span,
-                                value: String::new(),
-                                parent: None,
-                                children: items
-                                    .iter()
-                                    .map(|i| id_from_def_id(i.id.def_id.to_def_id()))
-                                    .collect(),
-                                docs: String::new(),
-                                sig: None,
-                                attributes: vec![],
+                let type_data = self.lookup_def_id(self_ty.hir_id);
+                type_data.map(|type_data| {
+                    Data::RelationData(
+                        Relation {
+                            kind: RelationKind::Impl { id: impl_id },
+                            span: span.clone(),
+                            from: id_from_def_id(type_data),
+                            to: of_trait
+                                .as_ref()
+                                .and_then(|t| self.lookup_def_id(t.hir_ref_id))
+                                .map(id_from_def_id)
+                                .unwrap_or_else(null_id),
+                        },
+                        Impl {
+                            id: impl_id,
+                            kind: match *of_trait {
+                                Some(_) => ImplKind::Direct,
+                                None => ImplKind::Inherent,
                             },
-                        )
-                    })
-                } else {
-                    None
-                }
+                            span,
+                            value: String::new(),
+                            parent: None,
+                            children: items
+                                .iter()
+                                .map(|i| id_from_def_id(i.id.def_id.to_def_id()))
+                                .collect(),
+                            docs: String::new(),
+                            sig: None,
+                            attributes: vec![],
+                        },
+                    )
+                })
             }
+            hir::ItemKind::Impl(_) => None,
             _ => {
                 // FIXME
                 bug!();
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9e127577b61a6..89e032b222fec 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -16,10 +16,12 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(array_windows)]
 #![feature(crate_visibility_modifier)]
+#![feature(if_let_guard)]
 #![feature(negative_impls)]
 #![feature(nll)]
 #![feature(min_specialization)]
 #![feature(thread_local_const_init)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index f700397fcdf0d..2c3af802be55a 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -982,15 +982,13 @@ impl SourceMap {
         None
     }
     pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
-        source_file.add_external_src(|| match source_file.name {
-            FileName::Real(ref name) => {
-                if let Some(local_path) = name.local_path() {
+        source_file.add_external_src(|| {
+            match source_file.name {
+                FileName::Real(ref name) if let Some(local_path) = name.local_path() => {
                     self.file_loader.read_file(local_path).ok()
-                } else {
-                    None
                 }
+                _ => None,
             }
-            _ => None,
         })
     }
 
@@ -1033,22 +1031,19 @@ impl FilePathMapping {
 
     fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
         match file {
-            FileName::Real(realfile) => {
-                if let RealFileName::LocalPath(local_path) = realfile {
-                    let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
-                    let realfile = if mapped {
-                        RealFileName::Remapped {
-                            local_path: Some(local_path.clone()),
-                            virtual_name: mapped_path,
-                        }
-                    } else {
-                        realfile.clone()
-                    };
-                    (FileName::Real(realfile), mapped)
+            FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => {
+                let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
+                let realfile = if mapped {
+                    RealFileName::Remapped {
+                        local_path: Some(local_path.clone()),
+                        virtual_name: mapped_path,
+                    }
                 } else {
-                    unreachable!("attempted to remap an already remapped filename");
-                }
+                    realfile.clone()
+                };
+                (FileName::Real(realfile), mapped)
             }
+            FileName::Real(_) => unreachable!("attempted to remap an already remapped filename"),
             other => (other.clone(), false),
         }
     }
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 7d7d69b40798f..606fd2812ecc7 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2380,12 +2380,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
                 // Our own parameters are the resolved lifetimes.
                 match param.kind {
-                    GenericParamDefKind::Lifetime => {
-                        if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] {
-                            self.ast_region_to_region(lifetime, None).into()
-                        } else {
-                            bug!()
-                        }
+                    GenericParamDefKind::Lifetime
+                        if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] =>
+                    {
+                        self.ast_region_to_region(lifetime, None).into()
                     }
                     _ => bug!(),
                 }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index f9b7bb8ea9915..dc0d8c0aeff2c 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1178,12 +1178,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut user_self_ty = None;
         let mut is_alias_variant_ctor = false;
         match res {
-            Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
-                if let Some(self_ty) = self_ty {
-                    let adt_def = self_ty.ty_adt_def().unwrap();
-                    user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
-                    is_alias_variant_ctor = true;
-                }
+            Res::Def(DefKind::Ctor(CtorOf::Variant, _), _)
+                if let Some(self_ty) = self_ty =>
+            {
+                let adt_def = self_ty.ty_adt_def().unwrap();
+                user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
+                is_alias_variant_ctor = true;
             }
             Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
                 let container = tcx.associated_item(def_id).container;
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 486e4d15d6580..1c7d68a3d57d4 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -616,32 +616,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         let lang_items = self.tcx.lang_items();
 
         match *self_ty.value.value.kind() {
-            ty::Dynamic(ref data, ..) => {
-                if let Some(p) = data.principal() {
-                    // Subtle: we can't use `instantiate_query_response` here: using it will
-                    // commit to all of the type equalities assumed by inference going through
-                    // autoderef (see the `method-probe-no-guessing` test).
-                    //
-                    // However, in this code, it is OK if we end up with an object type that is
-                    // "more general" than the object type that we are evaluating. For *every*
-                    // object type `MY_OBJECT`, a function call that goes through a trait-ref
-                    // of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
-                    // `ObjectCandidate`, and it should be discoverable "exactly" through one
-                    // of the iterations in the autoderef loop, so there is no problem with it
-                    // being discoverable in another one of these iterations.
-                    //
-                    // Using `instantiate_canonical_with_fresh_inference_vars` on our
-                    // `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
-                    // `CanonicalVarValues` will exactly give us such a generalization - it
-                    // will still match the original object type, but it won't pollute our
-                    // type variables in any form, so just do that!
-                    let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
-                        self.fcx
-                            .instantiate_canonical_with_fresh_inference_vars(self.span, &self_ty);
-
-                    self.assemble_inherent_candidates_from_object(generalized_self_ty);
-                    self.assemble_inherent_impl_candidates_for_type(p.def_id());
-                }
+            ty::Dynamic(ref data, ..) if let Some(p) = data.principal() => {
+                // Subtle: we can't use `instantiate_query_response` here: using it will
+                // commit to all of the type equalities assumed by inference going through
+                // autoderef (see the `method-probe-no-guessing` test).
+                //
+                // However, in this code, it is OK if we end up with an object type that is
+                // "more general" than the object type that we are evaluating. For *every*
+                // object type `MY_OBJECT`, a function call that goes through a trait-ref
+                // of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
+                // `ObjectCandidate`, and it should be discoverable "exactly" through one
+                // of the iterations in the autoderef loop, so there is no problem with it
+                // being discoverable in another one of these iterations.
+                //
+                // Using `instantiate_canonical_with_fresh_inference_vars` on our
+                // `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
+                // `CanonicalVarValues` will exactly give us such a generalization - it
+                // will still match the original object type, but it won't pollute our
+                // type variables in any form, so just do that!
+                let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
+                    self.fcx
+                        .instantiate_canonical_with_fresh_inference_vars(self.span, &self_ty);
+
+                self.assemble_inherent_candidates_from_object(generalized_self_ty);
+                self.assemble_inherent_impl_candidates_for_type(p.def_id());
             }
             ty::Adt(def, _) => {
                 self.assemble_inherent_impl_candidates_for_type(def.did);
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index dae574bb7bf0f..392262628c0c6 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -627,15 +627,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let binding_parent = tcx.hir().get(binding_parent_id);
             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
             match binding_parent {
-                hir::Node::Param(hir::Param { span, .. }) => {
-                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
-                        err.span_suggestion(
-                            *span,
-                            &format!("did you mean `{}`", snippet),
-                            format!(" &{}", expected),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                hir::Node::Param(hir::Param { span, .. })
+                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) =>
+                {
+                    err.span_suggestion(
+                        *span,
+                        &format!("did you mean `{}`", snippet),
+                        format!(" &{}", expected),
+                        Applicability::MachineApplicable,
+                    );
                 }
                 hir::Node::Arm(_) | hir::Node::Pat(_) => {
                     // rely on match ergonomics or it might be nested `&&pat`
@@ -1293,13 +1293,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             (Some(mut err), None) => {
                 err.emit();
             }
-            (None, None) => {
-                if let Some(mut err) =
-                    self.error_tuple_variant_index_shorthand(variant, pat, fields)
-                {
-                    err.emit();
-                }
+            (None, None) if let Some(mut err) =
+                    self.error_tuple_variant_index_shorthand(variant, pat, fields) =>
+            {
+                err.emit();
             }
+            (None, None) => {}
         }
         no_field_errors
     }
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index b824370965928..632b9492ee43a 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1049,26 +1049,24 @@ fn check_opaque_types<'fcx, 'tcx>(
                     let arg_is_param = match arg.unpack() {
                         GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
 
-                        GenericArgKind::Lifetime(region) => {
-                            if let ty::ReStatic = region {
-                                tcx.sess
-                                    .struct_span_err(
-                                        span,
-                                        "non-defining opaque type use in defining scope",
-                                    )
-                                    .span_label(
-                                        tcx.def_span(generics.param_at(i, tcx).def_id),
-                                        "cannot use static lifetime; use a bound lifetime \
-                                                 instead or remove the lifetime parameter from the \
-                                                 opaque type",
-                                    )
-                                    .emit();
-                                continue;
-                            }
-
-                            true
+                        GenericArgKind::Lifetime(region) if let ty::ReStatic = region => {
+                            tcx.sess
+                                .struct_span_err(
+                                    span,
+                                    "non-defining opaque type use in defining scope",
+                                )
+                                .span_label(
+                                    tcx.def_span(generics.param_at(i, tcx).def_id),
+                                    "cannot use static lifetime; use a bound lifetime \
+                                                instead or remove the lifetime parameter from the \
+                                                opaque type",
+                                )
+                                .emit();
+                            continue;
                         }
 
+                        GenericArgKind::Lifetime(_) => true,
+
                         GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
                     };
 
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index a13157b460828..2e59defdb7ba0 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -175,10 +175,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                                 }
                             }
                         }
-                        hir::ExprKind::AssignOp(..) => {
-                            if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) {
-                                a.pop();
-                            }
+                        hir::ExprKind::AssignOp(..)
+                            if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
+                        {
+                            a.pop();
                         }
                         _ => {}
                     }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index e63c3346e02b1..4048a54b58c98 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -446,13 +446,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             }
         }
 
-        Node::AnonConst(_) => {
-            if let Some(param) = tcx.opt_const_param_of(def_id) {
-                // We defer to `type_of` of the corresponding parameter
-                // for generic arguments.
-                return tcx.type_of(param);
-            }
+        Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
+            // We defer to `type_of` of the corresponding parameter
+            // for generic arguments.
+            tcx.type_of(param)
+        }
 
+        Node::AnonConst(_) => {
             let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
             match parent_node {
                 Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 61631f3b14bb1..638a46fec36f4 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -60,6 +60,7 @@ This API is completely unstable and subject to change.
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
 #![feature(format_args_capture)]
+#![feature(if_let_guard)]
 #![feature(in_band_lifetimes)]
 #![feature(is_sorted)]
 #![feature(iter_zip)]
@@ -68,6 +69,7 @@ This API is completely unstable and subject to change.
 #![feature(never_type)]
 #![feature(slice_partition_dedup)]
 #![feature(control_flow_enum)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 #![recursion_limit = "256"]
 
 #[macro_use]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index a4e57fd6a6db4..1a6d1aed2fd1e 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -69,6 +69,7 @@
 #![warn(missing_debug_implementations)]
 #![warn(missing_docs)]
 #![allow(explicit_outlives_requirements)]
+#![cfg_attr(bootstrap, allow(incomplete_features))] // if_let_guard
 //
 // Library features for const fns:
 #![feature(const_align_of_val)]
@@ -134,6 +135,7 @@
 #![feature(exhaustive_patterns)]
 #![feature(extern_types)]
 #![feature(fundamental)]
+#![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
 #![feature(intrinsics)]
 #![feature(lang_items)]
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index c78492f5ae2c9..2b280773e4c50 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -236,13 +236,8 @@ pub fn dec2flt<F: RawFloat>(s: &str) -> Result<F, ParseFloatError> {
 
     let num = match parse_number(s, negative) {
         Some(r) => r,
-        None => {
-            if let Some(value) = parse_inf_nan(s, negative) {
-                return Ok(value);
-            } else {
-                return Err(pfe_invalid());
-            }
-        }
+        None if let Some(value) = parse_inf_nan(s, negative) => return Ok(value),
+        None => return Err(pfe_invalid()),
     };
     if let Some(value) = num.try_fast_path::<F>() {
         return Ok(value);

From 2b0c8fff8a04dd995db0afaafba2ad9a5eff6fc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= <leseulartichaut@gmail.com>
Date: Mon, 16 Aug 2021 17:30:23 +0200
Subject: [PATCH 2/2] Various pattern cleanups

---
 compiler/rustc_ast/src/mut_visit.rs           |  7 +---
 compiler/rustc_ast/src/visit.rs               |  7 +---
 compiler/rustc_expand/src/lib.rs              |  1 +
 compiler/rustc_middle/src/mir/mod.rs          |  9 ++---
 compiler/rustc_middle/src/mir/visit.rs        | 17 ++++-----
 compiler/rustc_middle/src/thir.rs             | 16 ++------
 compiler/rustc_middle/src/ty/print/pretty.rs  | 38 ++++++++++---------
 compiler/rustc_typeck/src/check/expr.rs       |  9 ++---
 compiler/rustc_typeck/src/expr_use_visitor.rs | 11 ++----
 9 files changed, 47 insertions(+), 68 deletions(-)

diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index c824583118722..fb4db6005aca5 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1179,13 +1179,10 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
     for (op, _) in &mut asm.operands {
         match op {
             InlineAsmOperand::In { expr, .. }
+            | InlineAsmOperand::Out { expr: Some(expr), .. }
             | InlineAsmOperand::InOut { expr, .. }
             | InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr),
-            InlineAsmOperand::Out { expr, .. } => {
-                if let Some(expr) = expr {
-                    vis.visit_expr(expr);
-                }
-            }
+            InlineAsmOperand::Out { expr: None, .. } => {}
             InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                 vis.visit_expr(in_expr);
                 if let Some(out_expr) = out_expr {
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index a377763983a4b..cc699b237c215 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -714,13 +714,10 @@ fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
     for (op, _) in &asm.operands {
         match op {
             InlineAsmOperand::In { expr, .. }
+            | InlineAsmOperand::Out { expr: Some(expr), .. }
             | InlineAsmOperand::InOut { expr, .. }
             | InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
-            InlineAsmOperand::Out { expr, .. } => {
-                if let Some(expr) = expr {
-                    visitor.visit_expr(expr);
-                }
-            }
+            InlineAsmOperand::Out { expr: None, .. } => {}
             InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                 visitor.visit_expr(in_expr);
                 if let Some(out_expr) = out_expr {
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index f38f85a462688..aaded7ba23bbd 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,3 +1,4 @@
+#![cfg_attr(bootstrap, feature(bindings_after_at))]
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(destructuring_assignment)]
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index b66995afc6db6..00c2f0a0299a1 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1664,13 +1664,10 @@ impl Debug for Statement<'_> {
             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
             }
-            Coverage(box ref coverage) => {
-                if let Some(rgn) = &coverage.code_region {
-                    write!(fmt, "Coverage::{:?} for {:?}", coverage.kind, rgn)
-                } else {
-                    write!(fmt, "Coverage::{:?}", coverage.kind)
-                }
+            Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => {
+                write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
             }
+            Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
             CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
                 ref src,
                 ref dst,
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 45ea3e3d9f35e..af7f779652260 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -587,14 +587,12 @@ macro_rules! make_mir_visitor {
                                 InlineAsmOperand::In { value, .. } => {
                                     self.visit_operand(value, location);
                                 }
-                                InlineAsmOperand::Out { place, .. } => {
-                                    if let Some(place) = place {
-                                        self.visit_place(
-                                            place,
-                                            PlaceContext::MutatingUse(MutatingUseContext::Store),
-                                            location,
-                                        );
-                                    }
+                                InlineAsmOperand::Out { place: Some(place), .. } => {
+                                    self.visit_place(
+                                        place,
+                                        PlaceContext::MutatingUse(MutatingUseContext::Store),
+                                        location,
+                                    );
                                 }
                                 InlineAsmOperand::InOut { in_value, out_place, .. } => {
                                     self.visit_operand(in_value, location);
@@ -610,7 +608,8 @@ macro_rules! make_mir_visitor {
                                 | InlineAsmOperand::SymFn { value } => {
                                     self.visit_constant(value, location);
                                 }
-                                InlineAsmOperand::SymStatic { def_id: _ } => {}
+                                InlineAsmOperand::Out { place: None, .. }
+                                | InlineAsmOperand::SymStatic { def_id: _ } => {}
                             }
                         }
                     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 48337b8cb9617..b88bce844fa19 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -14,7 +14,7 @@ use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::RangeEnd;
 use rustc_index::newtype_index;
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::IndexVec;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::middle::region;
 use rustc_middle::mir::{
@@ -716,17 +716,9 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                     PatKind::Variant { adt_def, variant_index, .. } => {
                         Some(&adt_def.variants[variant_index])
                     }
-                    _ => {
-                        if let ty::Adt(adt, _) = self.ty.kind() {
-                            if !adt.is_enum() {
-                                Some(&adt.variants[VariantIdx::new(0)])
-                            } else {
-                                None
-                            }
-                        } else {
-                            None
-                        }
-                    }
+                    _ => self.ty.ty_adt_def().and_then(|adt| {
+                        if !adt.is_enum() { Some(adt.non_enum_variant()) } else { None }
+                    }),
                 };
 
                 if let Some(variant) = variant {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 8558d6bb00e72..4befeb1d827cf 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -927,27 +927,29 @@ pub trait PrettyPrinter<'tcx>:
         }
 
         match ct.val {
-            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
-                if let Some(promoted) = promoted {
-                    p!(print_value_path(def.did, substs));
-                    p!(write("::{:?}", promoted));
-                } else {
-                    match self.tcx().def_kind(def.did) {
-                        DefKind::Static | DefKind::Const | DefKind::AssocConst => {
-                            p!(print_value_path(def.did, substs))
-                        }
-                        _ => {
-                            if def.is_local() {
-                                let span = self.tcx().def_span(def.did);
-                                if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
-                                {
-                                    p!(write("{}", snip))
-                                } else {
-                                    print_underscore!()
-                                }
+            ty::ConstKind::Unevaluated(ty::Unevaluated {
+                def,
+                substs,
+                promoted: Some(promoted),
+            }) => {
+                p!(print_value_path(def.did, substs));
+                p!(write("::{:?}", promoted));
+            }
+            ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => {
+                match self.tcx().def_kind(def.did) {
+                    DefKind::Static | DefKind::Const | DefKind::AssocConst => {
+                        p!(print_value_path(def.did, substs))
+                    }
+                    _ => {
+                        if def.is_local() {
+                            let span = self.tcx().def_span(def.did);
+                            if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) {
+                                p!(write("{}", snip))
                             } else {
                                 print_underscore!()
                             }
+                        } else {
+                            print_underscore!()
                         }
                     }
                 }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index eaf24552355d4..ab927b7944223 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -2164,14 +2164,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 hir::InlineAsmOperand::In { expr, .. } => {
                     self.check_expr_asm_operand(expr, true);
                 }
-                hir::InlineAsmOperand::Out { expr, .. } => {
-                    if let Some(expr) = expr {
-                        self.check_expr_asm_operand(expr, false);
-                    }
-                }
-                hir::InlineAsmOperand::InOut { expr, .. } => {
+                hir::InlineAsmOperand::Out { expr: Some(expr), .. }
+                | hir::InlineAsmOperand::InOut { expr, .. } => {
                     self.check_expr_asm_operand(expr, false);
                 }
+                hir::InlineAsmOperand::Out { expr: None, .. } => {}
                 hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                     self.check_expr_asm_operand(in_expr, true);
                     if let Some(out_expr) = out_expr {
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index cd00d181ed046..024370f8d3711 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -334,12 +334,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                     match op {
                         hir::InlineAsmOperand::In { expr, .. }
                         | hir::InlineAsmOperand::Sym { expr, .. } => self.consume_expr(expr),
-                        hir::InlineAsmOperand::Out { expr, .. } => {
-                            if let Some(expr) = expr {
-                                self.mutate_expr(expr);
-                            }
-                        }
-                        hir::InlineAsmOperand::InOut { expr, .. } => {
+                        hir::InlineAsmOperand::Out { expr: Some(expr), .. }
+                        | hir::InlineAsmOperand::InOut { expr, .. } => {
                             self.mutate_expr(expr);
                         }
                         hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
@@ -348,7 +344,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                                 self.mutate_expr(out_expr);
                             }
                         }
-                        hir::InlineAsmOperand::Const { .. } => {}
+                        hir::InlineAsmOperand::Out { expr: None, .. }
+                        | hir::InlineAsmOperand::Const { .. } => {}
                     }
                 }
             }