提交 b49da276 编写于 作者: N Nick Cameron

Store a resolved def on hir::PathSegment

上级 fc67d8fa
......@@ -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>;
......@@ -163,7 +168,7 @@ fn resolve_str_path(
span: Span,
crate_root: Option<&str>,
components: &[&str],
params: Option<P<hir::GenericArgs>>,
args: Option<P<hir::GenericArgs>>,
is_value: bool,
) -> hir::Path;
}
......@@ -1380,6 +1385,7 @@ fn lower_existential_impl_trait(
// 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)
})
......@@ -1852,8 +1858,10 @@ fn lower_path_segment(
}
}
let def = self.expect_full_def(segment.id);
hir::PathSegment::new(
segment.ident,
Some(def),
generic_args,
infer_types,
)
......
......@@ -347,6 +347,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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
......@@ -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
......
......@@ -174,6 +174,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl_stable_hash_for!(struct hir::PathSegment {
ident -> (ident.name),
def,
infer_types,
args
});
......
......@@ -141,7 +141,7 @@ fn build_reduced_graph_for_use_tree(
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()
});
......@@ -202,13 +202,13 @@ fn build_reduced_graph_for_use_tree(
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)),
......@@ -219,7 +219,7 @@ fn build_reduced_graph_for_use_tree(
this.add_import_directive(
base.into_iter().collect(),
subclass.clone(),
source.span,
source.0.span,
id,
root_use_tree.span,
root_id,
......@@ -230,15 +230,15 @@ fn build_reduced_graph_for_use_tree(
};
// 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),
......@@ -265,10 +265,10 @@ fn build_reduced_graph_for_use_tree(
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 {
......@@ -284,20 +284,20 @@ fn build_reduced_graph_for_use_tree(
// 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!(),
......@@ -307,11 +307,11 @@ fn build_reduced_graph_for_use_tree(
// 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;
......@@ -332,7 +332,7 @@ fn build_reduced_graph_for_use_tree(
let subclass = SingleImport {
target: ident,
source,
source: source.0,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
......@@ -393,6 +393,17 @@ fn build_reduced_graph_for_use_tree(
}
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,
......
此差异已折叠。
......@@ -462,13 +462,13 @@ pub fn resolve_macro_to_def_inner(
force: bool,
) -> Result<Def, Determinacy> {
let ast::Path { ref segments, span } = *path;
let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
let mut path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect();
// Possibly apply the macro helper hack
if kind == MacroKind::Bang && path.len() == 1 &&
path[0].span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) {
let root = Ident::new(keywords::DollarCrate.name(), path[0].span);
path.insert(0, root);
path[0].0.span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) {
let root = Ident::new(keywords::DollarCrate.name(), path[0].0.span);
path.insert(0, (root, None));
}
if path.len() > 1 {
......@@ -496,12 +496,16 @@ pub fn resolve_macro_to_def_inner(
};
parent_scope.module.macro_resolutions.borrow_mut()
.push((path.into_boxed_slice(), span));
.push((path
.iter()
.map(|(ident, _)| *ident)
.collect::<Vec<Ident>>()
.into_boxed_slice(), span));
def
} else {
let binding = self.early_resolve_ident_in_lexical_scope(
path[0], MacroNS, Some(kind), parent_scope, false, force, span
path[0].0, MacroNS, Some(kind), parent_scope, false, force, span
);
match binding {
Ok(..) => {}
......@@ -510,7 +514,7 @@ pub fn resolve_macro_to_def_inner(
}
parent_scope.module.legacy_macro_resolutions.borrow_mut()
.push((path[0], kind, parent_scope.clone(), binding.ok()));
.push((path[0].0, kind, parent_scope.clone(), binding.ok()));
binding.map(|binding| binding.def_ignoring_ambiguity())
}
......@@ -846,6 +850,10 @@ struct Flags: u8 {
pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module;
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
let path = path
.iter()
.map(|ident| (*ident, None))
.collect::<Vec<(Ident, Option<ast::NodeId>)>>();
match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) {
PathResult::NonModule(_) => {},
PathResult::Failed(span, msg, _) => {
......@@ -938,7 +946,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
}
};
let ident = Ident::new(Symbol::intern(name), span);
self.lookup_typo_candidate(&[ident], MacroNS, is_macro, span)
self.lookup_typo_candidate(&[(ident, None)], MacroNS, is_macro, span)
});
if let Some(suggestion) = suggestion {
......
......@@ -14,7 +14,7 @@
use Namespace::{self, TypeNS, MacroNS};
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use Resolver;
use {names_to_string, module_to_string};
use {names_to_string, names_and_ids_to_string, module_to_string};
use {resolve_error, ResolutionError};
use rustc_data_structures::ptr_key::PtrKey;
......@@ -89,7 +89,7 @@ pub struct ImportDirective<'a> {
pub root_span: Span,
pub parent: Module<'a>,
pub module_path: Vec<Ident>,
pub module_path: Vec<(Ident, Option<NodeId>)>,
/// The resolution of `module_path`.
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
pub subclass: ImportDirectiveSubclass<'a>,
......@@ -393,7 +393,7 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
// Add an import directive to the current module.
pub fn add_import_directive(&mut self,
module_path: Vec<Ident>,
module_path: Vec<(Ident, Option<NodeId>)>,
subclass: ImportDirectiveSubclass<'a>,
span: Span,
id: NodeId,
......@@ -679,7 +679,7 @@ struct UniformPathsCanaryResults<'a> {
let has_explicit_self =
!import.module_path.is_empty() &&
import.module_path[0].name == keywords::SelfValue.name();
import.module_path[0].0.name == keywords::SelfValue.name();
self.per_ns(|_, ns| {
if let Some(result) = result[ns].get().ok() {
......@@ -728,9 +728,11 @@ struct UniformPathsCanaryResults<'a> {
self.throw_unresolved_import_error(empty_vec, None);
}
if !seen_spans.contains(&span) {
let path = import_path_to_string(&import.module_path[..],
&import.subclass,
span);
let path = import_path_to_string(
&import.module_path.iter().map(|(ident, _)| *ident).collect::<Vec<_>>(),
&import.subclass,
span,
);
error_vec.push((span, path, err));
seen_spans.insert(span);
prev_root_id = import.root_id;
......@@ -851,7 +853,7 @@ fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>,
/// If successful, the resolved bindings are written into the module.
fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
debug!("(resolving import for module) resolving import `{}::...` in `{}`",
names_to_string(&directive.module_path[..]),
names_and_ids_to_string(&directive.module_path[..]),
module_to_string(self.current_module).unwrap_or_else(|| "???".to_string()));
self.current_module = directive.parent;
......@@ -982,7 +984,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
let mut full_path = module_path.clone();
full_path.push(keywords::Invalid.ident());
full_path.push((keywords::Invalid.ident(), None));
self.lint_if_path_starts_with_module(
directive.crate_lint(),
&full_path,
......@@ -1146,7 +1148,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
let mut full_path = module_path.clone();
full_path.push(ident);
full_path.push((ident, None));
self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() {
this.lint_if_path_starts_with_module(
......@@ -1288,7 +1290,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
let resolutions = imported_module.parent.expect("parent should exist")
.resolutions.borrow();
let enum_path_segment_index = directive.module_path.len() - 1;
let enum_ident = directive.module_path[enum_path_segment_index];
let enum_ident = directive.module_path[enum_path_segment_index].0;
let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
.expect("resolution should exist");
......@@ -1311,6 +1313,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
"consider making the enum public",
suggestion);
err.emit();
}
}
}
}
......
......@@ -147,7 +147,7 @@ pub fn from_ident(ident: Ident) -> Self {
pub fn crate_root(span: Span) -> Self {
PathSegment {
ident: Ident::new(keywords::CrateRoot.name(), span),
id: CRATE_NODE_ID,
id: DUMMY_NODE_ID,
args: None,
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册