about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-08 14:06:42 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-10 13:16:06 +0300
commit6a347f3701665a2e01f1f762d6be3b201b73bf42 (patch)
tree5b612bfaf9eaee0b3f722c4218656f405fbb646b
parentdf03e420e020c2ccc71bad4f7978b49a1c049435 (diff)
downloadrust-6a347f3701665a2e01f1f762d6be3b201b73bf42.tar.gz
rust-6a347f3701665a2e01f1f762d6be3b201b73bf42.zip
resolve: Remove `Deref<Target=Resolver>` implementations
It's now immediately clear what fields belong to the global resolver state and what are specific to passes/visitors.
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs226
-rw-r--r--src/librustc_resolve/check_unused.rs31
-rw-r--r--src/librustc_resolve/diagnostics.rs18
-rw-r--r--src/librustc_resolve/late.rs141
-rw-r--r--src/librustc_resolve/late/diagnostics.rs39
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_resolve/macros.rs4
-rw-r--r--src/librustc_resolve/resolve_imports.rs127
8 files changed, 269 insertions, 319 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 9f6f36e0aa4..25d80021269 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -19,7 +19,6 @@ use rustc::middle::cstore::CrateStore;
 use rustc_metadata::cstore::LoadedMacro;
 
 use std::cell::Cell;
-use std::ops::{Deref, DerefMut};
 use std::ptr;
 use rustc_data_structures::sync::Lrc;
 
@@ -94,6 +93,14 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
+        if !field_names.is_empty() {
+            self.field_names.insert(def_id, field_names);
+        }
+    }
+}
+
+impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
         // If any statements are items, we need to create an anonymous module
         block.stmts.iter().any(|statement| match statement.node {
@@ -102,12 +109,6 @@ impl<'a> Resolver<'a> {
         })
     }
 
