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

Store a resolved def on hir::PathSegment

上级 fc67d8fa
...@@ -143,8 +143,13 @@ pub struct LoweringContext<'a> { ...@@ -143,8 +143,13 @@ pub struct LoweringContext<'a> {
} }
pub trait Resolver { pub trait Resolver {
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc. /// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool); 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 /// Obtain the resolution for a node id
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>; fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
...@@ -163,7 +168,7 @@ fn resolve_str_path( ...@@ -163,7 +168,7 @@ fn resolve_str_path(
span: Span, span: Span,
crate_root: Option<&str>, crate_root: Option<&str>,
components: &[&str], components: &[&str],
params: Option<P<hir::GenericArgs>>, args: Option<P<hir::GenericArgs>>,
is_value: bool, is_value: bool,
) -> hir::Path; ) -> hir::Path;
} }
...@@ -1380,6 +1385,7 @@ fn lower_existential_impl_trait( ...@@ -1380,6 +1385,7 @@ fn lower_existential_impl_trait(
// does not actually exist in the AST. // does not actually exist in the AST.
lctx.items.insert(exist_ty_id.node_id, exist_ty_item); 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, ..>` // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes) hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
}) })
...@@ -1852,8 +1858,10 @@ fn lower_path_segment( ...@@ -1852,8 +1858,10 @@ fn lower_path_segment(
} }
} }
let def = self.expect_full_def(segment.id);
hir::PathSegment::new( hir::PathSegment::new(
segment.ident, segment.ident,
Some(def),
generic_args, generic_args,
infer_types, infer_types,
) )
......
...@@ -347,6 +347,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ...@@ -347,6 +347,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
pub struct PathSegment { pub struct PathSegment {
/// The identifier portion of this path segment. /// The identifier portion of this path segment.
pub ident: Ident, pub ident: Ident,
pub def: Option<Def>,
/// Type/lifetime parameters attached to this path. They come in /// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
...@@ -367,14 +368,16 @@ impl PathSegment { ...@@ -367,14 +368,16 @@ impl PathSegment {
pub fn from_ident(ident: Ident) -> PathSegment { pub fn from_ident(ident: Ident) -> PathSegment {
PathSegment { PathSegment {
ident, ident,
def: None,
infer_types: true, infer_types: true,
args: None, 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 { PathSegment {
ident, ident,
def,
infer_types, infer_types,
args: if args.is_empty() { args: if args.is_empty() {
None None
......
...@@ -174,6 +174,7 @@ fn hash_stable<W: StableHasherResult>(&self, ...@@ -174,6 +174,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl_stable_hash_for!(struct hir::PathSegment { impl_stable_hash_for!(struct hir::PathSegment {
ident -> (ident.name), ident -> (ident.name),
def,
infer_types, infer_types,
args args
}); });
......
...@@ -141,7 +141,7 @@ fn build_reduced_graph_for_use_tree( ...@@ -141,7 +141,7 @@ fn build_reduced_graph_for_use_tree(
let prefix_iter = || parent_prefix.iter().cloned() let prefix_iter = || parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.ident)); .chain(use_tree.prefix.segments.iter().map(|seg| seg.ident));
let prefix_start = prefix_iter().next(); 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() !ident.is_path_segment_keyword()
}); });
...@@ -202,13 +202,13 @@ fn build_reduced_graph_for_use_tree( ...@@ -202,13 +202,13 @@ fn build_reduced_graph_for_use_tree(
let source = prefix_start.unwrap(); let source = prefix_start.unwrap();
// Helper closure to emit a canary with the given base path. // 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 { let subclass = SingleImport {
target: Ident { target: Ident {
name: keywords::Underscore.name().gensymed(), name: keywords::Underscore.name().gensymed(),
span: source.span, span: source.0.span,
}, },
source, source: source.0,
result: PerNS { result: PerNS {
type_ns: Cell::new(Err(Undetermined)), type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)),
...@@ -219,7 +219,7 @@ fn build_reduced_graph_for_use_tree( ...@@ -219,7 +219,7 @@ fn build_reduced_graph_for_use_tree(
this.add_import_directive( this.add_import_directive(
base.into_iter().collect(), base.into_iter().collect(),
subclass.clone(), subclass.clone(),
source.span, source.0.span,
id, id,
root_use_tree.span, root_use_tree.span,
root_id, root_id,
...@@ -230,15 +230,15 @@ fn build_reduced_graph_for_use_tree( ...@@ -230,15 +230,15 @@ fn build_reduced_graph_for_use_tree(
}; };
// A single simple `self::x` canary. // A single simple `self::x` canary.
emit(self, Some(Ident { emit(self, Some((Ident {
name: keywords::SelfValue.name(), name: keywords::SelfValue.name(),
span: source.span, span: source.0.span,
})); }, source.1)));
// One special unprefixed canary per block scope around // One special unprefixed canary per block scope around
// the import, to detect items unreachable by `self::x`. // the import, to detect items unreachable by `self::x`.
let orig_current_module = self.current_module; let orig_current_module = self.current_module;
let mut span = source.span.modern(); let mut span = source.0.span.modern();
loop { loop {
match self.current_module.kind { match self.current_module.kind {
ModuleKind::Block(..) => emit(self, None), ModuleKind::Block(..) => emit(self, None),
...@@ -265,10 +265,10 @@ fn build_reduced_graph_for_use_tree( ...@@ -265,10 +265,10 @@ fn build_reduced_graph_for_use_tree(
if nested { if nested {
// Correctly handle `self` // Correctly handle `self`
if source.name == keywords::SelfValue.name() { if source.0.name == keywords::SelfValue.name() {
type_ns_only = true; 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() ident.name == keywords::CrateRoot.name()
}); });
if empty_prefix { if empty_prefix {
...@@ -284,20 +284,20 @@ fn build_reduced_graph_for_use_tree( ...@@ -284,20 +284,20 @@ fn build_reduced_graph_for_use_tree(
// Replace `use foo::self;` with `use foo;` // Replace `use foo::self;` with `use foo;`
source = module_path.pop().unwrap(); source = module_path.pop().unwrap();
if rename.is_none() { if rename.is_none() {
ident = source; ident = source.0;
} }
} }
} else { } else {
// Disallow `self` // Disallow `self`
if source.name == keywords::SelfValue.name() { if source.0.name == keywords::SelfValue.name() {
resolve_error(self, resolve_error(self,
use_tree.span, use_tree.span,
ResolutionError::SelfImportsOnlyAllowedWithin); ResolutionError::SelfImportsOnlyAllowedWithin);
} }
// Disallow `use $crate;` // Disallow `use $crate;`
if source.name == keywords::DollarCrate.name() && module_path.is_empty() { if source.0.name == keywords::DollarCrate.name() && module_path.is_empty() {
let crate_root = self.resolve_crate_root(source); let crate_root = self.resolve_crate_root(source.0);
let crate_name = match crate_root.kind { let crate_name = match crate_root.kind {
ModuleKind::Def(_, name) => name, ModuleKind::Def(_, name) => name,
ModuleKind::Block(..) => unreachable!(), ModuleKind::Block(..) => unreachable!(),
...@@ -307,11 +307,11 @@ fn build_reduced_graph_for_use_tree( ...@@ -307,11 +307,11 @@ fn build_reduced_graph_for_use_tree(
// while the current crate doesn't have a valid `crate_name`. // while the current crate doesn't have a valid `crate_name`.
if crate_name != keywords::Invalid.name() { if crate_name != keywords::Invalid.name() {
// `crate_name` should not be interpreted as relative. // `crate_name` should not be interpreted as relative.
module_path.push(Ident { module_path.push((Ident {
name: keywords::CrateRoot.name(), name: keywords::CrateRoot.name(),
span: source.span, span: source.0.span,
}); }, Some(self.session.next_node_id())));
source.name = crate_name; source.0.name = crate_name;
} }
if rename.is_none() { if rename.is_none() {
ident.name = crate_name; ident.name = crate_name;
...@@ -332,7 +332,7 @@ fn build_reduced_graph_for_use_tree( ...@@ -332,7 +332,7 @@ fn build_reduced_graph_for_use_tree(
let subclass = SingleImport { let subclass = SingleImport {
target: ident, target: ident,
source, source: source.0,
result: PerNS { result: PerNS {
type_ns: Cell::new(Err(Undetermined)), type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)),
...@@ -393,6 +393,17 @@ fn build_reduced_graph_for_use_tree( ...@@ -393,6 +393,17 @@ fn build_reduced_graph_for_use_tree(
} }
for &(ref tree, id) in items { 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( self.build_reduced_graph_for_use_tree(
root_use_tree, root_use_tree,
root_id, root_id,
......
此差异已折叠。
...@@ -462,13 +462,13 @@ pub fn resolve_macro_to_def_inner( ...@@ -462,13 +462,13 @@ pub fn resolve_macro_to_def_inner(
force: bool, force: bool,
) -> Result<Def, Determinacy> { ) -> Result<Def, Determinacy> {
let ast::Path { ref segments, span } = *path; 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 // Possibly apply the macro helper hack
if kind == MacroKind::Bang && path.len() == 1 && if kind == MacroKind::Bang && path.len() == 1 &&
path[0].span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) { 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].span); let root = Ident::new(keywords::DollarCrate.name(), path[0].0.span);
path.insert(0, root); path.insert(0, (root, None));
} }
if path.len() > 1 { if path.len() > 1 {
...@@ -496,12 +496,16 @@ pub fn resolve_macro_to_def_inner( ...@@ -496,12 +496,16 @@ pub fn resolve_macro_to_def_inner(
}; };
parent_scope.module.macro_resolutions.borrow_mut() 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 def
} else { } else {
let binding = self.early_resolve_ident_in_lexical_scope( 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 { match binding {
Ok(..) => {} Ok(..) => {}
...@@ -510,7 +514,7 @@ pub fn resolve_macro_to_def_inner( ...@@ -510,7 +514,7 @@ pub fn resolve_macro_to_def_inner(
} }
parent_scope.module.legacy_macro_resolutions.borrow_mut() 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()) binding.map(|binding| binding.def_ignoring_ambiguity())
} }
...@@ -846,6 +850,10 @@ struct Flags: u8 { ...@@ -846,6 +850,10 @@ struct Flags: u8 {
pub fn finalize_current_module_macro_resolutions(&mut self) { pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module; let module = self.current_module;
for &(ref path, span) in module.macro_resolutions.borrow().iter() { 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) { match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) {
PathResult::NonModule(_) => {}, PathResult::NonModule(_) => {},
PathResult::Failed(span, msg, _) => { PathResult::Failed(span, msg, _) => {
...@@ -938,7 +946,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind, ...@@ -938,7 +946,7 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
} }
}; };
let ident = Ident::new(Symbol::intern(name), span); 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 { if let Some(suggestion) = suggestion {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
use Namespace::{self, TypeNS, MacroNS}; use Namespace::{self, TypeNS, MacroNS};
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use Resolver; 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 {resolve_error, ResolutionError};
use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::ptr_key::PtrKey;
...@@ -89,7 +89,7 @@ pub struct ImportDirective<'a> { ...@@ -89,7 +89,7 @@ pub struct ImportDirective<'a> {
pub root_span: Span, pub root_span: Span,
pub parent: Module<'a>, pub parent: Module<'a>,
pub module_path: Vec<Ident>, pub module_path: Vec<(Ident, Option<NodeId>)>,
/// The resolution of `module_path`. /// The resolution of `module_path`.
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>, pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
pub subclass: ImportDirectiveSubclass<'a>, pub subclass: ImportDirectiveSubclass<'a>,
...@@ -393,7 +393,7 @@ pub fn resolve_ident_in_module_unadjusted(&mut self, ...@@ -393,7 +393,7 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
// Add an import directive to the current module. // Add an import directive to the current module.
pub fn add_import_directive(&mut self, pub fn add_import_directive(&mut self,
module_path: Vec<Ident>, module_path: Vec<(Ident, Option<NodeId>)>,
subclass: ImportDirectiveSubclass<'a>, subclass: ImportDirectiveSubclass<'a>,
span: Span, span: Span,
id: NodeId, id: NodeId,
...@@ -679,7 +679,7 @@ struct UniformPathsCanaryResults<'a> { ...@@ -679,7 +679,7 @@ struct UniformPathsCanaryResults<'a> {
let has_explicit_self = let has_explicit_self =
!import.module_path.is_empty() && !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| { self.per_ns(|_, ns| {
if let Some(result) = result[ns].get().ok() { if let Some(result) = result[ns].get().ok() {
...@@ -728,9 +728,11 @@ struct UniformPathsCanaryResults<'a> { ...@@ -728,9 +728,11 @@ struct UniformPathsCanaryResults<'a> {
self.throw_unresolved_import_error(empty_vec, None); self.throw_unresolved_import_error(empty_vec, None);
} }
if !seen_spans.contains(&span) { if !seen_spans.contains(&span) {
let path = import_path_to_string(&import.module_path[..], let path = import_path_to_string(
&import.subclass, &import.module_path.iter().map(|(ident, _)| *ident).collect::<Vec<_>>(),
span); &import.subclass,
span,
);
error_vec.push((span, path, err)); error_vec.push((span, path, err));
seen_spans.insert(span); seen_spans.insert(span);
prev_root_id = import.root_id; prev_root_id = import.root_id;
...@@ -851,7 +853,7 @@ fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>, ...@@ -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. /// If successful, the resolved bindings are written into the module.
fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
debug!("(resolving import for module) resolving import `{}::...` in `{}`", 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())); module_to_string(self.current_module).unwrap_or_else(|| "???".to_string()));
self.current_module = directive.parent; self.current_module = directive.parent;
...@@ -982,7 +984,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa ...@@ -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 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it. // 2 segments, so the `resolve_path` above won't trigger it.
let mut full_path = module_path.clone(); 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( self.lint_if_path_starts_with_module(
directive.crate_lint(), directive.crate_lint(),
&full_path, &full_path,
...@@ -1146,7 +1148,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa ...@@ -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 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it. // 2 segments, so the `resolve_path` above won't trigger it.
let mut full_path = module_path.clone(); let mut full_path = module_path.clone();
full_path.push(ident); full_path.push((ident, None));
self.per_ns(|this, ns| { self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() { if let Ok(binding) = result[ns].get() {
this.lint_if_path_starts_with_module( this.lint_if_path_starts_with_module(
...@@ -1288,7 +1290,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) { ...@@ -1288,7 +1290,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
let resolutions = imported_module.parent.expect("parent should exist") let resolutions = imported_module.parent.expect("parent should exist")
.resolutions.borrow(); .resolutions.borrow();
let enum_path_segment_index = directive.module_path.len() - 1; 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)) let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
.expect("resolution should exist"); .expect("resolution should exist");
...@@ -1311,6 +1313,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) { ...@@ -1311,6 +1313,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
"consider making the enum public", "consider making the enum public",
suggestion); suggestion);
err.emit(); err.emit();
}
} }
} }
} }
......
...@@ -147,7 +147,7 @@ pub fn from_ident(ident: Ident) -> Self { ...@@ -147,7 +147,7 @@ pub fn from_ident(ident: Ident) -> Self {
pub fn crate_root(span: Span) -> Self { pub fn crate_root(span: Span) -> Self {
PathSegment { PathSegment {
ident: Ident::new(keywords::CrateRoot.name(), span), ident: Ident::new(keywords::CrateRoot.name(), span),
id: CRATE_NODE_ID, id: DUMMY_NODE_ID,
args: None, args: None,
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册