Skip to content

Commit 28eefb3

Browse files
committed
Move resolve_lifetimes query in librustc_resolve.
1 parent 2675765 commit 28eefb3

File tree

4 files changed

+188
-102
lines changed

4 files changed

+188
-102
lines changed
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//! Name resolution for lifetimes.
2+
//!
3+
//! Name resolution for lifetimes follows *much* simpler rules than the
4+
//! full resolve. For example, lifetime names are never exported or
5+
//! used between functions, and they operate in a purely top-down
6+
//! way. Therefore, we break lifetime name resolution into a separate pass.
7+
8+
use crate::hir::def_id::{DefId, LocalDefId};
9+
use crate::hir::{GenericParam, ItemLocalId};
10+
use crate::hir::{GenericParamKind, LifetimeParamKind};
11+
use crate::ty;
12+
13+
use crate::util::nodemap::{FxHashMap, FxHashSet, HirIdMap, HirIdSet};
14+
use rustc_macros::HashStable;
15+
16+
/// The origin of a named lifetime definition.
17+
///
18+
/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
19+
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
20+
pub enum LifetimeDefOrigin {
21+
// Explicit binders like `fn foo<'a>(x: &'a u8)` or elided like `impl Foo<&u32>`
22+
ExplicitOrElided,
23+
// In-band declarations like `fn foo(x: &'a u8)`
24+
InBand,
25+
// Some kind of erroneous origin
26+
Error,
27+
}
28+
29+
impl LifetimeDefOrigin {
30+
pub fn from_param(param: &GenericParam<'_>) -> Self {
31+
match param.kind {
32+
GenericParamKind::Lifetime { kind } => match kind {
33+
LifetimeParamKind::InBand => LifetimeDefOrigin::InBand,
34+
LifetimeParamKind::Explicit => LifetimeDefOrigin::ExplicitOrElided,
35+
LifetimeParamKind::Elided => LifetimeDefOrigin::ExplicitOrElided,
36+
LifetimeParamKind::Error => LifetimeDefOrigin::Error,
37+
},
38+
_ => bug!("expected a lifetime param"),
39+
}
40+
}
41+
}
42+
43+
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, HashStable)]
44+
pub enum Region {
45+
Static,
46+
EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin),
47+
LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin),
48+
LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
49+
Free(DefId, /* lifetime decl */ DefId),
50+
}
51+
52+
/// A set containing, at most, one known element.
53+
/// If two distinct values are inserted into a set, then it
54+
/// becomes `Many`, which can be used to detect ambiguities.
55+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable)]
56+
pub enum Set1<T> {
57+
Empty,
58+
One(T),
59+
Many,
60+
}
61+
62+
impl<T: PartialEq> Set1<T> {
63+
pub fn insert(&mut self, value: T) {
64+
*self = match self {
65+
Set1::Empty => Set1::One(value),
66+
Set1::One(old) if *old == value => return,
67+
_ => Set1::Many,
68+
};
69+
}
70+
}
71+
72+
pub type ObjectLifetimeDefault = Set1<Region>;
73+
74+
/// Maps the id of each lifetime reference to the lifetime decl
75+
/// that it corresponds to.
76+
#[derive(HashStable)]
77+
pub struct ResolveLifetimes {
78+
defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
79+
late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
80+
object_lifetime_defaults:
81+
FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
82+
}
83+
84+
impl ResolveLifetimes {
85+
pub fn new(
86+
defs: HirIdMap<Region>,
87+
late_bound: HirIdSet,
88+
object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
89+
) -> Self {
90+
let defs = {
91+
let mut map = FxHashMap::<_, FxHashMap<_, _>>::default();
92+
for (hir_id, v) in defs {
93+
let map = map.entry(hir_id.owner_local_def_id()).or_default();
94+
map.insert(hir_id.local_id, v);
95+
}
96+
map
97+
};
98+
let late_bound = {
99+
let mut map = FxHashMap::<_, FxHashSet<_>>::default();
100+
for hir_id in late_bound {
101+
let map = map.entry(hir_id.owner_local_def_id()).or_default();
102+
map.insert(hir_id.local_id);
103+
}
104+
map
105+
};
106+
let object_lifetime_defaults = {
107+
let mut map = FxHashMap::<_, FxHashMap<_, _>>::default();
108+
for (hir_id, v) in object_lifetime_defaults {
109+
let map = map.entry(hir_id.owner_local_def_id()).or_default();
110+
map.insert(hir_id.local_id, v);
111+
}
112+
map
113+
};
114+
115+
Self { defs, late_bound, object_lifetime_defaults }
116+
}
117+
118+
pub fn named_region_map(&self, id: &LocalDefId) -> Option<&FxHashMap<ItemLocalId, Region>> {
119+
self.defs.get(id)
120+
}
121+
122+
pub fn is_late_bound_map(&self, id: &LocalDefId) -> Option<&FxHashSet<ItemLocalId>> {
123+
self.late_bound.get(id)
124+
}
125+
126+
pub fn object_lifetime_defaults_map(
127+
&self,
128+
id: &LocalDefId,
129+
) -> Option<&FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
130+
self.object_lifetime_defaults.get(id)
131+
}
132+
}

src/librustc_interface/passes.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
1010
use rustc::hir::lowering::lower_crate;
1111
use rustc::lint;
1212
use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
13-
use rustc::middle::{self, resolve_lifetime, stability};
13+
use rustc::middle::{self, stability};
1414
use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType};
1515
use rustc::session::config::{PpMode, PpSourceMode};
1616
use rustc::session::search_paths::PathKind;
@@ -678,13 +678,13 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
678678
plugin::build::provide(providers);
679679
hir::provide(providers);
680680
mir::provide(providers);
681-
resolve_lifetime::provide(providers);
682681
rustc_privacy::provide(providers);
683682
typeck::provide(providers);
684683
ty::provide(providers);
685684
traits::provide(providers);
686685
stability::provide(providers);
687686
rustc_passes::provide(providers);
687+
rustc_resolve::provide(providers);
688688
rustc_traits::provide(providers);
689689
middle::region::provide(providers);
690690
rustc_metadata::provide(providers);

src/librustc_resolve/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
#![feature(nll)]
1717
#![recursion_limit = "256"]
1818

19+
#[macro_use]
20+
extern crate rustc;
21+
#[macro_use]
22+
extern crate log;
23+
#[macro_use]
24+
extern crate syntax;
25+
1926
pub use rustc::hir::def::{Namespace, PerNS};
2027

2128
use Determinacy::*;
@@ -30,6 +37,7 @@ use rustc::lint;
3037
use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
3138
use rustc::session::Session;
3239
use rustc::span_bug;
40+
use rustc::ty::query::Providers;
3341
use rustc::ty::{self, DefIdTree, ResolverOutputs};
3442
use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
3543

@@ -74,6 +82,7 @@ mod def_collector;
7482
mod diagnostics;
7583
mod imports;
7684
mod late;
85+
mod lifetimes;
7786
mod macros;
7887

7988
enum Weak {
@@ -3089,3 +3098,7 @@ impl CrateLint {
30893098
}
30903099
}
30913100
}
3101+
3102+
pub fn provide(providers: &mut Providers<'_>) {
3103+
lifetimes::provide(providers);
3104+
}

0 commit comments

Comments
 (0)