about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2019-12-29 10:48:52 +0100
committerCamille GILLOT <gillot.camille@gmail.com>2019-12-31 10:21:32 +0100
commit28eefb37974df9a70fdfd1853f541cb950c8068e (patch)
treeed0f75ab61e40bc374c6ea2632fd8ea1c63cebd0
parent2675765a1ea562000e785e100974efb9a7aaec08 (diff)
downloadrust-28eefb37974df9a70fdfd1853f541cb950c8068e.tar.gz
rust-28eefb37974df9a70fdfd1853f541cb950c8068e.zip
Move resolve_lifetimes query in librustc_resolve.
-rw-r--r--src/librustc/middle/resolve_lifetime.rs132
-rw-r--r--src/librustc_interface/passes.rs4
-rw-r--r--src/librustc_resolve/lib.rs13
-rw-r--r--src/librustc_resolve/lifetimes.rs141
4 files changed, 188 insertions, 102 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
new file mode 100644
index 00000000000..8e55e067513
--- /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<T> {
+    Empty,
+    One(T),
+    Many,
+}
+
+impl<T: PartialEq> Set1<T> {
+    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<Region>;
+
+/// Maps the id of each lifetime reference to the lifetime decl
+/// that it corresponds to.
+#[derive(HashStable)]
+pub struct ResolveLifetimes {
+    defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
+    late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
+    object_lifetime_defaults:
+        FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
+}
+
+impl ResolveLifetimes {
+    pub fn new(
+        defs: HirIdMap<Region>,
+        late_bound: HirIdSet,
+        object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
+    ) -> 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<ItemLocalId, Region>> {
+        self.defs.get(id)
+    }
+
+    pub fn is_late_bound_map(&self, id: &LocalDefId) -> Option<&FxHashSet<ItemLocalId>> {
+        self.late_bound.get(id)
+    }
+
+    pub fn object_lifetime_defaults_map(
+        &self,
+        id: &LocalDefId,
+    ) -> Option<&FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
+        self.object_lifetime_defaults.get(id)
+    }
+}
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 57fd2fb6d27..f519d5ab50a 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 357176ae090..4daf22d1b2b 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 5f8a58636c0..3bcd104246d 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<u32>) -> Region;
+
+    fn id(&self) -> Option<DefId>;
+
+    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<Region>
+    where
+        L: Iterator<Item = &'a hir::Lifetime>;
 }
 
-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<T> {
-    Empty,
-    One(T),
-    Many,
-}
-
-impl<T: PartialEq> Set1<T> {
-    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<Region>;
-
 /// Maps the id of each lifetime reference to the lifetime decl
 /// that it corresponds to.
 ///
@@ -178,25 +138,16 @@ pub type ObjectLifetimeDefault = Set1<Region>;
 struct NamedRegionMap {
     // maps from every use of a named (not anonymous) lifetime to a
     // `Region` describing how that region is bound
-    pub defs: HirIdMap<Region>,
+    defs: HirIdMap<Region>,
 
     // 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<Vec<ObjectLifetimeDefault>>,
-}
-
-/// See [`NamedRegionMap`].
-#[derive(Default, HashStable)]
-pub struct ResolveLifetimes {
-    defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
-    late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
-    object_lifetime_defaults:
-        FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
+    object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
 }
 
 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,