Skip to content

Commit

Permalink
Store a resolved def on hir::PathSegment
Browse files Browse the repository at this point in the history
  • Loading branch information
nrc committed Oct 25, 2018
1 parent fc67d8f commit b49da27
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 111 deletions.
14 changes: 11 additions & 3 deletions src/librustc/hir/lowering.rs
Expand Up @@ -143,8 +143,13 @@ pub struct LoweringContext<'a> {
}

pub trait Resolver {
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
fn resolve_hir_path(
&mut self,
path: &ast::Path,
args: Option<P<hir::GenericArgs>>,
is_value: bool,
) -> hir::Path;

/// Obtain the resolution for a node id
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
Expand All @@ -163,7 +168,7 @@ pub trait Resolver {
span: Span,
crate_root: Option<&str>,
components: &[&str],
params: Option<P<hir::GenericArgs>>,
args: Option<P<hir::GenericArgs>>,
is_value: bool,
) -> hir::Path;
}
Expand Down Expand Up @@ -1380,6 +1385,7 @@ impl<'a> LoweringContext<'a> {
// does not actually exist in the AST.
lctx.items.insert(exist_ty_id.node_id, exist_ty_item);

let def = Def::Existential(DefId::local(exist_ty_def_index));
// `impl Trait` now just becomes `Foo<'a, 'b, ..>`
hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
})
Expand Down Expand Up @@ -1852,8 +1858,10 @@ impl<'a> LoweringContext<'a> {
}
}

let def = self.expect_full_def(segment.id);
hir::PathSegment::new(
segment.ident,
Some(def),
generic_args,
infer_types,
)
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/hir/mod.rs
Expand Up @@ -347,6 +347,7 @@ impl fmt::Display for Path {
pub struct PathSegment {
/// The identifier portion of this path segment.
pub ident: Ident,
pub def: Option<Def>,

/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
Expand All @@ -367,14 +368,16 @@ impl PathSegment {
pub fn from_ident(ident: Ident) -> PathSegment {
PathSegment {
ident,
def: None,
infer_types: true,
args: None,
}
}

pub fn new(ident: Ident, args: GenericArgs, infer_types: bool) -> Self {
pub fn new(ident: Ident, def: Option<Def>, args: GenericArgs, infer_types: bool) -> Self {
PathSegment {
ident,
def,
infer_types,
args: if args.is_empty() {
None
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ich/impls_hir.rs
Expand Up @@ -174,6 +174,7 @@ impl_stable_hash_for!(struct hir::Path {

impl_stable_hash_for!(struct hir::PathSegment {
ident -> (ident.name),
def,
infer_types,
args
});
Expand Down
51 changes: 31 additions & 20 deletions src/librustc_resolve/build_reduced_graph.rs
Expand Up @@ -141,7 +141,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let prefix_iter = || parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.ident));
let prefix_start = prefix_iter().next();
let starts_with_non_keyword = prefix_start.map_or(false, |ident| {
let starts_with_non_keyword = prefix_start.map_or(false, |(ident, _)| {
!ident.is_path_segment_keyword()
});

Expand Down Expand Up @@ -202,13 +202,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let source = prefix_start.unwrap();

// Helper closure to emit a canary with the given base path.
let emit = |this: &mut Self, base: Option<Ident>| {
let emit = |this: &mut Self, base: Option<(Ident, Option<NodeId>)>| {
let subclass = SingleImport {
target: Ident {
name: keywords::Underscore.name().gensymed(),
span: source.span,
span: source.0.span,
},
source,
source: source.0,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
Expand All @@ -219,7 +219,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
this.add_import_directive(
base.into_iter().collect(),
subclass.clone(),
source.span,
source.0.span,
id,
root_use_tree.span,
root_id,
Expand All @@ -230,15 +230,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
};

// A single simple `self::x` canary.
emit(self, Some(Ident {
emit(self, Some((Ident {
name: keywords::SelfValue.name(),
span: source.span,
}));
span: source.0.span,
}, source.1)));

// One special unprefixed canary per block scope around
// the import, to detect items unreachable by `self::x`.
let orig_current_module = self.current_module;
let mut span = source.span.modern();
let mut span = source.0.span.modern();
loop {
match self.current_module.kind {
ModuleKind::Block(..) => emit(self, None),
Expand All @@ -265,10 +265,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {

if nested {
// Correctly handle `self`
if source.name == keywords::SelfValue.name() {
if source.0.name == keywords::SelfValue.name() {
type_ns_only = true;

let empty_prefix = module_path.last().map_or(true, |ident| {
let empty_prefix = module_path.last().map_or(true, |(ident, _)| {
ident.name == keywords::CrateRoot.name()
});
if empty_prefix {
Expand All @@ -284,20 +284,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// Replace `use foo::self;` with `use foo;`
source = module_path.pop().unwrap();
if rename.is_none() {
ident = source;
ident = source.0;
}
}
} else {
// Disallow `self`
if source.name == keywords::SelfValue.name() {
if source.0.name == keywords::SelfValue.name() {
resolve_error(self,
use_tree.span,
ResolutionError::SelfImportsOnlyAllowedWithin);
}

// Disallow `use $crate;`
if source.name == keywords::DollarCrate.name() && module_path.is_empty() {
let crate_root = self.resolve_crate_root(source);
if source.0.name == keywords::DollarCrate.name() && module_path.is_empty() {
let crate_root = self.resolve_crate_root(source.0);
let crate_name = match crate_root.kind {
ModuleKind::Def(_, name) => name,
ModuleKind::Block(..) => unreachable!(),
Expand All @@ -307,11 +307,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// while the current crate doesn't have a valid `crate_name`.
if crate_name != keywords::Invalid.name() {
// `crate_name` should not be interpreted as relative.
module_path.push(Ident {
module_path.push((Ident {
name: keywords::CrateRoot.name(),
span: source.span,
});
source.name = crate_name;
span: source.0.span,
}, Some(self.session.next_node_id())));
source.0.name = crate_name;
}
if rename.is_none() {
ident.name = crate_name;
Expand All @@ -332,7 +332,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {

let subclass = SingleImport {
target: ident,
source,
source: source.0,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
Expand Down Expand Up @@ -393,6 +393,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}

for &(ref tree, id) in items {
let prefix = ast::Path {
segments: module_path.iter()
.map(|ident| {
let mut seg = ast::PathSegment::from_ident(ident.0);
seg.id = self.session.next_node_id();
seg
})
.collect(),
span: path.span,
};

self.build_reduced_graph_for_use_tree(
root_use_tree,
root_id,
Expand Down

0 comments on commit b49da27

Please sign in to comment.