From 93d5a8025dd53469c0ea80b645a3087a1d87bb57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 21:08:55 +0100
Subject: [PATCH 1/7] Clean up with_generic_param_rib, avoid double hashing

---
 compiler/rustc_resolve/src/late.rs | 41 +++++++++++++-----------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f156caf23ba..02a7bc0b622 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -29,7 +29,7 @@ use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
 
 use rustc_span::source_map::{respan, Spanned};
-use std::collections::BTreeSet;
+use std::collections::{hash_map::Entry, BTreeSet};
 use std::mem::{replace, take};
 use tracing::debug;
 
@@ -1060,36 +1060,29 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 continue;
             }
 
-            let def_kind = match param.kind {
-                GenericParamKind::Type { .. } => DefKind::TyParam,
-                GenericParamKind::Const { .. } => DefKind::ConstParam,
-                _ => unreachable!(),
-            };
-
             let ident = param.ident.normalize_to_macros_2_0();
             debug!("with_generic_param_rib: {}", param.id);
 
-            if seen_bindings.contains_key(&ident) {
-                let span = seen_bindings.get(&ident).unwrap();
-                let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, *span);
-                self.report_error(param.ident.span, err);
+            match seen_bindings.entry(ident) {
+                Entry::Occupied(entry) => {
+                    let span = *entry.get();
+                    let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
+                    self.report_error(param.ident.span, err);
+                }
+                Entry::Vacant(entry) => {
+                    entry.insert(param.ident.span);
+                }
             }
-            seen_bindings.entry(ident).or_insert(param.ident.span);
 
             // Plain insert (no renaming).
-            let res = Res::Def(def_kind, self.r.local_def_id(param.id).to_def_id());
-
-            match param.kind {
-                GenericParamKind::Type { .. } => {
-                    function_type_rib.bindings.insert(ident, res);
-                    self.r.record_partial_res(param.id, PartialRes::new(res));
-                }
-                GenericParamKind::Const { .. } => {
-                    function_value_rib.bindings.insert(ident, res);
-                    self.r.record_partial_res(param.id, PartialRes::new(res));
-                }
+            let (rib, def_kind) = match param.kind {
+                GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
+                GenericParamKind::Const { .. } => (&mut function_value_rib, DefKind::ConstParam),
                 _ => unreachable!(),
-            }
+            };
+            let res = Res::Def(def_kind, self.r.local_def_id(param.id).to_def_id());
+            self.r.record_partial_res(param.id, PartialRes::new(res));
+            rib.bindings.insert(ident, res);
         }
 
         self.ribs[ValueNS].push(function_value_rib);

From 62f593bda9eff51efdbc3172c3ee768cb3528b1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 21:38:41 +0100
Subject: [PATCH 2/7] Precompute vector length in smart_resolve_path_fragment

---
 compiler/rustc_resolve/src/late.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 02a7bc0b622..4beaf6bfa80 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1891,8 +1891,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     self.r.trait_map.insert(id, traits);
                 }
 
-                let mut std_path = vec![Segment::from_ident(Ident::with_dummy_span(sym::std))];
+                let mut std_path = Vec::with_capacity(1 + path.len());
 
+                std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std)));
                 std_path.extend(path);
 
                 if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {

From 91ea623f49bb28a770b2283cfbd5ed457ee3c48d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 21:41:15 +0100
Subject: [PATCH 3/7] Remove unnecessary cloned

---
 compiler/rustc_resolve/src/late.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 4beaf6bfa80..f33952bd3a9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1977,7 +1977,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> {
         let mut fin_res = None;
 
-        for (i, ns) in [primary_ns, TypeNS, ValueNS].iter().cloned().enumerate() {
+        for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
             if i == 0 || ns != primary_ns {
                 match self.resolve_qpath(id, qself, path, ns, span, crate_lint)? {
                     Some(partial_res)

From 89bc399d56ead5b00028193708d26fc60ac607e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 21:41:35 +0100
Subject: [PATCH 4/7] Add missing semicolon

---
 compiler/rustc_resolve/src/late.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f33952bd3a9..a45c5ccea9c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1987,7 +1987,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     }
                     partial_res => {
                         if fin_res.is_none() {
-                            fin_res = partial_res
+                            fin_res = partial_res;
                         }
                     }
                 }

From f499601dd879159dbb593d2451756364f013285d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 22:49:53 +0100
Subject: [PATCH 5/7] Create closure outside of the loop

---
 compiler/rustc_resolve/src/late.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index a45c5ccea9c..eee115fc0f6 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -953,8 +953,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                             });
                         };
 
-                        for item in trait_items {
-                            this.with_trait_items(trait_items, |this| {
+                        this.with_trait_items(trait_items, |this| {
+                            for item in trait_items {
                                 match &item.kind {
                                     AssocItemKind::Const(_, ty, default) => {
                                         this.visit_ty(ty);
@@ -983,8 +983,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                         panic!("unexpanded macro in resolve!")
                                     }
                                 };
-                            });
-                        }
+                            }
+                        });
                     });
                 });
             }

From 66c28729016301da78f294aaff15d29567d9d02c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 23:17:56 +0100
Subject: [PATCH 6/7] Inline a single-use closure

---
 compiler/rustc_resolve/src/late.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index eee115fc0f6..2775ed51c51 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1771,7 +1771,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             path
         );
         let ns = source.namespace();
-        let is_expected = &|res| source.is_expected(res);
 
         let report_errors = |this: &mut Self, res: Option<Res>| {
             if this.should_report_errs() {
@@ -1874,7 +1873,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             crate_lint,
         ) {
             Ok(Some(partial_res)) if partial_res.unresolved_segments() == 0 => {
-                if is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err {
+                if source.is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err
+                {
                     partial_res
                 } else {
                     report_errors(self, Some(partial_res.base_res()))

From 6d71cc675091e2ca1080dc46ddaf3d202dd2c949 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1niel=20Buga?= <bugadani@gmail.com>
Date: Sun, 20 Dec 2020 23:55:03 +0100
Subject: [PATCH 7/7] Move std_path construction into condition

---
 compiler/rustc_resolve/src/late.rs | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 2775ed51c51..b13462587bc 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1891,12 +1891,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     self.r.trait_map.insert(id, traits);
                 }
 
-                let mut std_path = Vec::with_capacity(1 + path.len());
-
-                std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std)));
-                std_path.extend(path);
-
                 if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
+                    let mut std_path = Vec::with_capacity(1 + path.len());
+
+                    std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std)));
+                    std_path.extend(path);
                     if let PathResult::Module(_) | PathResult::NonModule(_) =
                         self.resolve_path(&std_path, Some(ns), false, span, CrateLint::No)
                     {