id: NodeId,
p: &Path,
name: Option<Name>,
- param_mode: ParamMode,
- defaults_to_global: bool)
+ param_mode: ParamMode)
-> hir::Path {
- let mut segments = p.segments.iter();
- if defaults_to_global && p.is_global() {
- segments.next();
- }
-
hir::Path {
def: self.expect_full_def(id),
- segments: segments.map(|segment| {
+ segments: p.segments.iter().map(|segment| {
self.lower_path_segment(p.span, segment, param_mode, 0,
ParenthesizedGenericArgs::Err,
ImplTraitContext::Disallowed)
fn lower_path(&mut self,
id: NodeId,
p: &Path,
- param_mode: ParamMode,
- defaults_to_global: bool)
+ param_mode: ParamMode)
-> hir::Path {
- self.lower_path_extra(id, p, None, param_mode, defaults_to_global)
+ self.lower_path_extra(id, p, None, param_mode)
}
fn lower_path_segment(&mut self,
}
}
- let path = P(self.lower_path(id, &path, ParamMode::Explicit, true));
+ let path = P(self.lower_path(id, &path, ParamMode::Explicit));
hir::ItemUse(path, hir::UseKind::Single)
}
UseTreeKind::Glob => {
.cloned()
.collect(),
span: path.span,
- }, ParamMode::Explicit, true));
+ }, ParamMode::Explicit));
hir::ItemUse(path, hir::UseKind::Glob)
}
UseTreeKind::Nested(ref trees) => {
// Privatize the degenerate import base, used only to check
// the stability of `use a::{};`, to avoid it showing up as
// a re-export by accident when `pub`, e.g. in documentation.
- let path = P(self.lower_path(id, &prefix, ParamMode::Explicit, true));
+ let path = P(self.lower_path(id, &prefix, ParamMode::Explicit));
*vis = hir::Inherited;
hir::ItemUse(path, hir::UseKind::ListStem)
}
VisibilityKind::Crate(..) => hir::Visibility::Crate,
VisibilityKind::Restricted { ref path, id, .. } => {
hir::Visibility::Restricted {
- path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
+ path: P(self.lower_path(id, path, ParamMode::Explicit)),
id: if let Some(owner) = explicit_owner {
self.lower_node_id_with_owner(id, owner).node_id
} else {
match item.node {
ItemKind::Use(ref use_tree) => {
- // Just an empty prefix to start out
+ // Imports are resolved as global by default, add starting root segment.
let prefix = ast::Path {
- segments: vec![],
+ segments: use_tree.prefix.make_root().into_iter().collect(),
span: use_tree.span,
};
}
ItemKind::Use(ref use_tree) => {
+ // Imports are resolved as global by default, add starting root segment.
let path = Path {
- segments: vec![],
+ segments: use_tree.prefix.make_root().into_iter().collect(),
span: use_tree.span,
};
self.resolve_use_tree(item.id, use_tree, &path);
None,
&path,
trait_ref.path.span,
- trait_ref.path.segments.last().unwrap().span,
PathSource::Trait(AliasPossibility::No)
).base_def();
if def != Def::Err {
let segments = &path.segments.iter()
.map(|seg| respan(seg.span, seg.identifier))
.collect::<Vec<_>>();
- let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
- self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
+ self.smart_resolve_path_fragment(id, qself, segments, path.span, source)
}
fn smart_resolve_path_fragment(&mut self,
qself: Option<&QSelf>,
path: &[SpannedIdent],
span: Span,
- ident_span: Span,
source: PathSource)
-> PathResolution {
+ let ident_span = path.last().map_or(span, |ident| ident.span);
let ns = source.namespace();
let is_expected = &|def| source.is_expected(def);
let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
// Make sure `A::B` in `<T as A>::B::C` is a trait item.
let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
- span, span, PathSource::TraitItem(ns));
+ span, PathSource::TraitItem(ns));
return Some(PathResolution::with_unresolved_segments(
res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
));
ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
}
ast::VisibilityKind::Restricted { ref path, id, .. } => {
- let def = self.smart_resolve_path(id, None, path,
- PathSource::Visibility).base_def();
+ // Visibilities are resolved as global by default, add starting root segment.
+ let segments = path.make_root().iter().chain(path.segments.iter())
+ .map(|seg| respan(seg.span, seg.identifier))
+ .collect::<Vec<_>>();
+ let def = self.smart_resolve_path_fragment(id, None, &segments, path.span,
+ PathSource::Visibility).base_def();
if def == Def::Err {
ty::Visibility::Public
} else {
}
PathResult::Failed(span, msg, true) => {
let (mut self_path, mut self_result) = (module_path.clone(), None);
- if !self_path.is_empty() &&
- !token::Ident(self_path[0].node).is_path_segment_keyword() &&
- !(self_path.len() > 1 &&
- token::Ident(self_path[1].node).is_path_segment_keyword())
- {
+ let is_special = |ident| token::Ident(ident).is_path_segment_keyword() &&
+ ident.name != keywords::CrateRoot.name();
+ if !self_path.is_empty() && !is_special(self_path[0].node) &&
+ !(self_path.len() > 1 && is_special(self_path[1].node)) {
self_path[0].node.name = keywords::SelfValue.name();
self_result = Some(self.resolve_path(&self_path, None, false, span));
}
}
}
- // Add starting "crate root" segment to all paths except those that
- // already have it or start with `self`, `super`, `Self` or `$crate`.
- pub fn default_to_global(mut self) -> Path {
- if !self.is_global() {
- let ident = self.segments[0].identifier;
- if !::parse::token::Ident(ident).is_path_segment_keyword() ||
- ident.name == keywords::Crate.name() {
- self.segments.insert(0, PathSegment::crate_root(self.span));
+ // Make a "crate root" segment for this path unless it already has it
+ // or starts with something like `self`/`super`/`$crate`/etc.
+ pub fn make_root(&self) -> Option<PathSegment> {
+ if let Some(ident) = self.segments.get(0).map(|seg| seg.identifier) {
+ if ::parse::token::Ident(ident).is_path_segment_keyword() &&
+ ident.name != keywords::Crate.name() {
+ return None;
}
}
- self
+ Some(PathSegment::crate_root(self.span.with_hi(self.span.lo())))
}
pub fn is_global(&self) -> bool {
None
};
segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
- let path = ast::Path { span, segments };
-
- if global { path.default_to_global() } else { path }
+ let mut path = ast::Path { span, segments };
+ if global {
+ if let Some(seg) = path.make_root() {
+ path.segments.insert(0, seg);
+ }
+ }
+ path
}
/// Constructs a qualified path.
// `pub(in path)`
self.bump(); // `(`
self.bump(); // `in`
- let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `path`
+ let path = self.parse_path(PathStyle::Mod)?; // `path`
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
path: P(path),
{
// `pub(self)` or `pub(super)`
self.bump(); // `(`
- let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `super`/`self`
+ let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
path: P(path),
if self.eat_keyword(keywords::Use) {
// USE ITEM
- let item_ = ItemKind::Use(P(self.parse_use_tree(false)?));
+ let item_ = ItemKind::Use(P(self.parse_use_tree()?));
self.expect(&token::Semi)?;
let prev_span = self.prev_span;
/// PATH `::` `*` |
/// PATH `::` `{` USE_TREE_LIST `}` |
/// PATH [`as` IDENT]
- fn parse_use_tree(&mut self, nested: bool) -> PResult<'a, UseTree> {
+ fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
let lo = self.span;
let mut prefix = ast::Path {
// Remove the first `::`
if self.eat(&token::ModSep) {
prefix.segments.push(PathSegment::crate_root(self.prev_span));
- } else if !nested {
- prefix.segments.push(PathSegment::crate_root(self.span));
}
if self.eat(&token::BinOp(token::Star)) {
} else {
// `use path::...;`
let mut parsed = self.parse_path(PathStyle::Mod)?;
- if !nested {
- parsed = parsed.default_to_global();
- }
prefix.segments.append(&mut parsed.segments);
prefix.span = prefix.span.to(parsed.span);
self.parse_unspanned_seq(&token::OpenDelim(token::Brace),
&token::CloseDelim(token::Brace),
SeqSep::trailing_allowed(token::Comma), |this| {
- Ok((this.parse_use_tree(true)?, ast::DUMMY_NODE_ID))
+ Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID))
})
}
id.name == keywords::SelfType.name() ||
id.name == keywords::Extern.name() ||
id.name == keywords::Crate.name() ||
+ id.name == keywords::CrateRoot.name() ||
id.name == keywords::DollarCrate.name(),
None => false,
}
}
pub fn path_to_string(p: &ast::Path) -> String {
- to_string(|s| s.print_path(p, false, 0, false))
+ to_string(|s| s.print_path(p, false, 0))
}
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
&f.generic_params)?;
}
ast::TyKind::Path(None, ref path) => {
- self.print_path(path, false, 0, false)?;
+ self.print_path(path, false, 0)?;
}
ast::TyKind::Path(Some(ref qself), ref path) => {
self.print_qpath(path, qself, false)?
self.s.word(";")?;
}
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
- self.print_path(&node.path, false, 0, false)?;
+ self.print_path(&node.path, false, 0)?;
self.s.word("! ")?;
self.print_ident(item.ident)?;
self.cbox(INDENT_UNIT)?;
}
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
- self.print_path(&t.path, false, 0, false)
+ self.print_path(&t.path, false, 0)
}
fn print_formal_generic_params(
ast::CrateSugar::JustCrate => self.word_nbsp("crate")
}
ast::VisibilityKind::Restricted { ref path, .. } => {
- let path = to_string(|s| s.print_path(path, false, 0, true));
+ let path = to_string(|s| s.print_path(path, false, 0));
if path == "self" || path == "super" {
self.word_nbsp(&format!("pub({})", path))
} else {
}
ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
// code copied from ItemKind::Mac:
- self.print_path(&node.path, false, 0, false)?;
+ self.print_path(&node.path, false, 0)?;
self.s.word("! ")?;
self.cbox(INDENT_UNIT)?;
self.popen()?;
}
ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
// code copied from ItemKind::Mac:
- self.print_path(&node.path, false, 0, false)?;
+ self.print_path(&node.path, false, 0)?;
self.s.word("! ")?;
self.cbox(INDENT_UNIT)?;
self.popen()?;
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
-> io::Result<()> {
- self.print_path(&m.node.path, false, 0, false)?;
+ self.print_path(&m.node.path, false, 0)?;
self.s.word("!")?;
match delim {
token::Paren => self.popen()?,
fields: &[ast::Field],
wth: &Option<P<ast::Expr>>,
attrs: &[Attribute]) -> io::Result<()> {
- self.print_path(path, true, 0, false)?;
+ self.print_path(path, true, 0)?;
self.s.word("{")?;
self.print_inner_attributes_inline(attrs)?;
self.commasep_cmnt(
}
}
ast::ExprKind::Path(None, ref path) => {
- self.print_path(path, true, 0, false)?
+ self.print_path(path, true, 0)?
}
ast::ExprKind::Path(Some(ref qself), ref path) => {
self.print_qpath(path, qself, true)?
fn print_path(&mut self,
path: &ast::Path,
colons_before_params: bool,
- depth: usize,
- defaults_to_global: bool)
+ depth: usize)
-> io::Result<()>
{
self.maybe_print_comment(path.span.lo())?;
- let mut segments = path.segments[..path.segments.len()-depth].iter();
- if defaults_to_global && path.is_global() {
- segments.next();
- }
- for (i, segment) in segments.enumerate() {
+ for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() {
if i > 0 {
self.s.word("::")?
}
self.s.space()?;
self.word_space("as")?;
let depth = path.segments.len() - qself.position;
- self.print_path(path, false, depth, false)?;
+ self.print_path(path, false, depth)?;
}
self.s.word(">")?;
self.s.word("::")?;
}
}
PatKind::TupleStruct(ref path, ref elts, ddpos) => {
- self.print_path(path, true, 0, false)?;
+ self.print_path(path, true, 0)?;
self.popen()?;
if let Some(ddpos) = ddpos {
self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?;
self.pclose()?;
}
PatKind::Path(None, ref path) => {
- self.print_path(path, true, 0, false)?;
+ self.print_path(path, true, 0)?;
}
PatKind::Path(Some(ref qself), ref path) => {
self.print_qpath(path, qself, false)?;
}
PatKind::Struct(ref path, ref fields, etc) => {
- self.print_path(path, true, 0, false)?;
+ self.print_path(path, true, 0)?;
self.nbsp()?;
self.word_space("{")?;
self.commasep_cmnt(
pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
match tree.kind {
ast::UseTreeKind::Simple(rename) => {
- self.print_path(&tree.prefix, false, 0, true)?;
+ self.print_path(&tree.prefix, false, 0)?;
if let Some(rename) = rename {
self.s.space()?;
self.word_space("as")?;
}
ast::UseTreeKind::Glob => {
if !tree.prefix.segments.is_empty() {
- self.print_path(&tree.prefix, false, 0, true)?;
+ self.print_path(&tree.prefix, false, 0)?;
self.s.word("::")?;
}
self.s.word("*")?;
if tree.prefix.segments.is_empty() {
self.s.word("{")?;
} else {
- self.print_path(&tree.prefix, false, 0, true)?;
+ self.print_path(&tree.prefix, false, 0)?;
self.s.word("::{")?;
}
self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| {
vis: respan(span.empty(), ast::VisibilityKind::Inherited),
node: ast::ItemKind::Use(P(ast::UseTree {
prefix: ast::Path {
- segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
+ segments: [name, "prelude", "v1"].into_iter().map(|name| {
ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
}).collect(),
span,