-    fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
-        if !field_names.is_empty() {
-            self.field_names.insert(def_id, field_names);
-        }
-    }
-
     fn build_reduced_graph_for_use_tree(
         &mut self,
         // This particular use tree
@@ -165,7 +166,7 @@ impl<'a> Resolver<'a> {
 
                         if empty_for_self(&module_path) {
                             resolve_error(
-                                self,
+                                &self.r,
                                 use_tree.span,
                                 ResolutionError::
                                 SelfImportOnlyInImportListWithNonEmptyPrefix
@@ -182,14 +183,14 @@ impl<'a> Resolver<'a> {
                 } else {
                     // Disallow `self`
                     if source.ident.name == kw::SelfLower {
-                        resolve_error(self,
+                        resolve_error(&self.r,
                                       use_tree.span,
                                       ResolutionError::SelfImportsOnlyAllowedWithin);
                     }
 
                     // Disallow `use $crate;`
                     if source.ident.name == kw::DollarCrate && module_path.is_empty() {
-                        let crate_root = self.resolve_crate_root(source.ident);
+                        let crate_root = self.r.resolve_crate_root(source.ident);
                         let crate_name = match crate_root.kind {
                             ModuleKind::Def(.., name) => name,
                             ModuleKind::Block(..) => unreachable!(),
@@ -204,7 +205,7 @@ impl<'a> Resolver<'a> {
                                     name: kw::PathRoot,
                                     span: source.ident.span,
                                 },
-                                id: Some(self.session.next_node_id()),
+                                id: Some(self.r.session.next_node_id()),
                             });
                             source.ident.name = crate_name;
                         }
@@ -212,7 +213,7 @@ impl<'a> Resolver<'a> {
                             ident.name = crate_name;
                         }
 
-                        self.session.struct_span_warn(item.span, "`$crate` may not be imported")
+                        self.r.session.struct_span_warn(item.span, "`$crate` may not be imported")
                             .note("`use $crate;` was erroneously allowed and \
                                    will become a hard error in a future release")
                             .emit();
@@ -220,7 +221,7 @@ impl<'a> Resolver<'a> {
                 }
 
                 if ident.name == kw::Crate {
-                    self.session.span_err(ident.span,
+                    self.r.session.span_err(ident.span,
                         "crate root imports need to be explicitly named: \
                          `use crate as name;`");
                 }
@@ -282,7 +283,7 @@ impl<'a> Resolver<'a> {
                     None
                 }).collect::<Vec<_>>();
                 if self_spans.len() > 1 {
-                    let mut e = resolve_struct_error(self,
+                    let mut e = resolve_struct_error(&self.r,
                         self_spans[0],
                         ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
 
@@ -328,9 +329,7 @@ impl<'a> Resolver<'a> {
             }
         }
     }
-}
 
-impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     /// Constructs the reduced graph for one item.
     fn build_reduced_graph_for_item(&mut self, item: &Item) {
         let parent_scope = &self.parent_scope.clone();
@@ -338,7 +337,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         let expansion = parent_scope.expansion;
         let ident = item.ident.gensym_if_underscore();
         let sp = item.span;
-        let vis = self.resolve_visibility(&item.vis, parent_scope);
+        let vis = self.r.resolve_visibility(&item.vis, parent_scope);
 
         match item.node {
             ItemKind::Use(ref use_tree) => {
@@ -352,7 +351,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
 
             ItemKind::ExternCrate(orig_name) => {
                 let module = if orig_name.is_none() && ident.name == kw::SelfLower {
-                    self.session
+                    self.r.session
                         .struct_span_err(item.span, "`extern crate self;` requires renaming")
                         .span_suggestion(
                             item.span,
@@ -363,25 +362,25 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                         .emit();
                     return;
                 } else if orig_name == Some(kw::SelfLower) {
-                    self.graph_root
+                    self.r.graph_root
                 } else {
-                    let crate_id = self.resolver.crate_loader.process_extern_crate(
-                        item, &self.resolver.definitions
+                    let crate_id = self.r.crate_loader.process_extern_crate(
+                        item, &self.r.definitions
                     );
-                    self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
+                    self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
                 };
 
-                self.populate_module_if_necessary(module);
-                if let Some(name) = self.session.parse_sess.injected_crate_name.try_get() {
+                self.r.populate_module_if_necessary(module);
+                if let Some(name) = self.r.session.parse_sess.injected_crate_name.try_get() {
                     if name.as_str() == ident.name.as_str() {
-                        self.injected_crate = Some(module);
+                        self.r.injected_crate = Some(module);
                     }
                 }
 
                 let used = self.process_legacy_macro_imports(item, module, parent_scope);
                 let binding =
-                    (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
-                let directive = self.arenas.alloc_import_directive(ImportDirective {
+                    (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
+                let directive = self.r.arenas.alloc_import_directive(ImportDirective {
                     root_id: item.id,
                     id: item.id,
                     parent_scope: parent_scope.clone(),
@@ -399,18 +398,18 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                     vis: Cell::new(vis),
                     used: Cell::new(used),
                 });
-                self.potentially_unused_imports.push(directive);
-                let imported_binding = self.import(binding, directive);
-                if ptr::eq(parent, self.graph_root) {
-                    if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
+                self.r.potentially_unused_imports.push(directive);
+                let imported_binding = self.r.import(binding, directive);
+                if ptr::eq(parent, self.r.graph_root) {
+                    if let Some(entry) = self.r.extern_prelude.get(&ident.modern()) {
                         if expansion != ExpnId::root() && orig_name.is_some() &&
                            entry.extern_crate_item.is_none() {
-                            self.session.span_err(item.span, "macro-expanded `extern crate` items \
-                                                              cannot shadow names passed with \
-                                                              `--extern`");
+                            let msg = "macro-expanded `extern crate` items cannot \
+                                       shadow names passed with `--extern`";
+                            self.r.session.span_err(item.span, msg);
                         }
                     }
-                    let entry = self.extern_prelude.entry(ident.modern())
+                    let entry = self.r.extern_prelude.entry(ident.modern())
                                                    .or_insert(ExternPreludeEntry {
                         extern_crate_item: None,
                         introduced_by_item: true,
@@ -420,7 +419,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                         entry.introduced_by_item = true;
                     }
                 }
-                self.define(parent, ident, TypeNS, imported_binding);
+                self.r.define(parent, ident, TypeNS, imported_binding);
             }
 
             ItemKind::GlobalAsm(..) => {}
@@ -428,16 +427,16 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
             ItemKind::Mod(..) if ident.name == kw::Invalid => {} // Crate root
 
             ItemKind::Mod(..) => {
-                let def_id = self.definitions.local_def_id(item.id);
+                let def_id = self.r.definitions.local_def_id(item.id);
                 let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
-                let module = self.arenas.alloc_module(ModuleData {
+                let module = self.r.arenas.alloc_module(ModuleData {
                     no_implicit_prelude: parent.no_implicit_prelude || {
                         attr::contains_name(&item.attrs, sym::no_implicit_prelude)
                     },
                     ..ModuleData::new(Some(parent), module_kind, def_id, expansion, item.span)
                 });
-                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
-                self.module_map.insert(def_id, module);
+                self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
+                self.r.module_map.insert(def_id, module);
 
                 // Descend into the module.
                 self.parent_scope.module = module;
@@ -448,45 +447,45 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
 
             // These items live in the value namespace.
             ItemKind::Static(..) => {
-                let res = Res::Def(DefKind::Static, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
             }
             ItemKind::Const(..) => {
-                let res = Res::Def(DefKind::Const, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::Const, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
             }
             ItemKind::Fn(..) => {
-                let res = Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
 
                 // Functions introducing procedural macros reserve a slot
                 // in the macro namespace as well (see #52225).
-                self.define_macro(item, parent_scope);
+                self.r.define_macro(item, parent_scope);
             }
 
             // These items live in the type namespace.
             ItemKind::TyAlias(..) => {
-                let res = Res::Def(DefKind::TyAlias, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::TyAlias, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
             ItemKind::OpaqueTy(_, _) => {
-                let res = Res::Def(DefKind::OpaqueTy, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::OpaqueTy, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
             ItemKind::Enum(ref enum_definition, _) => {
                 let module_kind = ModuleKind::Def(
                     DefKind::Enum,
-                    self.definitions.local_def_id(item.id),
+                    self.r.definitions.local_def_id(item.id),
                     ident.name,
                 );
-                let module = self.new_module(parent,
+                let module = self.r.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
                                              expansion,
                                              item.span);
-                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
+                self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
                 for variant in &(*enum_definition).variants {
                     self.build_reduced_graph_for_variant(variant, module, vis, expansion);
@@ -494,16 +493,16 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
             }
 
             ItemKind::TraitAlias(..) => {
-                let res = Res::Def(DefKind::TraitAlias, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::TraitAlias, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
             // These items live in both the type and value namespaces.
             ItemKind::Struct(ref struct_def, _) => {
                 // Define a name in the type namespace.
-                let def_id = self.definitions.local_def_id(item.id);
+                let def_id = self.r.definitions.local_def_id(item.id);
                 let res = Res::Def(DefKind::Struct, def_id);
-                self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
+                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
 
                 let mut ctor_vis = vis;
 
@@ -517,53 +516,53 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
 
                 // Record field names for error reporting.
                 let field_names = struct_def.fields().iter().filter_map(|field| {
-                    let field_vis = self.resolve_visibility(&field.vis, parent_scope);
-                    if ctor_vis.is_at_least(field_vis, &*self.resolver) {
+                    let field_vis = self.r.resolve_visibility(&field.vis, parent_scope);
+                    if ctor_vis.is_at_least(field_vis, &*self.r) {
                         ctor_vis = field_vis;
                     }
                     field.ident.map(|ident| ident.name)
                 }).collect();
-                let item_def_id = self.definitions.local_def_id(item.id);
-                self.insert_field_names(item_def_id, field_names);
+                let item_def_id = self.r.definitions.local_def_id(item.id);
+                self.r.insert_field_names(item_def_id, field_names);
 
                 // If this is a tuple or unit struct, define a name
                 // in the value namespace as well.
                 if let Some(ctor_node_id) = struct_def.ctor_id() {
                     let ctor_res = Res::Def(
                         DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)),
-                        self.definitions.local_def_id(ctor_node_id),
+                        self.r.definitions.local_def_id(ctor_node_id),
                     );
-                    self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
-                    self.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis));
+                    self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
+                    self.r.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis));
                 }
             }
 
             ItemKind::Union(ref vdata, _) => {
-                let res = Res::Def(DefKind::Union, self.definitions.local_def_id(item.id));
-                self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
+                let res = Res::Def(DefKind::Union, self.r.definitions.local_def_id(item.id));
+                self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
 
                 // Record field names for error reporting.
                 let field_names = vdata.fields().iter().filter_map(|field| {
-                    self.resolve_visibility(&field.vis, parent_scope);
+                    self.r.resolve_visibility(&field.vis, parent_scope);
                     field.ident.map(|ident| ident.name)
                 }).collect();
-                let item_def_id = self.definitions.local_def_id(item.id);
-                self.insert_field_names(item_def_id, field_names);
+                let item_def_id = self.r.definitions.local_def_id(item.id);
+                self.r.insert_field_names(item_def_id, field_names);
             }
 
             ItemKind::Impl(..) => {}
 
             ItemKind::Trait(..) => {
-                let def_id = self.definitions.local_def_id(item.id);
+                let def_id = self.r.definitions.local_def_id(item.id);
 
                 // Add all the items within to a new module.
                 let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
-                let module = self.new_module(parent,
+                let module = self.r.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
                                              expansion,
                                              item.span);
-                self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
+                self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.parent_scope.module = module;
             }
 
@@ -581,9 +580,9 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         let ident = variant.node.ident;
 
         // Define a name in the type namespace.
-        let def_id = self.definitions.local_def_id(variant.node.id);
+        let def_id = self.r.definitions.local_def_id(variant.node.id);
         let res = Res::Def(DefKind::Variant, def_id);
-        self.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
+        self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
 
         // If the variant is marked as non_exhaustive then lower the visibility to within the
         // crate.
@@ -599,42 +598,42 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         // It's ok to use the variant's id as a ctor id since an
         // error will be reported on any use of such resolution anyway.
         let ctor_node_id = variant.node.data.ctor_id().unwrap_or(variant.node.id);
-        let ctor_def_id = self.definitions.local_def_id(ctor_node_id);
+        let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id);
         let ctor_kind = CtorKind::from_ast(&variant.node.data);
         let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
-        self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
+        self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
     }
 
     /// Constructs the reduced graph for one foreign item.
     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
         let (res, ns) = match item.node {
             ForeignItemKind::Fn(..) => {
-                (Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
+                (Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Static(..) => {
-                (Res::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS)
+                (Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Ty => {
-                (Res::Def(DefKind::ForeignTy, self.definitions.local_def_id(item.id)), TypeNS)
+                (Res::Def(DefKind::ForeignTy, self.r.definitions.local_def_id(item.id)), TypeNS)
             }
             ForeignItemKind::Macro(_) => unreachable!(),
         };
         let parent = self.parent_scope.module;
         let expansion = self.parent_scope.expansion;
-        let vis = self.resolver.resolve_visibility(&item.vis, &self.parent_scope);
-        self.define(parent, item.ident, ns, (res, vis, item.span, expansion));
+        let vis = self.r.resolve_visibility(&item.vis, &self.parent_scope);
+        self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion));
     }
 
     fn build_reduced_graph_for_block(&mut self, block: &Block) {
         let parent = self.parent_scope.module;
         let expansion = self.parent_scope.expansion;
         if self.block_needs_anonymous_module(block) {
-            let module = self.new_module(parent,
+            let module = self.r.new_module(parent,
                                          ModuleKind::Block(block.id),
                                          parent.normal_ancestor_id,
                                          expansion,
                                          block.span);
-            self.block_map.insert(block.id, module);
+            self.r.block_map.insert(block.id, module);
             self.parent_scope.module = module; // Descend into the block.
         }
     }
@@ -801,22 +800,22 @@ impl<'a> Resolver<'a> {
         }
         module.populated.set(true)
     }
+}
 
+impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     fn legacy_import_macro(&mut self,
                            name: Name,
                            binding: &'a NameBinding<'a>,
                            span: Span,
                            allow_shadowing: bool) {
-        if self.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
+        if self.r.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
             let msg = format!("`{}` is already in scope", name);
             let note =
                 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
-            self.session.struct_span_err(span, &msg).note(note).emit();
+            self.r.session.struct_span_err(span, &msg).note(note).emit();
         }
     }
-}
 
-impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     /// Returns `true` if we should consider the underlying `extern crate` to be used.
     fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>,
                                     parent_scope: &ParentScope<'a>) -> bool {
@@ -825,16 +824,16 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         for attr in &item.attrs {
             if attr.check_name(sym::macro_use) {
                 if self.parent_scope.module.parent.is_some() {
-                    span_err!(self.session, item.span, E0468,
+                    span_err!(self.r.session, item.span, E0468,
                         "an `extern crate` loading macros must be at the crate root");
                 }
                 if let ItemKind::ExternCrate(Some(orig_name)) = item.node {
                     if orig_name == kw::SelfLower {
-                        self.session.span_err(attr.span,
+                        self.r.session.span_err(attr.span,
                             "`macro_use` is not supported on `extern crate self`");
                     }
                 }
-                let ill_formed = |span| span_err!(self.session, span, E0466, "bad macro import");
+                let ill_formed = |span| span_err!(self.r.session, span, E0466, "bad macro import");
                 match attr.meta() {
                     Some(meta) => match meta.node {
                         MetaItemKind::Word => {
@@ -854,7 +853,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
             }
         }
 
-        let arenas = self.arenas;
+        let arenas = self.r.arenas;
         let macro_use_directive = |span| arenas.alloc_import_directive(ImportDirective {
             root_id: item.id,
             id: item.id,
@@ -874,14 +873,14 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         let allow_shadowing = parent_scope.expansion == ExpnId::root();
         if let Some(span) = import_all {
             let directive = macro_use_directive(span);
-            self.potentially_unused_imports.push(directive);
+            self.r.potentially_unused_imports.push(directive);
             module.for_each_child(|ident, ns, binding| if ns == MacroNS {
-                let imported_binding = self.import(binding, directive);
+                let imported_binding = self.r.import(binding, directive);
                 self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
             });
         } else {
             for ident in single_imports.iter().cloned() {
-                let result = self.resolve_ident_in_module(
+                let result = self.r.resolve_ident_in_module(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     MacroNS,
@@ -891,12 +890,12 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                 );
                 if let Ok(binding) = result {
                     let directive = macro_use_directive(ident.span);
-                    self.potentially_unused_imports.push(directive);
-                    let imported_binding = self.import(binding, directive);
+                    self.r.potentially_unused_imports.push(directive);
+                    let imported_binding = self.r.import(binding, directive);
                     self.legacy_import_macro(ident.name, imported_binding,
                                              ident.span, allow_shadowing);
                 } else {
-                    span_err!(self.session, ident.span, E0469, "imported macro not found");
+                    span_err!(self.r.session, ident.span, E0469, "imported macro not found");
                 }
             }
         }
@@ -908,7 +907,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         for attr in attrs {
             if attr.check_name(sym::macro_escape) {
                 let msg = "macro_escape is a deprecated synonym for macro_use";
-                let mut err = self.session.struct_span_warn(attr.span, msg);
+                let mut err = self.r.session.struct_span_warn(attr.span, msg);
                 if let ast::AttrStyle::Inner = attr.style {
                     err.help("consider an outer attribute, `#[macro_use]` mod ...").emit();
                 } else {
@@ -919,7 +918,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
             }
 
             if !attr.is_word() {
-                self.session.span_err(attr.span, "arguments to macro_use are not allowed here");
+                self.r.session.span_err(attr.span, "arguments to macro_use are not allowed here");
             }
             return true;
         }
@@ -929,35 +928,22 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
 }
 
 pub struct BuildReducedGraphVisitor<'a, 'b> {
-    pub resolver: &'a mut Resolver<'b>,
+    pub r: &'a mut Resolver<'b>,
     pub parent_scope: ParentScope<'b>,
 }
 
-impl<'b> Deref for BuildReducedGraphVisitor<'_, 'b> {
-    type Target = Resolver<'b>;
-    fn deref(&self) -> &Self::Target {
-        self.resolver
-    }
-}
-
-impl<'b> DerefMut for BuildReducedGraphVisitor<'_, 'b> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        self.resolver
-    }
-}
-
 impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
         let invoc_id = id.placeholder_to_expn_id();
 
         self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
 
-        let invocation_data = self.arenas.alloc_invocation_data(InvocationData {
+        let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData {
             module: self.parent_scope.module,
             parent_legacy_scope: self.parent_scope.legacy,
             output_legacy_scope: Cell::new(None),
         });
-        let old_invocation_data = self.invocations.insert(invoc_id, invocation_data);
+        let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data);
         assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation");
 
         invocation_data
@@ -985,7 +971,7 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
     fn visit_item(&mut self, item: &'a Item) {
         let macro_use = match item.node {
             ItemKind::MacroDef(..) => {
-                self.parent_scope.legacy = self.resolver.define_macro(item, &self.parent_scope);
+                self.parent_scope.legacy = self.r.define_macro(item, &self.parent_scope);
                 return
             }
             ItemKind::Mac(..) => {
@@ -1042,12 +1028,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
         }
 
         // Add the item to the trait info.
-        let item_def_id = self.definitions.local_def_id(item.id);
+        let item_def_id = self.r.definitions.local_def_id(item.id);
         let (res, ns) = match item.node {
             TraitItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS),
             TraitItemKind::Method(ref sig, _) => {
                 if sig.decl.has_self() {
-                    self.has_self.insert(item_def_id);
+                    self.r.has_self.insert(item_def_id);
                 }
                 (Res::Def(DefKind::Method, item_def_id), ValueNS)
             }
@@ -1057,7 +1043,7 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
 
         let vis = ty::Visibility::Public;
         let expansion = self.parent_scope.expansion;
-        self.resolver.define(parent, item.ident, ns, (res, vis, item.span, expansion));
+        self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion));
 
         self.parent_scope.module = parent.parent.unwrap(); // nearest normal ancestor
         visit::walk_trait_item(self, item);
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index d733a32c9c3..922da7eef7a 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -23,8 +23,6 @@
 //  - `check_crate` finally emits the diagnostics based on the data generated
 //    in the last step
 
-use std::ops::{Deref, DerefMut};
-
 use crate::Resolver;
 use crate::resolve_imports::ImportDirectiveSubclass;
 
@@ -49,7 +47,7 @@ impl<'a> UnusedImport<'a> {
 }
 
 struct UnusedImportCheckVisitor<'a, 'b> {
-    resolver: &'a mut Resolver<'b>,
+    r: &'a mut Resolver<'b>,
     /// All the (so far) unused imports, grouped path list
     unused_imports: NodeMap<UnusedImport<'a>>,
     base_use_tree: Option<&'a ast::UseTree>,
@@ -57,29 +55,14 @@ struct UnusedImportCheckVisitor<'a, 'b> {
     item_span: Span,
 }
 
-// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
-impl<'a, 'b> Deref for UnusedImportCheckVisitor<'a, 'b> {
-    type Target = Resolver<'b>;
-
-    fn deref<'c>(&'c self) -> &'c Resolver<'b> {
-        &*self.resolver
-    }
-}
-
-impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> {
-    fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> {
-        &mut *self.resolver
-    }
-}
-
 impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
     // We have information about whether `use` (import) directives are actually
     // used now. If an import is not used at all, we signal a lint error.
     fn check_import(&mut self, id: ast::NodeId) {
         let mut used = false;
-        self.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns)));
+        self.r.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns)));
         if !used {
-            if self.maybe_unused_trait_imports.contains(&id) {
+            if self.r.maybe_unused_trait_imports.contains(&id) {
                 // Check later.
                 return;
             }
@@ -87,7 +70,7 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
         } else {
             // This trait import is definitely used, in a way other than
             // method resolution.
-            self.maybe_unused_trait_imports.remove(&id);
+            self.r.maybe_unused_trait_imports.remove(&id);
             if let Some(i) = self.unused_imports.get_mut(&self.base_id) {
                 i.unused.remove(&id);
             }
@@ -271,7 +254,7 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
     }
 
     let mut visitor = UnusedImportCheckVisitor {
-        resolver,
+        r: resolver,
         unused_imports: Default::default(),
         base_use_tree: None,
         base_id: ast::DUMMY_NODE_ID,
@@ -304,7 +287,7 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
         let ms = MultiSpan::from_spans(spans.clone());
         let mut span_snippets = spans.iter()
             .filter_map(|s| {
-                match visitor.session.source_map().span_to_snippet(*s) {
+                match visitor.r.session.source_map().span_to_snippet(*s) {
                     Ok(s) => Some(format!("`{}`", s)),
                     _ => None,
                 }
@@ -326,7 +309,7 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
             "remove the unused import"
         };
 
-        visitor.session.buffer_lint_with_diagnostic(
+        visitor.r.session.buffer_lint_with_diagnostic(
             lint::builtin::UNUSED_IMPORTS,
             unused.use_tree_id,
             ms,
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index f56954e32ae..3a39307849e 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -396,7 +396,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = kw::SelfLower;
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((path, Vec::new()))
@@ -420,7 +420,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Crate;
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((
@@ -451,7 +451,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<(Vec<Segment>, Vec<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Super;
-        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((path, Vec::new()))
@@ -484,13 +484,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         // 1) some consistent ordering for emitted dignostics, and
         // 2) `std` suggestions before `core` suggestions.
         let mut extern_crate_names =
-            self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
+            self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
         extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
 
         for name in extern_crate_names.into_iter() {
             // Replace first ident with a crate name and check if that is valid.
             path[0].ident.name = name;
-            let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
+            let result = self.r.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
             debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
                     name, path, result);
             if let PathResult::Module(..) = result {
@@ -556,7 +556,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 //   ie. `use a::b::{c, d, e};`
                 //                      ^^^
                 let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding(
-                    self.resolver.session, directive.span, directive.use_span,
+                    self.r.session, directive.span, directive.use_span,
                 );
                 debug!("check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}",
                        found_closing_brace, binding_span);
@@ -571,7 +571,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     //   ie. `use a::b::{c, d};`
                     //                    ^^^
                     if let Some(previous_span) = extend_span_to_previous_binding(
-                        self.resolver.session, binding_span,
+                        self.r.session, binding_span,
                     ) {
                         debug!("check_for_module_export_macro: previous_span={:?}", previous_span);
                         removal_span = removal_span.with_lo(previous_span.lo());
@@ -589,12 +589,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 //   or  `use a::{b, c, d}};`
                 //               ^^^^^^^^^^^
                 let (has_nested, after_crate_name) = find_span_immediately_after_crate_name(
-                    self.resolver.session, module_name, directive.use_span,
+                    self.r.session, module_name, directive.use_span,
                 );
                 debug!("check_for_module_export_macro: has_nested={:?} after_crate_name={:?}",
                        has_nested, after_crate_name);
 
-                let source_map = self.resolver.session.source_map();
+                let source_map = self.r.session.source_map();
 
                 // Add the import to the start, with a `{` if required.
                 let start_point = source_map.start_point(after_crate_name);
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index efc02f1c057..fe0760364f3 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -24,7 +24,6 @@ use syntax_pos::Span;
 
 use std::collections::BTreeSet;
 use std::mem::replace;
-use std::ops::{Deref, DerefMut};
 
 mod diagnostics;
 
@@ -69,7 +68,7 @@ impl PatternSource {
 }
 
 struct LateResolutionVisitor<'a, 'b> {
-    resolver: &'b mut Resolver<'a>,
+    r: &'b mut Resolver<'a>,
 
     /// The module that represents the current item scope.
     parent_scope: ParentScope<'a>,
@@ -101,19 +100,6 @@ struct LateResolutionVisitor<'a, 'b> {
     current_type_ascription: Vec<Span>,
 }
 
-impl<'a> Deref for LateResolutionVisitor<'a, '_> {
-    type Target = Resolver<'a>;
-    fn deref(&self) -> &Self::Target {
-        self.resolver
-    }
-}
-
-impl<'a> DerefMut for LateResolutionVisitor<'a, '_> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        self.resolver
-    }
-}
-
 /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
 impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
     fn visit_item(&mut self, item: &'tcx Item) {
@@ -146,7 +132,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 let self_ty = Ident::with_empty_ctxt(kw::SelfUpper);
                 let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                               .map_or(Res::Err, |d| d.res());
-                self.record_partial_res(ty.id, PartialRes::new(res));
+                self.r.record_partial_res(ty.id, PartialRes::new(res));
             }
             _ => (),
         }
@@ -295,7 +281,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let parent_scope = resolver.dummy_parent_scope();
         let graph_root = resolver.graph_root;
         LateResolutionVisitor {
-            resolver,
+            r: resolver,
             parent_scope,
             ribs: PerNS {
                 value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
@@ -318,7 +304,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                       record_used_id: Option<NodeId>,
                                       path_span: Span)
                                       -> Option<LexicalScopeBinding<'a>> {
-        self.resolver.resolve_ident_in_lexical_scope(
+        self.r.resolve_ident_in_lexical_scope(
             ident, ns, &self.parent_scope, record_used_id, path_span, &self.ribs[ns]
         )
     }
@@ -331,7 +317,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         path_span: Span,
         crate_lint: CrateLint,
     ) -> PathResult<'a> {
-        self.resolver.resolve_path_with_ribs(
+        self.r.resolve_path_with_ribs(
             path, opt_ns, &self.parent_scope, record_used, path_span, crate_lint, &self.ribs
         )
     }
@@ -357,15 +343,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn with_scope<F, T>(&mut self, id: NodeId, f: F) -> T
         where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T
     {
-        let id = self.definitions.local_def_id(id);
-        let module = self.module_map.get(&id).cloned(); // clones a reference
+        let id = self.r.definitions.local_def_id(id);
+        let module = self.r.module_map.get(&id).cloned(); // clones a reference
         if let Some(module) = module {
             // Move down in the graph.
             let orig_module = replace(&mut self.parent_scope.module, module);
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
 
-            self.finalize_current_module_macro_resolutions(module);
+            self.r.finalize_current_module_macro_resolutions(module);
             let ret = f(self);
 
             self.parent_scope.module = orig_module;
@@ -390,7 +376,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 // If an invocation of this macro created `ident`, give up on `ident`
                 // and switch to `ident`'s source from the macro definition.
                 MacroDefinition(def) => {
-                    if def == self.macro_def(ident.span.ctxt()) {
+                    if def == self.r.macro_def(ident.span.ctxt()) {
                         ident.span.remove_mark();
                     }
                 }
@@ -411,7 +397,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         debug!("resolve_adt");
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
-                let item_def_id = this.definitions.local_def_id(item.id);
+                let item_def_id = this.r.definitions.local_def_id(item.id);
                 this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| {
                     visit::walk_item(this, item);
                 });
@@ -433,7 +419,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             };
             let report_error = |this: &Self, ns| {
                 let what = if ns == TypeNS { "type parameters" } else { "local variables" };
-                this.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
+                this.r.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
             };
 
             for &ns in nss {
@@ -443,13 +429,13 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     }
                     Some(LexicalScopeBinding::Item(binding)) => {
                         let orig_blacklisted_binding =
-                            replace(&mut self.blacklisted_binding, Some(binding));
+                            replace(&mut self.r.blacklisted_binding, Some(binding));
                         if let Some(LexicalScopeBinding::Res(..)) =
                                 self.resolve_ident_in_lexical_scope(ident, ns, None,
                                                                     use_tree.prefix.span) {
                             report_error(self, ns);
                         }
-                        self.blacklisted_binding = orig_blacklisted_binding;
+                        self.r.blacklisted_binding = orig_blacklisted_binding;
                     }
                     None => {}
                 }
@@ -491,7 +477,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
-                    let local_def_id = this.definitions.local_def_id(item.id);
+                    let local_def_id = this.r.definitions.local_def_id(item.id);
                     this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds);
@@ -536,7 +522,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             ItemKind::TraitAlias(ref generics, ref bounds) => {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
-                    let local_def_id = this.definitions.local_def_id(item.id);
+                    let local_def_id = this.r.definitions.local_def_id(item.id);
                     this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds);
@@ -596,17 +582,17 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                     ident.name,
                                     *span,
                                 );
-                                resolve_error(self, param.ident.span, err);
+                                resolve_error(&self.r, param.ident.span, err);
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
                             // Plain insert (no renaming).
                             let res = Res::Def(
                                 DefKind::TyParam,
-                                self.definitions.local_def_id(param.id),
+                                self.r.definitions.local_def_id(param.id),
                             );
                             function_type_rib.bindings.insert(ident, res);
-                            self.record_partial_res(param.id, PartialRes::new(res));
+                            self.r.record_partial_res(param.id, PartialRes::new(res));
                         }
                         GenericParamKind::Const { .. } => {
                             let ident = param.ident.modern();
@@ -618,16 +604,16 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                     ident.name,
                                     *span,
                                 );
-                                resolve_error(self, param.ident.span, err);
+                                resolve_error(&self.r, param.ident.span, err);
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
                             let res = Res::Def(
                                 DefKind::ConstParam,
-                                self.definitions.local_def_id(param.id),
+                                self.r.definitions.local_def_id(param.id),
                             );
                             function_value_rib.bindings.insert(ident, res);
-                            self.record_partial_res(param.id, PartialRes::new(res));
+                            self.r.record_partial_res(param.id, PartialRes::new(res));
                         }
                     }
                 }
@@ -786,7 +772,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             this.with_self_rib(Res::SelfTy(None, None), |this| {
                 // Resolve the trait reference, if necessary.
                 this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
-                    let item_def_id = this.definitions.local_def_id(item_id);
+                    let item_def_id = this.r.definitions.local_def_id(item_id);
                     this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| {
                         if let Some(trait_ref) = opt_trait_reference.as_ref() {
                             // Resolve type arguments in the trait path.
@@ -801,7 +787,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                             this.with_self_struct_ctor_rib(item_def_id, |this| {
                                 debug!("resolve_implementation with_self_struct_ctor_rib");
                                 for impl_item in impl_items {
-                                    this.resolver.resolve_visibility(
+                                    this.r.resolve_visibility(
                                         &impl_item.vis, &this.parent_scope
                                     );
                                     // We also need a new scope for the impl item type parameters.
@@ -878,7 +864,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         // If there is a TraitRef in scope for an impl, then the method must be in the
         // trait.
         if let Some((module, _)) = self.current_trait_ref {
-            if self.resolver.resolve_ident_in_module(
+            if self.r.resolve_ident_in_module(
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
@@ -887,7 +873,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 span,
             ).is_err() {
                 let path = &self.current_trait_ref.as_ref().unwrap().1.path;
-                resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
+                resolve_error(&self.r, span, err(ident.name, &path_names_to_string(path)));
             }
         }
     }
@@ -912,7 +898,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
         pat.walk(&mut |pat| {
             if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
-                if sub_pat.is_some() || match self.partial_res_map.get(&pat.id)
+                if sub_pat.is_some() || match self.r.partial_res_map.get(&pat.id)
                                                                   .map(|res| res.base_res()) {
                     Some(Res::Local(..)) => true,
                     _ => false,
@@ -985,14 +971,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut missing_vars = missing_vars.iter().collect::<Vec<_>>();
         missing_vars.sort();
         for (_, v) in missing_vars {
-            resolve_error(self,
+            resolve_error(&self.r,
                           *v.origin.iter().next().unwrap(),
                           ResolutionError::VariableNotBoundInPattern(v));
         }
         let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
         inconsistent_vars.sort();
         for (name, v) in inconsistent_vars {
-            resolve_error(self, v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
+            let err = ResolutionError::VariableBoundWithDifferentMode(*name, v.1);
+            resolve_error(&self.r, v.0, err);
         }
     }
 
@@ -1023,7 +1010,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         debug!("(resolving block) entering block");
         // Move down in the graph, if there's an anonymous module rooted here.
         let orig_module = self.parent_scope.module;
-        let anonymous_module = self.block_map.get(&block.id).cloned(); // clones a reference
+        let anonymous_module = self.r.block_map.get(&block.id).cloned(); // clones a reference
 
         let mut num_macro_definition_ribs = 0;
         if let Some(anonymous_module) = anonymous_module {
@@ -1031,7 +1018,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.parent_scope.module = anonymous_module;
-            self.finalize_current_module_macro_resolutions(anonymous_module);
+            self.r.finalize_current_module_macro_resolutions(anonymous_module);
         } else {
             self.ribs[ValueNS].push(Rib::new(NormalRibKind));
         }
@@ -1041,7 +1028,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             if let StmtKind::Item(ref item) = stmt.node {
                 if let ItemKind::MacroDef(..) = item.node {
                     num_macro_definition_ribs += 1;
-                    let res = self.definitions.local_def_id(item.id);
+                    let res = self.r.definitions.local_def_id(item.id);
                     self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
                     self.label_ribs.push(Rib::new(MacroDefinition(res)));
                 }
@@ -1081,7 +1068,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             Some(id) if id == outer_pat_id => {
                 // `Variant(a, a)`, error
                 resolve_error(
-                    self,
+                    &self.r,
                     ident.span,
                     ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
                         &ident.as_str())
@@ -1090,7 +1077,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             Some(..) if pat_src == PatternSource::FnParam => {
                 // `fn f(a: u8, a: u8)`, error
                 resolve_error(
-                    self,
+                    &self.r,
                     ident.span,
                     ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
                         &ident.as_str())
@@ -1143,7 +1130,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                             Res::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
                                 // Disambiguate in favor of a unit struct/variant
                                 // or constant pattern.
-                                self.record_use(ident, ValueNS, binding.unwrap(), false);
+                                self.r.record_use(ident, ValueNS, binding.unwrap(), false);
                                 Some(res)
                             }
                             Res::Def(DefKind::Ctor(..), _)
@@ -1155,7 +1142,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                 // but we still conservatively report an error, see
                                 // issues/33118#issuecomment-233962221 for one reason why.
                                 resolve_error(
-                                    self,
+                                    &self.r,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
                                         pat_src.descr(), ident.name, binding.unwrap())
@@ -1176,7 +1163,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                         self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
                     });
 
-                    self.record_partial_res(pat.id, PartialRes::new(res));
+                    self.r.record_partial_res(pat.id, PartialRes::new(res));
                 }
 
                 PatKind::TupleStruct(ref path, ..) => {
@@ -1233,9 +1220,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let report_errors = |this: &mut Self, res: Option<Res>| {
             let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res);
             let def_id = this.parent_scope.module.normal_ancestor_id;
-            let node_id = this.definitions.as_local_node_id(def_id).unwrap();
+            let node_id = this.r.definitions.as_local_node_id(def_id).unwrap();
             let better = res.is_some();
-            this.use_injections.push(UseError { err, candidates, node_id, better });
+            this.r.use_injections.push(UseError { err, candidates, node_id, better });
             PartialRes::new(Res::Err)
         };
 
@@ -1257,11 +1244,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     let mut res = None;
                     if let Res::Def(DefKind::Struct, def_id) = partial_res.base_res() {
                         if let Some((ctor_res, ctor_vis))
-                                = self.struct_constructors.get(&def_id).cloned() {
+                                = self.r.struct_constructors.get(&def_id).cloned() {
                             if is_expected(ctor_res) &&
-                               self.is_accessible_from(ctor_vis, self.parent_scope.module) {
+                               self.r.is_accessible_from(ctor_vis, self.parent_scope.module) {
                                 let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
-                                self.session.buffer_lint(lint, id, span,
+                                self.r.session.buffer_lint(lint, id, span,
                                     "private struct constructors are not usable through \
                                      re-exports in outer modules",
                                 );
@@ -1280,12 +1267,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 if ns == ValueNS {
                     let item_name = path.last().unwrap().ident;
                     let traits = self.get_traits_containing_item(item_name, ns);
-                    self.trait_map.insert(id, traits);
+                    self.r.trait_map.insert(id, traits);
                 }
 
                 let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))];
                 std_path.extend(path);
-                if self.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
+                if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
                     let cl = CrateLint::No;
                     let ns = Some(ns);
                     if let PathResult::Module(_) | PathResult::NonModule(_) =
@@ -1294,7 +1281,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                         let item_span = path.iter().last().map(|segment| segment.ident.span)
                             .unwrap_or(span);
                         debug!("accessed item from `std` submodule as a bare type {:?}", std_path);
-                        let mut hm = self.session.confused_type_with_std_module.borrow_mut();
+                        let mut hm = self.r.session.confused_type_with_std_module.borrow_mut();
                         hm.insert(item_span, span);
                         // In some places (E0223) we only have access to the full path
                         hm.insert(span, span);
@@ -1307,7 +1294,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
         if let PathSource::TraitItem(..) = source {} else {
             // Avoid recording definition of `A::B` in `<T as A>::B::C`.
-            self.record_partial_res(id, partial_res);
+            self.r.record_partial_res(id, partial_res);
         }
         partial_res
     }
@@ -1358,7 +1345,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         if qself.is_none() {
             let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
             let path = Path { segments: path.iter().map(path_seg).collect(), span };
-            if let Ok((_, res)) = self.resolver.resolve_macro_path(
+            if let Ok((_, res)) = self.r.resolve_macro_path(
                 &path, None, &self.parent_scope, false, false
             ) {
                 return Some(PartialRes::new(res));
@@ -1453,15 +1440,16 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             PathResult::Module(ModuleOrUniformRoot::Module(_)) |
             PathResult::Failed { .. }
                     if (ns == TypeNS || path.len() > 1) &&
-                       self.primitive_type_table.primitive_types
+                       self.r.primitive_type_table.primitive_types
                            .contains_key(&path[0].ident.name) => {
-                let prim = self.primitive_type_table.primitive_types[&path[0].ident.name];
+                let prim = self.r.primitive_type_table.primitive_types[&path[0].ident.name];
                 PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1)
             }
             PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
                 PartialRes::new(module.res().unwrap()),
             PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
-                resolve_error(self, span, ResolutionError::FailedToResolve { label, suggestion });
+                let err = ResolutionError::FailedToResolve { label, suggestion };
+                resolve_error(&self.r, span, err);
                 PartialRes::new(Res::Err)
             }
             PathResult::Module(..) | PathResult::Failed { .. } => return None,
@@ -1487,7 +1475,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             };
             if result.base_res() == unqualified_result {
                 let lint = lint::builtin::UNUSED_QUALIFICATIONS;
-                self.session.buffer_lint(lint, id, span, "unnecessary qualification")
+                self.r.session.buffer_lint(lint, id, span, "unnecessary qualification")
             }
         }
 
@@ -1550,15 +1538,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                             });
                             find_best_match_for_name(names, &*ident.as_str(), None)
                         });
-                        self.record_partial_res(expr.id, PartialRes::new(Res::Err));
-                        resolve_error(self,
+                        self.r.record_partial_res(expr.id, PartialRes::new(Res::Err));
+                        resolve_error(&self.r,
                                       label.ident.span,
                                       ResolutionError::UndeclaredLabel(&label.ident.as_str(),
                                                                        close_match));
                     }
                     Some(node_id) => {
                         // Since this res is a label, it is never read.
-                        self.label_res_map.insert(expr.id, node_id);
+                        self.r.label_res_map.insert(expr.id, node_id);
                         self.unused_labels.remove(&node_id);
                     }
                 }
@@ -1670,13 +1658,13 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 // the field name so that we can do some nice error reporting
                 // later on in typeck.
                 let traits = self.get_traits_containing_item(ident, ValueNS);
-                self.trait_map.insert(expr.id, traits);
+                self.r.trait_map.insert(expr.id, traits);
             }
             ExprKind::MethodCall(ref segment, ..) => {
                 debug!("(recording candidate traits for expr) recording traits for {}",
                        expr.id);
                 let traits = self.get_traits_containing_item(segment.ident, ValueNS);
-                self.trait_map.insert(expr.id, traits);
+                self.r.trait_map.insert(expr.id, traits);
             }
             _ => {
                 // Nothing to do.
@@ -1691,7 +1679,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut found_traits = Vec::new();
         // Look for the current trait.
         if let Some((module, _)) = self.current_trait_ref {
-            if self.resolver.resolve_ident_in_module(
+            if self.r.resolve_ident_in_module(
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
@@ -1709,11 +1697,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         loop {
             self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
             search_module = unwrap_or!(
-                self.hygienic_lexical_parent(search_module, &mut ident.span), break
+                self.r.hygienic_lexical_parent(search_module, &mut ident.span), break
             );
         }
 
-        if let Some(prelude) = self.prelude {
+        if let Some(prelude) = self.r.prelude {
             if !search_module.no_implicit_prelude {
                 self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
             }
@@ -1752,7 +1740,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 ).is_none() {
                     continue
                 }
-                if self.resolver.resolve_ident_in_module_unadjusted(
+                if self.r.resolve_ident_in_module_unadjusted(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     ns,
@@ -1780,8 +1768,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                trait_name: Ident) -> SmallVec<[NodeId; 1]> {
         let mut import_ids = smallvec![];
         while let NameBindingKind::Import { directive, binding, .. } = kind {
-            self.maybe_unused_trait_imports.insert(directive.id);
-            self.add_to_glob_map(&directive, trait_name);
+            self.r.maybe_unused_trait_imports.insert(directive.id);
+            self.r.add_to_glob_map(&directive, trait_name);
             import_ids.push(directive.id);
             kind = &binding.kind;
         };
@@ -1791,9 +1779,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
 impl<'a> Resolver<'a> {
     pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
+        self.finalize_current_module_macro_resolutions(self.graph_root);
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
-        let module = late_resolution_visitor.parent_scope.module;
-        late_resolution_visitor.finalize_current_module_macro_resolutions(module);
         visit::walk_crate(&mut late_resolution_visitor, krate);
         for (id, span) in late_resolution_visitor.unused_labels.iter() {
             self.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label");
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 28ab53bc2f0..9c9eb017aef 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -100,7 +100,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         };
 
         let code = DiagnosticId::Error(code.into());
-        let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code);
+        let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code);
 
         // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
         if ["this", "my"].contains(&&*item_str.as_str())
@@ -143,7 +143,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
         // Try to lookup name in more relaxed fashion for better error reporting.
         let ident = path.last().unwrap().ident;
-        let candidates = self.lookup_import_candidates(ident, ns, is_expected)
+        let candidates = self.r.lookup_import_candidates(ident, ns, is_expected)
             .drain(..)
             .filter(|ImportSuggestion { did, .. }| {
                 match (did, res.and_then(|res| res.opt_def_id())) {
@@ -155,7 +155,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         let crate_def_id = DefId::local(CRATE_DEF_INDEX);
         if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
             let enum_candidates =
-                self.lookup_import_candidates(ident, ns, is_enum_variant);
+                self.r.lookup_import_candidates(ident, ns, is_enum_variant);
             let mut enum_candidates = enum_candidates.iter()
                 .map(|suggestion| {
                     import_candidate_to_enum_paths(&suggestion)
@@ -267,7 +267,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         // parser issue where a struct literal is being used on an expression
         // where a brace being opened means a block is being started. Look
         // ahead for the next text to see if `span` is followed by a `{`.
-        let sm = self.session.source_map();
+        let sm = self.r.session.source_map();
         let mut sp = span;
         loop {
             sp = sm.next_point(sp);
@@ -429,9 +429,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             },
             (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
                 if let Some((ctor_def, ctor_vis))
-                        = self.struct_constructors.get(&def_id).cloned() {
+                        = self.r.struct_constructors.get(&def_id).cloned() {
                     let accessible_ctor =
-                        self.is_accessible_from(ctor_vis, self.parent_scope.module);
+                        self.r.is_accessible_from(ctor_vis, self.parent_scope.module);
                     if is_expected(ctor_def) && !accessible_ctor {
                         err.span_label(
                             span,
@@ -482,11 +482,11 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
             if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
                 // Look for a field with the same name in the current self_type.
-                if let Some(resolution) = self.partial_res_map.get(&node_id) {
+                if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
                     match resolution.base_res() {
                         Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did)
                                 if resolution.unresolved_segments() == 0 => {
-                            if let Some(field_names) = self.field_names.get(&did) {
+                            if let Some(field_names) = self.r.field_names.get(&did) {
                                 if field_names.iter().any(|&field_name| ident.name == field_name) {
                                     return Some(AssocSuggestion::Field);
                                 }
@@ -506,7 +506,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
         // Look for associated items in the current trait.
         if let Some((module, _)) = self.current_trait_ref {
-            if let Ok(binding) = self.resolver.resolve_ident_in_module(
+            if let Ok(binding) = self.r.resolve_ident_in_module(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     ns,
@@ -516,7 +516,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                 ) {
                 let res = binding.res();
                 if filter_fn(res) {
-                    return Some(if self.has_self.contains(&res.def_id()) {
+                    return Some(if self.r.has_self.contains(&res.def_id()) {
                         AssocSuggestion::MethodWithSelf
                     } else {
                         AssocSuggestion::AssocItem
@@ -556,8 +556,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                     } else {
                         // Items from the prelude
                         if !module.no_implicit_prelude {
-                            names.extend(self.extern_prelude.clone().iter().flat_map(|(ident, _)| {
-                                self.crate_loader
+                            let extern_prelude = self.r.extern_prelude.clone();
+                            names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
+                                self.r.crate_loader
                                     .maybe_process_path_extern(ident.name, ident.span)
                                     .and_then(|crate_id| {
                                         let crate_mod = Res::Def(
@@ -576,7 +577,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                                     })
                             }));
 
-                            if let Some(prelude) = self.prelude {
+                            if let Some(prelude) = self.r.prelude {
                                 add_module_candidates(prelude, &mut names, &filter_fn);
                             }
                         }
@@ -587,7 +588,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             // Add primitive types to the mix
             if filter_fn(Res::PrimTy(PrimTy::Bool)) {
                 names.extend(
-                    self.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| {
+                    self.r.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| {
                         TypoSuggestion::from_res(*name, Res::PrimTy(*prim_ty))
                     })
                 )
@@ -622,7 +623,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
     /// Only used in a specific case of type ascription suggestions
     fn get_colon_suggestion_span(&self, start: Span) -> Span {
-        let cm = self.session.source_map();
+        let cm = self.r.session.source_map();
         start.to(cm.next_point(start))
     }
 
@@ -632,7 +633,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         base_span: Span,
     ) {
         debug!("type_ascription_suggetion {:?}", base_span);
-        let cm = self.session.source_map();
+        let cm = self.r.session.source_map();
         let base_snippet = cm.span_to_snippet(base_span);
         debug!("self.current_type_ascription {:?}", self.current_type_ascription);
         if let Some(sp) = self.current_type_ascription.last() {
@@ -711,13 +712,13 @@ impl<'a> LateResolutionVisitor<'a, '_> {
     fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
         let mut result = None;
         let mut seen_modules = FxHashSet::default();
-        let mut worklist = vec![(self.graph_root, Vec::new())];
+        let mut worklist = vec![(self.r.graph_root, Vec::new())];
 
         while let Some((in_module, path_segments)) = worklist.pop() {
             // abort if the module is already found
             if result.is_some() { break; }
 
-            self.populate_module_if_necessary(in_module);
+            self.r.populate_module_if_necessary(in_module);
 
             in_module.for_each_child_stable(|ident, _, name_binding| {
                 // abort if the module is already found or if name_binding is private external
@@ -750,7 +751,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
     fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
         self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
-            self.populate_module_if_necessary(enum_module);
+            self.r.populate_module_if_necessary(enum_module);
 
             let mut variants = Vec::new();
             enum_module.for_each_child_stable(|ident, _, name_binding| {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8c099e4532c..4aa3e2f9167 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1732,7 +1732,7 @@ impl<'a> Resolver<'a> {
 
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
-        ImportResolver { resolver: self }.finalize_imports();
+        ImportResolver { r: self }.finalize_imports();
 
         self.late_resolve_crate(krate);
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 914125b7cae..fed8e555d2b 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -174,7 +174,7 @@ impl<'a> base::Resolver for Resolver<'a> {
         }
         self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
         let mut visitor = BuildReducedGraphVisitor {
-            resolver: self,
+            r: self,
             parent_scope: ParentScope {
                 module: invocation.module,
                 expansion: expn_id,
@@ -194,7 +194,7 @@ impl<'a> base::Resolver for Resolver<'a> {
     }
 
     fn resolve_imports(&mut self) {
-        ImportResolver { resolver: self }.resolve_imports()
+        ImportResolver { r: self }.resolve_imports()
     }
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 4611b813153..2ae2b1f3fc3 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -9,6 +9,7 @@ use crate::{Resolver, Segment};
 use crate::{names_to_string, module_to_string};
 use crate::{resolve_error, ResolutionError};
 use crate::ModuleKind;
+use crate::build_reduced_graph::BuildReducedGraphVisitor;
 use crate::diagnostics::Suggestion;
 
 use errors::Applicability;
@@ -417,7 +418,9 @@ impl<'a> Resolver<'a> {
         // No resolution and no one else can define the name - determinate error.
         Err((Determined, Weak::No))
     }
+}
 
+impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     // Add an import directive to the current module.
     pub fn add_import_directive(&mut self,
                                 module_path: Vec<Segment>,
@@ -430,7 +433,7 @@ impl<'a> Resolver<'a> {
                                 vis: ty::Visibility,
                                 parent_scope: ParentScope<'a>) {
         let current_module = parent_scope.module;
-        let directive = self.arenas.alloc_import_directive(ImportDirective {
+        let directive = self.r.arenas.alloc_import_directive(ImportDirective {
             parent_scope,
             module_path,
             imported_module: Cell::new(None),
@@ -448,10 +451,10 @@ impl<'a> Resolver<'a> {
 
         debug!("add_import_directive({:?})", directive);
 
-        self.indeterminate_imports.push(directive);
+        self.r.indeterminate_imports.push(directive);
         match directive.subclass {
             SingleImport { target, type_ns_only, .. } => {
-                self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
+                self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
                     let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
                     resolution.single_imports.insert(PtrKey(directive));
                 });
@@ -463,7 +466,9 @@ impl<'a> Resolver<'a> {
             _ => unreachable!(),
         }
     }
+}
 
+impl<'a> Resolver<'a> {
     // Given a binding and an import directive that resolves to it,
     // return the corresponding binding defined by the import directive.
     crate fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
@@ -638,25 +643,12 @@ struct UnresolvedImportError {
 }
 
 pub struct ImportResolver<'a, 'b> {
-    pub resolver: &'a mut Resolver<'b>,
-}
-
-impl<'a, 'b> std::ops::Deref for ImportResolver<'a, 'b> {
-    type Target = Resolver<'b>;
-    fn deref(&self) -> &Resolver<'b> {
-        self.resolver
-    }
-}
-
-impl<'a, 'b> std::ops::DerefMut for ImportResolver<'a, 'b> {
-    fn deref_mut(&mut self) -> &mut Resolver<'b> {
-        self.resolver
-    }
+    pub r: &'a mut Resolver<'b>,
 }
 
 impl<'a, 'b> ty::DefIdTree for &'a ImportResolver<'a, 'b> {
     fn parent(self, id: DefId) -> Option<DefId> {
-        self.resolver.parent(id)
+        self.r.parent(id)
     }
 }
 
@@ -672,20 +664,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     /// Resolves all imports for the crate. This method performs the fixed-
     /// point iteration.
     pub fn resolve_imports(&mut self) {
-        let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
-        while self.indeterminate_imports.len() < prev_num_indeterminates {
-            prev_num_indeterminates = self.indeterminate_imports.len();
-            for import in mem::take(&mut self.indeterminate_imports) {
+        let mut prev_num_indeterminates = self.r.indeterminate_imports.len() + 1;
+        while self.r.indeterminate_imports.len() < prev_num_indeterminates {
+            prev_num_indeterminates = self.r.indeterminate_imports.len();
+            for import in mem::take(&mut self.r.indeterminate_imports) {
                 match self.resolve_import(&import) {
-                    true => self.determined_imports.push(import),
-                    false => self.indeterminate_imports.push(import),
+                    true => self.r.determined_imports.push(import),
+                    false => self.r.indeterminate_imports.push(import),
                 }
             }
         }
     }
 
     pub fn finalize_imports(&mut self) {
-        for module in self.arenas.local_modules().iter() {
+        for module in self.r.arenas.local_modules().iter() {
             self.finalize_resolutions_in(module);
         }
 
@@ -693,8 +685,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         let mut seen_spans = FxHashSet::default();
         let mut errors = vec![];
         let mut prev_root_id: NodeId = NodeId::from_u32(0);
-        for i in 0 .. self.determined_imports.len() {
-            let import = self.determined_imports[i];
+        for i in 0 .. self.r.determined_imports.len() {
+            let import = self.r.determined_imports[i];
             if let Some(err) = self.finalize_import(import) {
                 has_errors = true;
 
@@ -709,7 +701,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
                 // If the error is a single failed import then create a "fake" import
                 // resolution for it so that later resolve stages won't complain.
-                self.import_dummy_binding(import);
+                self.r.import_dummy_binding(import);
                 if prev_root_id.as_u32() != 0
                         && prev_root_id.as_u32() != import.root_id.as_u32()
                         && !errors.is_empty() {
@@ -738,7 +730,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         // Report unresolved imports only if no hard error was already reported
         // to avoid generating multiple errors on the same import.
         if !has_errors {
-            for import in &self.indeterminate_imports {
+            for import in &self.r.indeterminate_imports {
                 self.throw_unresolved_import_error(errors, Some(MultiSpan::from(import.span)));
                 break;
             }
@@ -777,7 +769,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             (span, msg)
         };
 
-        let mut diag = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg);
+        let mut diag = struct_span_err!(self.r.session, span, E0432, "{}", &msg);
 
         if let Some((_, UnresolvedImportError { note, .. })) = errors.iter().last() {
             for message in note {
@@ -813,7 +805,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             // For better failure detection, pretend that the import will
             // not define any names while resolving its module path.
             let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
-            let path_res = self.resolve_path(
+            let path_res = self.r.resolve_path(
                 &directive.module_path,
                 None,
                 &directive.parent_scope,
@@ -844,7 +836,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         };
 
         let mut indeterminate = false;
-        self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
+        self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
             if let Err(Undetermined) = source_bindings[ns].get() {
                 // For better failure detection, pretend that the import will
                 // not define any names while resolving its module path.
@@ -896,10 +888,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         directive: &'b ImportDirective<'b>
     ) -> Option<UnresolvedImportError> {
         let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
-        let prev_ambiguity_errors_len = self.ambiguity_errors.len();
-        let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
+        let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
+        let path_res = self.r.resolve_path(&directive.module_path, None, &directive.parent_scope,
                                          true, directive.span, directive.crate_lint());
-        let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
+        let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         directive.vis.set(orig_vis);
         let module = match path_res {
             PathResult::Module(module) => {
@@ -909,10 +901,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                         span_bug!(directive.span, "inconsistent resolution for an import");
                     }
                 } else {
-                    if self.privacy_errors.is_empty() {
+                    if self.r.privacy_errors.is_empty() {
                         let msg = "cannot determine resolution for the import";
                         let msg_note = "import resolution is stuck, try simplifying other imports";
-                        self.session.struct_span_err(directive.span, msg).note(msg_note).emit();
+                        self.r.session.struct_span_err(directive.span, msg).note(msg_note).emit();
                     }
                 }
 
@@ -921,7 +913,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
                 if no_ambiguity {
                     assert!(directive.imported_module.get().is_none());
-                    resolve_error(self, span, ResolutionError::FailedToResolve {
+                    resolve_error(&self.r, span, ResolutionError::FailedToResolve {
                         label,
                         suggestion,
                     });
@@ -983,7 +975,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     // 2 segments, so the `resolve_path` above won't trigger it.
                     let mut full_path = directive.module_path.clone();
                     full_path.push(Segment::from_ident(Ident::invalid()));
-                    self.lint_if_path_starts_with_module(
+                    self.r.lint_if_path_starts_with_module(
                         directive.crate_lint(),
                         &full_path,
                         directive.span,
@@ -1006,7 +998,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                    max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
                    !max_vis.get().is_at_least(directive.vis.get(), &*self) {
                     let msg = "A non-empty glob must import something with the glob's visibility";
-                    self.session.span_err(directive.span, msg);
+                    self.r.session.span_err(directive.span, msg);
                 }
                 return None;
             }
@@ -1014,7 +1006,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         };
 
         let mut all_ns_err = true;
-        self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
+        self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
             let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
             let orig_blacklisted_binding =
                 mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
@@ -1069,7 +1061,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
         if all_ns_err {
             let mut all_ns_failed = true;
-            self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
+            self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
                 let binding = this.resolve_ident_in_module(
                     module, ident, ns, &directive.parent_scope, true, directive.span
                 );
@@ -1148,14 +1140,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 })
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
-                self.import_dummy_binding(directive);
+                self.r.import_dummy_binding(directive);
                 None
             }
         }
 
         let mut reexport_error = None;
         let mut any_successful_reexport = false;
-        self.per_ns(|this, ns| {
+        self.r.per_ns(|this, ns| {
             if let Ok(binding) = source_bindings[ns].get() {
                 let vis = directive.vis.get();
                 if !binding.pseudo_vis().is_at_least(vis, &*this) {
@@ -1174,12 +1166,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                                    re-exported (error E0365), consider declaring with \
                                    `pub`",
                                    ident);
-                self.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
+                self.r.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
                                          directive.id,
                                          directive.span,
                                          &msg);
             } else if ns == TypeNS {
-                struct_span_err!(self.session, directive.span, E0365,
+                struct_span_err!(self.r.session, directive.span, E0365,
                                  "`{}` is private, and cannot be re-exported", ident)
                     .span_label(directive.span, format!("re-export of private `{}`", ident))
                     .note(&format!("consider declaring type or module `{}` with `pub`", ident))
@@ -1188,7 +1180,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 let msg = format!("`{}` is private, and cannot be re-exported", ident);
                 let note_msg =
                     format!("consider marking `{}` as `pub` in the imported module", ident);
-                struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
+                struct_span_err!(self.r.session, directive.span, E0364, "{}", &msg)
                     .span_note(directive.span, &note_msg)
                     .emit();
             }
@@ -1199,7 +1191,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             // 2 segments, so the `resolve_path` above won't trigger it.
             let mut full_path = directive.module_path.clone();
             full_path.push(Segment::from_ident(ident));
-            self.per_ns(|this, ns| {
+            self.r.per_ns(|this, ns| {
                 if let Ok(binding) = source_bindings[ns].get() {
                     this.lint_if_path_starts_with_module(
                         directive.crate_lint(),
@@ -1214,7 +1206,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         // Record what this import resolves to for later uses in documentation,
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
-        self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
+        self.r.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
             this.import_res_map.entry(directive.id).or_default()[ns] = Some(binding.res());
         });
 
@@ -1261,7 +1253,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             macro_ns: None,
         };
 
-        self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
+        self.r.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
             if binding.res() == Res::Err {
                 return;
             }
@@ -1299,7 +1291,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
             redundant_spans.sort();
             redundant_spans.dedup();
-            self.session.buffer_lint_with_diagnostic(
+            self.r.session.buffer_lint_with_diagnostic(
                 UNUSED_IMPORTS,
                 directive.id,
                 directive.span,
@@ -1313,20 +1305,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         let module = match directive.imported_module.get().unwrap() {
             ModuleOrUniformRoot::Module(module) => module,
             _ => {
-                self.session.span_err(directive.span, "cannot glob-import all possible crates");
+                self.r.session.span_err(directive.span, "cannot glob-import all possible crates");
                 return;
             }
         };
 
-        self.populate_module_if_necessary(module);
+        self.r.populate_module_if_necessary(module);
 
         if module.is_trait() {
-            self.session.span_err(directive.span, "items in traits are not importable.");
+            self.r.session.span_err(directive.span, "items in traits are not importable.");
             return;
         } else if module.def_id() == directive.parent_scope.module.def_id()  {
             return;
         } else if let GlobImport { is_prelude: true, .. } = directive.subclass {
-            self.prelude = Some(module);
+            self.r.prelude = Some(module);
             return;
         }
 
@@ -1340,18 +1332,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         }).collect::<Vec<_>>();
         for ((mut ident, ns), binding) in bindings {
             let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) {
-                Some(Some(def)) => self.macro_def_scope(def),
+                Some(Some(def)) => self.r.macro_def_scope(def),
                 Some(None) => directive.parent_scope.module,
                 None => continue,
             };
-            if self.is_accessible_from(binding.pseudo_vis(), scope) {
-                let imported_binding = self.import(binding, directive);
-                let _ = self.try_define(directive.parent_scope.module, ident, ns, imported_binding);
+            if self.r.is_accessible_from(binding.pseudo_vis(), scope) {
+                let imported_binding = self.r.import(binding, directive);
+                let _ =
+                    self.r.try_define(directive.parent_scope.module, ident, ns, imported_binding);
             }
         }
 
         // Record the destination of this import
-        self.record_partial_res(directive.id, PartialRes::new(module.res().unwrap()));
+        self.r.record_partial_res(directive.id, PartialRes::new(module.res().unwrap()));
     }
 
     // Miscellaneous post-processing, including recording re-exports,
@@ -1380,7 +1373,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 if res != Res::Err {
                     if let Some(def_id) = res.opt_def_id() {
                         if !def_id.is_local() {
-                            self.cstore.export_macros_untracked(def_id.krate);
+                            self.r.cstore.export_macros_untracked(def_id.krate);
                         }
                     }
                     reexports.push(Export {
@@ -1406,7 +1399,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                                 let error_id = (DiagnosticMessageId::ErrorId(0), // no code?!
                                                 Some(binding.span),
                                                 msg.clone());
-                                let fresh = self.session.one_time_diagnostics
+                                let fresh = self.r.session.one_time_diagnostics
                                     .borrow_mut().insert(error_id);
                                 if !fresh {
                                     continue;
@@ -1415,7 +1408,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                             },
                             ref s @ _ => bug!("unexpected import subclass {:?}", s)
                         };
-                        let mut err = self.session.struct_span_err(binding.span, &msg);
+                        let mut err = self.r.session.struct_span_err(binding.span, &msg);
 
                         let imported_module = match directive.imported_module.get() {
                             Some(ModuleOrUniformRoot::Module(module)) => module,
@@ -1431,8 +1424,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                         let enum_span = enum_resolution.borrow()
                             .binding.expect("binding should exist")
                             .span;
-                        let enum_def_span = self.session.source_map().def_span(enum_span);
-                        let enum_def_snippet = self.session.source_map()
+                        let enum_def_span = self.r.session.source_map().def_span(enum_span);
+                        let enum_def_snippet = self.r.session.source_map()
                             .span_to_snippet(enum_def_span).expect("snippet should exist");
                         // potentially need to strip extant `crate`/`pub(path)` for suggestion
                         let after_vis_index = enum_def_snippet.find("enum")
@@ -1440,7 +1433,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                         let suggestion = format!("pub {}",
                                                  &enum_def_snippet[after_vis_index..]);
 
-                        self.session
+                        self.r.session
                             .diag_span_suggestion_once(&mut err,
                                                        DiagnosticMessageId::ErrorId(0),
                                                        enum_def_span,
@@ -1453,7 +1446,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
         if reexports.len() > 0 {
             if let Some(def_id) = module.def_id() {
-                self.export_map.insert(def_id, reexports);
+                self.r.export_map.insert(def_id, reexports);
             }
         }
     }