From 2675765a1ea562000e785e100974efb9a7aaec08 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Dec 2019 10:47:49 +0100 Subject: [PATCH 1/5] Move resolve_lifetime.rs to librustc_resolve. --- .../middle/resolve_lifetime.rs => librustc_resolve/lifetimes.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/middle/resolve_lifetime.rs => librustc_resolve/lifetimes.rs} (100%) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc_resolve/lifetimes.rs similarity index 100% rename from src/librustc/middle/resolve_lifetime.rs rename to src/librustc_resolve/lifetimes.rs From 28eefb37974df9a70fdfd1853f541cb950c8068e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Dec 2019 10:48:52 +0100 Subject: [PATCH 2/5] Move resolve_lifetimes query in librustc_resolve. --- src/librustc/middle/resolve_lifetime.rs | 132 ++++++++++++++++++++++ src/librustc_interface/passes.rs | 4 +- src/librustc_resolve/lib.rs | 13 +++ src/librustc_resolve/lifetimes.rs | 141 +++++++----------------- 4 files changed, 188 insertions(+), 102 deletions(-) create mode 100644 src/librustc/middle/resolve_lifetime.rs diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs new file mode 100644 index 0000000000000..8e55e067513f2 --- /dev/null +++ b/src/librustc/middle/resolve_lifetime.rs @@ -0,0 +1,132 @@ +//! Name resolution for lifetimes. +//! +//! Name resolution for lifetimes follows *much* simpler rules than the +//! full resolve. For example, lifetime names are never exported or +//! used between functions, and they operate in a purely top-down +//! way. Therefore, we break lifetime name resolution into a separate pass. + +use crate::hir::def_id::{DefId, LocalDefId}; +use crate::hir::{GenericParam, ItemLocalId}; +use crate::hir::{GenericParamKind, LifetimeParamKind}; +use crate::ty; + +use crate::util::nodemap::{FxHashMap, FxHashSet, HirIdMap, HirIdSet}; +use rustc_macros::HashStable; + +/// The origin of a named lifetime definition. +/// +/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax. +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)] +pub enum LifetimeDefOrigin { + // Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>` + ExplicitOrElided, + // In-band declarations like `fn foo(x: &'a u8)` + InBand, + // Some kind of erroneous origin + Error, +} + +impl LifetimeDefOrigin { + pub fn from_param(param: &GenericParam<'_>) -> Self { + match param.kind { + GenericParamKind::Lifetime { kind } => match kind { + LifetimeParamKind::InBand => LifetimeDefOrigin::InBand, + LifetimeParamKind::Explicit => LifetimeDefOrigin::ExplicitOrElided, + LifetimeParamKind::Elided => LifetimeDefOrigin::ExplicitOrElided, + LifetimeParamKind::Error => LifetimeDefOrigin::Error, + }, + _ => bug!("expected a lifetime param"), + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)] +pub enum Region { + Static, + EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin), + LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin), + LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), + Free(DefId, /* lifetime decl */ DefId), +} + +/// A set containing, at most, one known element. +/// If two distinct values are inserted into a set, then it +/// becomes `Many`, which can be used to detect ambiguities. +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)] +pub enum Set1 { + Empty, + One(T), + Many, +} + +impl Set1 { + pub fn insert(&mut self, value: T) { + *self = match self { + Set1::Empty => Set1::One(value), + Set1::One(old) if *old == value => return, + _ => Set1::Many, + }; + } +} + +pub type ObjectLifetimeDefault = Set1; + +/// Maps the id of each lifetime reference to the lifetime decl +/// that it corresponds to. +#[derive(HashStable)] +pub struct ResolveLifetimes { + defs: FxHashMap>, + late_bound: FxHashMap>, + object_lifetime_defaults: + FxHashMap>>, +} + +impl ResolveLifetimes { + pub fn new( + defs: HirIdMap, + late_bound: HirIdSet, + object_lifetime_defaults: HirIdMap>, + ) -> Self { + let defs = { + let mut map = FxHashMap::<_, FxHashMap<_, _>>::default(); + for (hir_id, v) in defs { + let map = map.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id, v); + } + map + }; + let late_bound = { + let mut map = FxHashMap::<_, FxHashSet<_>>::default(); + for hir_id in late_bound { + let map = map.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id); + } + map + }; + let object_lifetime_defaults = { + let mut map = FxHashMap::<_, FxHashMap<_, _>>::default(); + for (hir_id, v) in object_lifetime_defaults { + let map = map.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id, v); + } + map + }; + + Self { defs, late_bound, object_lifetime_defaults } + } + + pub fn named_region_map(&self, id: &LocalDefId) -> Option<&FxHashMap> { + self.defs.get(id) + } + + pub fn is_late_bound_map(&self, id: &LocalDefId) -> Option<&FxHashSet> { + self.late_bound.get(id) + } + + pub fn object_lifetime_defaults_map( + &self, + id: &LocalDefId, + ) -> Option<&FxHashMap>> { + self.object_lifetime_defaults.get(id) + } +} diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 57fd2fb6d2783..f519d5ab50a40 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -10,7 +10,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::hir::lowering::lower_crate; use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; -use rustc::middle::{self, resolve_lifetime, stability}; +use rustc::middle::{self, stability}; use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType}; use rustc::session::config::{PpMode, PpSourceMode}; use rustc::session::search_paths::PathKind; @@ -678,13 +678,13 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { plugin::build::provide(providers); hir::provide(providers); mir::provide(providers); - resolve_lifetime::provide(providers); rustc_privacy::provide(providers); typeck::provide(providers); ty::provide(providers); traits::provide(providers); stability::provide(providers); rustc_passes::provide(providers); + rustc_resolve::provide(providers); rustc_traits::provide(providers); middle::region::provide(providers); rustc_metadata::provide(providers); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 357176ae090ca..4daf22d1b2bb2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -16,6 +16,13 @@ #![feature(nll)] #![recursion_limit = "256"] +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate log; +#[macro_use] +extern crate syntax; + pub use rustc::hir::def::{Namespace, PerNS}; use Determinacy::*; @@ -30,6 +37,7 @@ use rustc::lint; use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::session::Session; use rustc::span_bug; +use rustc::ty::query::Providers; use rustc::ty::{self, DefIdTree, ResolverOutputs}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet}; @@ -74,6 +82,7 @@ mod def_collector; mod diagnostics; mod imports; mod late; +mod lifetimes; mod macros; enum Weak { @@ -3089,3 +3098,7 @@ impl CrateLint { } } } + +pub fn provide(providers: &mut Providers<'_>) { + lifetimes::provide(providers); +} diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 5f8a58636c083..3bcd104246d06 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -5,17 +5,16 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. -use crate::hir::def::{DefKind, Res}; -use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; -use crate::hir::map::Map; -use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName, QPath}; -use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; - -use crate::rustc::lint; -use crate::session::Session; -use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; +use rustc::hir::def::{DefKind, Res}; +use rustc::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; +use rustc::hir::map::Map; +use rustc::hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath}; +use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; + use errors::{pluralize, Applicability, DiagnosticBuilder}; -use rustc_macros::HashStable; +use rustc::lint; +use rustc::session::Session; +use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; use std::borrow::Cow; use std::cell::Cell; use std::mem::{replace, take}; @@ -24,38 +23,12 @@ use syntax::attr; use syntax::symbol::{kw, sym}; use syntax_pos::Span; -use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; -use crate::hir::{self, GenericParamKind, LifetimeParamKind}; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc::hir::{self, GenericParamKind, LifetimeParamKind}; +use rustc::middle::resolve_lifetime::*; use rustc_error_codes::*; -/// The origin of a named lifetime definition. -/// -/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax. -#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)] -pub enum LifetimeDefOrigin { - // Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>` - ExplicitOrElided, - // In-band declarations like `fn foo(x: &'a u8)` - InBand, - // Some kind of erroneous origin - Error, -} - -impl LifetimeDefOrigin { - fn from_param(param: &GenericParam<'_>) -> Self { - match param.kind { - GenericParamKind::Lifetime { kind } => match kind { - LifetimeParamKind::InBand => LifetimeDefOrigin::InBand, - LifetimeParamKind::Explicit => LifetimeDefOrigin::ExplicitOrElided, - LifetimeParamKind::Elided => LifetimeDefOrigin::ExplicitOrElided, - LifetimeParamKind::Error => LifetimeDefOrigin::Error, - }, - _ => bug!("expected a lifetime param"), - } - } -} - // This counts the no of times a lifetime is used #[derive(Clone, Copy, Debug)] pub enum LifetimeUseSet<'tcx> { @@ -63,16 +36,25 @@ pub enum LifetimeUseSet<'tcx> { Many, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)] -pub enum Region { - Static, - EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin), - LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin), - LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), - Free(DefId, /* lifetime decl */ DefId), +trait RegionExt { + fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region); + + fn late(hir_map: &Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); + + fn late_anon(index: &Cell) -> Region; + + fn id(&self) -> Option; + + fn shifted(self, amount: u32) -> Region; + + fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region; + + fn subst<'a, L>(self, params: L, map: &NamedRegionMap) -> Option + where + L: Iterator; } -impl Region { +impl RegionExt for Region { fn early(hir_map: &Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region) { let i = *index; *index += 1; @@ -146,28 +128,6 @@ impl Region { } } -/// A set containing, at most, one known element. -/// If two distinct values are inserted into a set, then it -/// becomes `Many`, which can be used to detect ambiguities. -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)] -pub enum Set1 { - Empty, - One(T), - Many, -} - -impl Set1 { - pub fn insert(&mut self, value: T) { - *self = match self { - Set1::Empty => Set1::One(value), - Set1::One(old) if *old == value => return, - _ => Set1::Many, - }; - } -} - -pub type ObjectLifetimeDefault = Set1; - /// Maps the id of each lifetime reference to the lifetime decl /// that it corresponds to. /// @@ -178,25 +138,16 @@ pub type ObjectLifetimeDefault = Set1; struct NamedRegionMap { // maps from every use of a named (not anonymous) lifetime to a // `Region` describing how that region is bound - pub defs: HirIdMap, + defs: HirIdMap, // the set of lifetime def ids that are late-bound; a region can // be late-bound if (a) it does NOT appear in a where-clause and // (b) it DOES appear in the arguments. - pub late_bound: HirIdSet, + late_bound: HirIdSet, // For each type and trait definition, maps type parameters // to the trait object lifetime defaults computed from them. - pub object_lifetime_defaults: HirIdMap>, -} - -/// See [`NamedRegionMap`]. -#[derive(Default, HashStable)] -pub struct ResolveLifetimes { - defs: FxHashMap>, - late_bound: FxHashMap>, - object_lifetime_defaults: - FxHashMap>>, + object_lifetime_defaults: HirIdMap>, } struct LifetimeContext<'a, 'tcx> { @@ -323,17 +274,17 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { named_region_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).named_region_map(&id) }, is_late_bound_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).is_late_bound_map(&id) }, object_lifetime_defaults_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults_map(&id) }, ..*providers @@ -351,21 +302,11 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> &ResolveLifetimes let named_region_map = krate(tcx); - let mut rl = ResolveLifetimes::default(); - - for (hir_id, v) in named_region_map.defs { - let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id, v); - } - for hir_id in named_region_map.late_bound { - let map = rl.late_bound.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id); - } - for (hir_id, v) in named_region_map.object_lifetime_defaults { - let map = rl.object_lifetime_defaults.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id, v); - } - + let rl = ResolveLifetimes::new( + named_region_map.defs, + named_region_map.late_bound, + named_region_map.object_lifetime_defaults, + ); tcx.arena.alloc(rl) } @@ -2899,7 +2840,7 @@ fn insert_late_bound_lifetimes( } } -pub fn report_missing_lifetime_specifiers( +fn report_missing_lifetime_specifiers( sess: &Session, span: Span, count: usize, From 1b92e7e44640e69a48c92d31cee19f982d4e6140 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Dec 2019 11:17:20 +0100 Subject: [PATCH 3/5] Inert doc comments. --- src/librustc_resolve/lifetimes.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 3bcd104246d06..5e099dba897b3 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -203,7 +203,9 @@ enum Scope<'a> { /// Whether or not this binder would serve as the parent /// binder for opaque types introduced within. For example: /// + /// ```text /// fn foo<'a>() -> impl for<'b> Trait> + /// ``` /// /// Here, the opaque types we create for the `impl Trait` /// and `impl Trait2` references will both have the `foo` item From 31f85d3fe2b447e31017eb01e6aec8af30ec5a14 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Dec 2019 20:45:48 +0100 Subject: [PATCH 4/5] Review comments. --- src/librustc/middle/resolve_lifetime.rs | 7 +------ src/librustc_resolve/lib.rs | 7 ------- src/librustc_resolve/lifetimes.rs | 4 ++++ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8e55e067513f2..a07f21fcbbed6 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1,9 +1,4 @@ -//! Name resolution for lifetimes. -//! -//! Name resolution for lifetimes follows *much* simpler rules than the -//! full resolve. For example, lifetime names are never exported or -//! used between functions, and they operate in a purely top-down -//! way. Therefore, we break lifetime name resolution into a separate pass. +//! Name resolution for lifetimes: type declarations. use crate::hir::def_id::{DefId, LocalDefId}; use crate::hir::{GenericParam, ItemLocalId}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4daf22d1b2bb2..fa3e6291c300c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -16,13 +16,6 @@ #![feature(nll)] #![recursion_limit = "256"] -#[macro_use] -extern crate rustc; -#[macro_use] -extern crate log; -#[macro_use] -extern crate syntax; - pub use rustc::hir::def::{Namespace, PerNS}; use Determinacy::*; diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index 5e099dba897b3..b2b5c387eb8b7 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -26,6 +26,10 @@ use syntax_pos::Span; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::hir::{self, GenericParamKind, LifetimeParamKind}; +use log::debug; +use rustc::{bug, span_bug}; +use syntax::{help, span_err, struct_span_err, walk_list}; + use rustc::middle::resolve_lifetime::*; use rustc_error_codes::*; From 7e4345ca798cf5d2edc11dd6c3311f9b89c42261 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 30 Dec 2019 12:48:32 +0100 Subject: [PATCH 5/5] Simplify ResolveLiftimes creation. --- src/librustc/middle/resolve_lifetime.rs | 67 +++++-------------------- src/librustc_resolve/lifetimes.rs | 26 +++++++--- 2 files changed, 31 insertions(+), 62 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a07f21fcbbed6..6926ed24afdfb 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -5,7 +5,7 @@ use crate::hir::{GenericParam, ItemLocalId}; use crate::hir::{GenericParamKind, LifetimeParamKind}; use crate::ty; -use crate::util::nodemap::{FxHashMap, FxHashSet, HirIdMap, HirIdSet}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use rustc_macros::HashStable; /// The origin of a named lifetime definition. @@ -68,60 +68,19 @@ pub type ObjectLifetimeDefault = Set1; /// Maps the id of each lifetime reference to the lifetime decl /// that it corresponds to. -#[derive(HashStable)] +#[derive(Default, HashStable)] pub struct ResolveLifetimes { - defs: FxHashMap>, - late_bound: FxHashMap>, - object_lifetime_defaults: - FxHashMap>>, -} + /// Maps from every use of a named (not anonymous) lifetime to a + /// `Region` describing how that region is bound + pub defs: FxHashMap>, -impl ResolveLifetimes { - pub fn new( - defs: HirIdMap, - late_bound: HirIdSet, - object_lifetime_defaults: HirIdMap>, - ) -> Self { - let defs = { - let mut map = FxHashMap::<_, FxHashMap<_, _>>::default(); - for (hir_id, v) in defs { - let map = map.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id, v); - } - map - }; - let late_bound = { - let mut map = FxHashMap::<_, FxHashSet<_>>::default(); - for hir_id in late_bound { - let map = map.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id); - } - map - }; - let object_lifetime_defaults = { - let mut map = FxHashMap::<_, FxHashMap<_, _>>::default(); - for (hir_id, v) in object_lifetime_defaults { - let map = map.entry(hir_id.owner_local_def_id()).or_default(); - map.insert(hir_id.local_id, v); - } - map - }; - - Self { defs, late_bound, object_lifetime_defaults } - } + /// Set of lifetime def ids that are late-bound; a region can + /// be late-bound if (a) it does NOT appear in a where-clause and + /// (b) it DOES appear in the arguments. + pub late_bound: FxHashMap>, - pub fn named_region_map(&self, id: &LocalDefId) -> Option<&FxHashMap> { - self.defs.get(id) - } - - pub fn is_late_bound_map(&self, id: &LocalDefId) -> Option<&FxHashSet> { - self.late_bound.get(id) - } - - pub fn object_lifetime_defaults_map( - &self, - id: &LocalDefId, - ) -> Option<&FxHashMap>> { - self.object_lifetime_defaults.get(id) - } + /// For each type and trait definition, maps type parameters + /// to the trait object lifetime defaults computed from them. + pub object_lifetime_defaults: + FxHashMap>>, } diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index b2b5c387eb8b7..345974ae243e9 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -280,17 +280,17 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { named_region_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).named_region_map(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id) }, is_late_bound_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).is_late_bound_map(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&id) }, object_lifetime_defaults_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults_map(&id) + tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id) }, ..*providers @@ -308,11 +308,21 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> &ResolveLifetimes let named_region_map = krate(tcx); - let rl = ResolveLifetimes::new( - named_region_map.defs, - named_region_map.late_bound, - named_region_map.object_lifetime_defaults, - ); + let mut rl = ResolveLifetimes::default(); + + for (hir_id, v) in named_region_map.defs { + let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id, v); + } + for hir_id in named_region_map.late_bound { + let map = rl.late_bound.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id); + } + for (hir_id, v) in named_region_map.object_lifetime_defaults { + let map = rl.object_lifetime_defaults.entry(hir_id.owner_local_def_id()).or_default(); + map.insert(hir_id.local_id, v); + } + tcx.arena.alloc(rl) }