Skip to content

Commit 2719b84

Browse files
committed
Give spans to individual path segments in AST
1 parent ee60afa commit 2719b84

File tree

10 files changed

+60
-41
lines changed

10 files changed

+60
-41
lines changed

src/librustc_resolve/lib.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -3124,11 +3124,10 @@ impl<'a> Resolver<'a> {
31243124
if ident.name == lookup_name && ns == namespace {
31253125
if filter_fn(name_binding.def()) {
31263126
// create the path
3127-
let span = name_binding.span;
31283127
let mut segms = path_segments.clone();
3129-
segms.push(ident.into());
3128+
segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
31303129
let path = Path {
3131-
span: span,
3130+
span: name_binding.span,
31323131
segments: segms,
31333132
};
31343133
// the entity is accessible in the following cases:
@@ -3148,7 +3147,7 @@ impl<'a> Resolver<'a> {
31483147
if let Some(module) = name_binding.module() {
31493148
// form the path
31503149
let mut path_segments = path_segments.clone();
3151-
path_segments.push(ident.into());
3150+
path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
31523151

31533152
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
31543153
// add the module to the lookup

src/librustc_resolve/macros.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,11 @@ impl<'a> base::Resolver for Resolver<'a> {
110110
path.segments[0].identifier.name = keywords::CrateRoot.name();
111111
let module = self.0.resolve_crate_var(ident.ctxt);
112112
if !module.is_local() {
113+
let span = path.segments[0].span;
113114
path.segments.insert(1, match module.kind {
114-
ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name).into(),
115+
ModuleKind::Def(_, name) => ast::PathSegment::from_ident(
116+
ast::Ident::with_empty_ctxt(name), span
117+
),
115118
_ => unreachable!(),
116119
})
117120
}

src/libsyntax/ast.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl Path {
134134
pub fn from_ident(s: Span, identifier: Ident) -> Path {
135135
Path {
136136
span: s,
137-
segments: vec![identifier.into()],
137+
segments: vec![PathSegment::from_ident(identifier, s)],
138138
}
139139
}
140140

@@ -159,6 +159,8 @@ impl Path {
159159
pub struct PathSegment {
160160
/// The identifier portion of this path segment.
161161
pub identifier: Ident,
162+
/// Span of the segment identifier.
163+
pub span: Span,
162164

163165
/// Type/lifetime parameters attached to this path. They come in
164166
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
@@ -170,16 +172,14 @@ pub struct PathSegment {
170172
pub parameters: Option<P<PathParameters>>,
171173
}
172174

173-
impl From<Ident> for PathSegment {
174-
fn from(id: Ident) -> Self {
175-
PathSegment { identifier: id, parameters: None }
176-
}
177-
}
178-
179175
impl PathSegment {
176+
pub fn from_ident(ident: Ident, span: Span) -> Self {
177+
PathSegment { identifier: ident, span: span, parameters: None }
178+
}
180179
pub fn crate_root() -> Self {
181180
PathSegment {
182181
identifier: keywords::CrateRoot.ident(),
182+
span: DUMMY_SP,
183183
parameters: None,
184184
}
185185
}

src/libsyntax/ext/build.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ pub trait AstBuilder {
3838

3939
fn qpath(&self, self_type: P<ast::Ty>,
4040
trait_path: ast::Path,
41-
ident: ast::Ident)
41+
ident: ast::SpannedIdent)
4242
-> (ast::QSelf, ast::Path);
4343
fn qpath_all(&self, self_type: P<ast::Ty>,
4444
trait_path: ast::Path,
45-
ident: ast::Ident,
45+
ident: ast::SpannedIdent,
4646
lifetimes: Vec<ast::Lifetime>,
4747
types: Vec<P<ast::Ty>>,
4848
bindings: Vec<ast::TypeBinding>)
@@ -323,7 +323,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
323323
segments.push(ast::PathSegment::crate_root());
324324
}
325325

326-
segments.extend(idents.into_iter().map(Into::into));
326+
segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
327327
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
328328
None
329329
} else {
@@ -333,7 +333,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
333333
bindings: bindings,
334334
})))
335335
};
336-
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
336+
segments.push(ast::PathSegment {
337+
identifier: last_identifier,
338+
span: sp,
339+
parameters: parameters
340+
});
337341
ast::Path {
338342
span: sp,
339343
segments: segments,
@@ -346,7 +350,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
346350
fn qpath(&self,
347351
self_type: P<ast::Ty>,
348352
trait_path: ast::Path,
349-
ident: ast::Ident)
353+
ident: ast::SpannedIdent)
350354
-> (ast::QSelf, ast::Path) {
351355
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
352356
}
@@ -357,7 +361,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
357361
fn qpath_all(&self,
358362
self_type: P<ast::Ty>,
359363
trait_path: ast::Path,
360-
ident: ast::Ident,
364+
ident: ast::SpannedIdent,
361365
lifetimes: Vec<ast::Lifetime>,
362366
types: Vec<P<ast::Ty>>,
363367
bindings: Vec<ast::TypeBinding>)
@@ -369,7 +373,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
369373
bindings: bindings,
370374
};
371375
path.segments.push(ast::PathSegment {
372-
identifier: ident,
376+
identifier: ident.node,
377+
span: ident.span,
373378
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
374379
});
375380

src/libsyntax/fold.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,9 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
434434

435435
pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
436436
Path {
437-
segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
437+
segments: segments.move_map(|PathSegment {identifier, span, parameters}| PathSegment {
438438
identifier: fld.fold_ident(identifier),
439+
span: fld.new_span(span),
439440
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
440441
}),
441442
span: fld.new_span(span)

src/libsyntax/parse/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -617,13 +617,17 @@ mod tests {
617617
Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
618618
}
619619

620+
fn str2seg(s: &str, lo: u32, hi: u32) -> ast::PathSegment {
621+
ast::PathSegment::from_ident(Ident::from_str(s), sp(lo, hi))
622+
}
623+
620624
#[test] fn path_exprs_1() {
621625
assert!(string_to_expr("a".to_string()) ==
622626
P(ast::Expr{
623627
id: ast::DUMMY_NODE_ID,
624628
node: ast::ExprKind::Path(None, ast::Path {
625629
span: sp(0, 1),
626-
segments: vec![Ident::from_str("a").into()],
630+
segments: vec![str2seg("a", 0, 1)],
627631
}),
628632
span: sp(0, 1),
629633
attrs: ThinVec::new(),
@@ -637,8 +641,8 @@ mod tests {
637641
node: ast::ExprKind::Path(None, ast::Path {
638642
span: sp(0, 6),
639643
segments: vec![ast::PathSegment::crate_root(),
640-
Ident::from_str("a").into(),
641-
Ident::from_str("b").into()]
644+
str2seg("a", 2, 3),
645+
str2seg("b", 5, 6)]
642646
}),
643647
span: sp(0, 6),
644648
attrs: ThinVec::new(),
@@ -744,7 +748,7 @@ mod tests {
744748
id: ast::DUMMY_NODE_ID,
745749
node:ast::ExprKind::Path(None, ast::Path{
746750
span: sp(7, 8),
747-
segments: vec![Ident::from_str("d").into()],
751+
segments: vec![str2seg("d", 7, 8)],
748752
}),
749753
span:sp(7,8),
750754
attrs: ThinVec::new(),
@@ -761,7 +765,7 @@ mod tests {
761765
id: ast::DUMMY_NODE_ID,
762766
node: ast::ExprKind::Path(None, ast::Path {
763767
span:sp(0,1),
764-
segments: vec![Ident::from_str("b").into()],
768+
segments: vec![str2seg("b", 0, 1)],
765769
}),
766770
span: sp(0,1),
767771
attrs: ThinVec::new()})),
@@ -802,7 +806,7 @@ mod tests {
802806
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
803807
node: ast::TyKind::Path(None, ast::Path{
804808
span:sp(10,13),
805-
segments: vec![Ident::from_str("i32").into()],
809+
segments: vec![str2seg("i32", 10, 13)],
806810
}),
807811
span:sp(10,13)
808812
}),
@@ -844,7 +848,7 @@ mod tests {
844848
node: ast::ExprKind::Path(None,
845849
ast::Path{
846850
span:sp(17,18),
847-
segments: vec![Ident::from_str("b").into()],
851+
segments: vec![str2seg("b", 17, 18)],
848852
}),
849853
span: sp(17,18),
850854
attrs: ThinVec::new()})),

src/libsyntax/parse/parser.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use ast::Local;
2727
use ast::MacStmtStyle;
2828
use ast::Mac_;
2929
use ast::{MutTy, Mutability};
30-
use ast::{Pat, PatKind};
30+
use ast::{Pat, PatKind, PathSegment};
3131
use ast::{PolyTraitRef, QSelf};
3232
use ast::{Stmt, StmtKind};
3333
use ast::{VariantData, StructField};
@@ -1811,7 +1811,7 @@ impl<'a> Parser<'a> {
18111811
};
18121812

18131813
if is_global {
1814-
segments.insert(0, ast::PathSegment::crate_root());
1814+
segments.insert(0, PathSegment::crate_root());
18151815
}
18161816

18171817
// Assemble the span.
@@ -1829,11 +1829,12 @@ impl<'a> Parser<'a> {
18291829
/// - `a::b<T,U>::c<V,W>`
18301830
/// - `a::b<T,U>::c(V) -> W`
18311831
/// - `a::b<T,U>::c(V)`
1832-
pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
1832+
pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
18331833
let mut segments = Vec::new();
18341834
loop {
18351835
// First, parse an identifier.
18361836
let identifier = self.parse_path_segment_ident()?;
1837+
let ident_span = self.prev_span;
18371838

18381839
if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
18391840
self.bump();
@@ -1881,7 +1882,11 @@ impl<'a> Parser<'a> {
18811882
};
18821883

18831884
// Assemble and push the result.
1884-
segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
1885+
segments.push(PathSegment {
1886+
identifier: identifier,
1887+
span: ident_span,
1888+
parameters: parameters
1889+
});
18851890

18861891
// Continue only if we see a `::`
18871892
if !self.eat(&token::ModSep) {
@@ -1892,15 +1897,16 @@ impl<'a> Parser<'a> {
18921897

18931898
/// Examples:
18941899
/// - `a::b::<T,U>::c`
1895-
pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
1900+
pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
18961901
let mut segments = Vec::new();
18971902
loop {
18981903
// First, parse an identifier.
18991904
let identifier = self.parse_path_segment_ident()?;
1905+
let ident_span = self.prev_span;
19001906

19011907
// If we do not see a `::`, stop.
19021908
if !self.eat(&token::ModSep) {
1903-
segments.push(identifier.into());
1909+
segments.push(PathSegment::from_ident(identifier, ident_span));
19041910
return Ok(segments);
19051911
}
19061912

@@ -1909,8 +1915,9 @@ impl<'a> Parser<'a> {
19091915
// Consumed `a::b::<`, go look for types
19101916
let (lifetimes, types, bindings) = self.parse_generic_args()?;
19111917
self.expect_gt()?;
1912-
segments.push(ast::PathSegment {
1918+
segments.push(PathSegment {
19131919
identifier: identifier,
1920+
span: ident_span,
19141921
parameters: ast::AngleBracketedParameterData {
19151922
lifetimes: lifetimes,
19161923
types: types,
@@ -1924,22 +1931,22 @@ impl<'a> Parser<'a> {
19241931
}
19251932
} else {
19261933
// Consumed `a::`, go look for `b`
1927-
segments.push(identifier.into());
1934+
segments.push(PathSegment::from_ident(identifier, ident_span));
19281935
}
19291936
}
19301937
}
19311938

19321939
/// Examples:
19331940
/// - `a::b::c`
19341941
pub fn parse_path_segments_without_types(&mut self)
1935-
-> PResult<'a, Vec<ast::PathSegment>> {
1942+
-> PResult<'a, Vec<PathSegment>> {
19361943
let mut segments = Vec::new();
19371944
loop {
19381945
// First, parse an identifier.
19391946
let identifier = self.parse_path_segment_ident()?;
19401947

19411948
// Assemble and push the result.
1942-
segments.push(identifier.into());
1949+
segments.push(PathSegment::from_ident(identifier, self.prev_span));
19431950

19441951
// If we do not see a `::` or see `::{`/`::*`, stop.
19451952
if !self.check(&token::ModSep) || self.is_import_coupler() {
@@ -5902,7 +5909,7 @@ impl<'a> Parser<'a> {
59025909
// `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
59035910
self.eat(&token::ModSep);
59045911
let prefix = ast::Path {
5905-
segments: vec![ast::PathSegment::crate_root()],
5912+
segments: vec![PathSegment::crate_root()],
59065913
span: mk_sp(lo, self.span.hi),
59075914
};
59085915
let view_path_kind = if self.eat(&token::BinOp(token::Star)) {

src/libsyntax/std_inject.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
8282
vis: ast::Visibility::Inherited,
8383
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
8484
segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
85-
ast::Ident::from_str(name).into()
85+
ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
8686
}).collect(),
8787
span: span,
8888
})))),

src/libsyntax/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ fn nospan<T>(t: T) -> codemap::Spanned<T> {
580580
fn path_node(ids: Vec<Ident>) -> ast::Path {
581581
ast::Path {
582582
span: DUMMY_SP,
583-
segments: ids.into_iter().map(Into::into).collect(),
583+
segments: ids.into_iter().map(|id| ast::PathSegment::from_ident(id, DUMMY_SP)).collect(),
584584
}
585585
}
586586

src/libsyntax_ext/concat_idents.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
6161
fn path(&self) -> ast::Path {
6262
ast::Path {
6363
span: self.span,
64-
segments: vec![self.ident.into()],
64+
segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
6565
}
6666
}
6767
}

0 commit comments

Comments
 (0)