if ident.name == lookup_name && ns == namespace {
if filter_fn(name_binding.def()) {
// create the path
- let span = name_binding.span;
let mut segms = path_segments.clone();
- segms.push(ident.into());
+ segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
let path = Path {
- span: span,
+ span: name_binding.span,
segments: segms,
};
// the entity is accessible in the following cases:
if let Some(module) = name_binding.module() {
// form the path
let mut path_segments = path_segments.clone();
- path_segments.push(ident.into());
+ path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
// add the module to the lookup
path.segments[0].identifier.name = keywords::CrateRoot.name();
let module = self.0.resolve_crate_var(ident.ctxt);
if !module.is_local() {
+ let span = path.segments[0].span;
path.segments.insert(1, match module.kind {
- ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name).into(),
+ ModuleKind::Def(_, name) => ast::PathSegment::from_ident(
+ ast::Ident::with_empty_ctxt(name), span
+ ),
_ => unreachable!(),
})
}
pub fn from_ident(s: Span, identifier: Ident) -> Path {
Path {
span: s,
- segments: vec![identifier.into()],
+ segments: vec![PathSegment::from_ident(identifier, s)],
}
}
pub struct PathSegment {
/// The identifier portion of this path segment.
pub identifier: Ident,
+ /// Span of the segment identifier.
+ pub span: Span,
/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
pub parameters: Option<P<PathParameters>>,
}
-impl From<Ident> for PathSegment {
- fn from(id: Ident) -> Self {
- PathSegment { identifier: id, parameters: None }
- }
-}
-
impl PathSegment {
+ pub fn from_ident(ident: Ident, span: Span) -> Self {
+ PathSegment { identifier: ident, span: span, parameters: None }
+ }
pub fn crate_root() -> Self {
PathSegment {
identifier: keywords::CrateRoot.ident(),
+ span: DUMMY_SP,
parameters: None,
}
}
fn qpath(&self, self_type: P<ast::Ty>,
trait_path: ast::Path,
- ident: ast::Ident)
+ ident: ast::SpannedIdent)
-> (ast::QSelf, ast::Path);
fn qpath_all(&self, self_type: P<ast::Ty>,
trait_path: ast::Path,
- ident: ast::Ident,
+ ident: ast::SpannedIdent,
lifetimes: Vec<ast::Lifetime>,
types: Vec<P<ast::Ty>>,
bindings: Vec<ast::TypeBinding>)
segments.push(ast::PathSegment::crate_root());
}
- segments.extend(idents.into_iter().map(Into::into));
+ segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
None
} else {
bindings: bindings,
})))
};
- segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
+ segments.push(ast::PathSegment {
+ identifier: last_identifier,
+ span: sp,
+ parameters: parameters
+ });
ast::Path {
span: sp,
segments: segments,
fn qpath(&self,
self_type: P<ast::Ty>,
trait_path: ast::Path,
- ident: ast::Ident)
+ ident: ast::SpannedIdent)
-> (ast::QSelf, ast::Path) {
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
}
fn qpath_all(&self,
self_type: P<ast::Ty>,
trait_path: ast::Path,
- ident: ast::Ident,
+ ident: ast::SpannedIdent,
lifetimes: Vec<ast::Lifetime>,
types: Vec<P<ast::Ty>>,
bindings: Vec<ast::TypeBinding>)
bindings: bindings,
};
path.segments.push(ast::PathSegment {
- identifier: ident,
+ identifier: ident.node,
+ span: ident.span,
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
});
pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
Path {
- segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
+ segments: segments.move_map(|PathSegment {identifier, span, parameters}| PathSegment {
identifier: fld.fold_ident(identifier),
+ span: fld.new_span(span),
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
}),
span: fld.new_span(span)
Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
}
+ fn str2seg(s: &str, lo: u32, hi: u32) -> ast::PathSegment {
+ ast::PathSegment::from_ident(Ident::from_str(s), sp(lo, hi))
+ }
+
#[test] fn path_exprs_1() {
assert!(string_to_expr("a".to_string()) ==
P(ast::Expr{
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Path(None, ast::Path {
span: sp(0, 1),
- segments: vec![Ident::from_str("a").into()],
+ segments: vec![str2seg("a", 0, 1)],
}),
span: sp(0, 1),
attrs: ThinVec::new(),
node: ast::ExprKind::Path(None, ast::Path {
span: sp(0, 6),
segments: vec![ast::PathSegment::crate_root(),
- Ident::from_str("a").into(),
- Ident::from_str("b").into()]
+ str2seg("a", 2, 3),
+ str2seg("b", 5, 6)]
}),
span: sp(0, 6),
attrs: ThinVec::new(),
id: ast::DUMMY_NODE_ID,
node:ast::ExprKind::Path(None, ast::Path{
span: sp(7, 8),
- segments: vec![Ident::from_str("d").into()],
+ segments: vec![str2seg("d", 7, 8)],
}),
span:sp(7,8),
attrs: ThinVec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Path(None, ast::Path {
span:sp(0,1),
- segments: vec![Ident::from_str("b").into()],
+ segments: vec![str2seg("b", 0, 1)],
}),
span: sp(0,1),
attrs: ThinVec::new()})),
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
node: ast::TyKind::Path(None, ast::Path{
span:sp(10,13),
- segments: vec![Ident::from_str("i32").into()],
+ segments: vec![str2seg("i32", 10, 13)],
}),
span:sp(10,13)
}),
node: ast::ExprKind::Path(None,
ast::Path{
span:sp(17,18),
- segments: vec![Ident::from_str("b").into()],
+ segments: vec![str2seg("b", 17, 18)],
}),
span: sp(17,18),
attrs: ThinVec::new()})),
use ast::MacStmtStyle;
use ast::Mac_;
use ast::{MutTy, Mutability};
-use ast::{Pat, PatKind};
+use ast::{Pat, PatKind, PathSegment};
use ast::{PolyTraitRef, QSelf};
use ast::{Stmt, StmtKind};
use ast::{VariantData, StructField};
};
if is_global {
- segments.insert(0, ast::PathSegment::crate_root());
+ segments.insert(0, PathSegment::crate_root());
}
// Assemble the span.
/// - `a::b<T,U>::c<V,W>`
/// - `a::b<T,U>::c(V) -> W`
/// - `a::b<T,U>::c(V)`
- pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
+ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
let mut segments = Vec::new();
loop {
// First, parse an identifier.
let identifier = self.parse_path_segment_ident()?;
+ let ident_span = self.prev_span;
if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
self.bump();
};
// Assemble and push the result.
- segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
+ segments.push(PathSegment {
+ identifier: identifier,
+ span: ident_span,
+ parameters: parameters
+ });
// Continue only if we see a `::`
if !self.eat(&token::ModSep) {
/// Examples:
/// - `a::b::<T,U>::c`
- pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
+ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
let mut segments = Vec::new();
loop {
// First, parse an identifier.
let identifier = self.parse_path_segment_ident()?;
+ let ident_span = self.prev_span;
// If we do not see a `::`, stop.
if !self.eat(&token::ModSep) {
- segments.push(identifier.into());
+ segments.push(PathSegment::from_ident(identifier, ident_span));
return Ok(segments);
}
// Consumed `a::b::<`, go look for types
let (lifetimes, types, bindings) = self.parse_generic_args()?;
self.expect_gt()?;
- segments.push(ast::PathSegment {
+ segments.push(PathSegment {
identifier: identifier,
+ span: ident_span,
parameters: ast::AngleBracketedParameterData {
lifetimes: lifetimes,
types: types,
}
} else {
// Consumed `a::`, go look for `b`
- segments.push(identifier.into());
+ segments.push(PathSegment::from_ident(identifier, ident_span));
}
}
}
/// Examples:
/// - `a::b::c`
pub fn parse_path_segments_without_types(&mut self)
- -> PResult<'a, Vec<ast::PathSegment>> {
+ -> PResult<'a, Vec<PathSegment>> {
let mut segments = Vec::new();
loop {
// First, parse an identifier.
let identifier = self.parse_path_segment_ident()?;
// Assemble and push the result.
- segments.push(identifier.into());
+ segments.push(PathSegment::from_ident(identifier, self.prev_span));
// If we do not see a `::` or see `::{`/`::*`, stop.
if !self.check(&token::ModSep) || self.is_import_coupler() {
// `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
self.eat(&token::ModSep);
let prefix = ast::Path {
- segments: vec![ast::PathSegment::crate_root()],
+ segments: vec![PathSegment::crate_root()],
span: mk_sp(lo, self.span.hi),
};
let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
vis: ast::Visibility::Inherited,
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
- ast::Ident::from_str(name).into()
+ ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
}).collect(),
span: span,
})))),
fn path_node(ids: Vec<Ident>) -> ast::Path {
ast::Path {
span: DUMMY_SP,
- segments: ids.into_iter().map(Into::into).collect(),
+ segments: ids.into_iter().map(|id| ast::PathSegment::from_ident(id, DUMMY_SP)).collect(),
}
}
fn path(&self) -> ast::Path {
ast::Path {
span: self.span,
- segments: vec![self.ident.into()],
+ segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
}
}
}