diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-12-05 03:51:11 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-12-22 06:14:35 +0000 |
| commit | f10f50b42639718b2580d10802f05f2b6ff209d5 (patch) | |
| tree | 19b61435b37e14f97a74e18b6db32c507e7b1a58 /src/libsyntax | |
| parent | 164619a8cfe6d376d25bd3a6a9a5f2856c8de64d (diff) | |
| download | rust-f10f50b42639718b2580d10802f05f2b6ff209d5.tar.gz rust-f10f50b42639718b2580d10802f05f2b6ff209d5.zip | |
Refactor how global paths are represented (for both ast and hir).
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/placeholders.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 67 | ||||
| -rw-r--r-- | src/libsyntax/std_inject.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/symbol.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 1 |
10 files changed, 83 insertions, 57 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fdd82225b97..648a82ffb76 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -111,10 +111,8 @@ pub struct LifetimeDef { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub struct Path { pub span: Span, - /// A `::foo` path, is relative to the crate root rather than current - /// module (like paths in an import). - pub global: bool, /// The segments in the path: the things separated by `::`. + /// Global paths begin with `keywords::CrateRoot`. pub segments: Vec<PathSegment>, } @@ -136,10 +134,22 @@ impl Path { pub fn from_ident(s: Span, identifier: Ident) -> Path { Path { span: s, - global: false, segments: vec![identifier.into()], } } + + pub fn default_to_global(mut self) -> Path { + let name = self.segments[0].identifier.name; + if !self.is_global() && name != "$crate" && + name != keywords::SelfValue.name() && name != keywords::Super.name() { + self.segments.insert(0, PathSegment::crate_root()); + } + self + } + + pub fn is_global(&self) -> bool { + !self.segments.is_empty() && self.segments[0].identifier.name == keywords::CrateRoot.name() + } } /// A segment of a path: an identifier, an optional lifetime, and a set of types. @@ -166,6 +176,15 @@ impl From<Ident> for PathSegment { } } +impl PathSegment { + pub fn crate_root() -> Self { + PathSegment { + identifier: keywords::CrateRoot.ident(), + parameters: None, + } + } +} + /// Parameters of a path segment. /// /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)` diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index c3dc64f9124..7584fa3916d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -322,7 +322,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { bindings: Vec<ast::TypeBinding> ) -> ast::Path { let last_identifier = idents.pop().unwrap(); - let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect(); + let mut segments: Vec<ast::PathSegment> = Vec::new(); + if global { + segments.push(ast::PathSegment::crate_root()); + } + + segments.extend(idents.into_iter().map(Into::into)); let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() { None } else { @@ -335,7 +340,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters }); ast::Path { span: sp, - global: global, segments: segments, } } diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index eb4b6144c8d..66555d7d95d 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -25,7 +25,7 @@ use std::mem; pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion { fn mac_placeholder() -> ast::Mac { dummy_spanned(ast::Mac_ { - path: ast::Path { span: DUMMY_SP, global: false, segments: Vec::new() }, + path: ast::Path { span: DUMMY_SP, segments: Vec::new() }, tts: Vec::new(), }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index b3753e3e977..bf10d45add4 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -433,9 +433,8 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize { i } -pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut T) -> Path { +pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path { Path { - global: global, segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment { identifier: fld.fold_ident(identifier), parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index b9e6605639e..24178e1f675 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -633,7 +633,6 @@ mod tests { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::Path(None, ast::Path { span: sp(0, 1), - global: false, segments: vec![Ident::from_str("a").into()], }), span: sp(0, 1), @@ -647,8 +646,9 @@ mod tests { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::Path(None, ast::Path { span: sp(0, 6), - global: true, - segments: vec![Ident::from_str("a").into(), Ident::from_str("b").into()], + segments: vec![ast::PathSegment::crate_root(), + Ident::from_str("a").into(), + Ident::from_str("b").into()] }), span: sp(0, 6), attrs: ThinVec::new(), @@ -757,7 +757,6 @@ mod tests { id: ast::DUMMY_NODE_ID, node:ast::ExprKind::Path(None, ast::Path{ span: sp(7, 8), - global: false, segments: vec![Ident::from_str("d").into()], }), span:sp(7,8), @@ -775,7 +774,6 @@ mod tests { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::Path(None, ast::Path { span:sp(0,1), - global:false, segments: vec![Ident::from_str("b").into()], }), span: sp(0,1), @@ -817,7 +815,6 @@ mod tests { ty: P(ast::Ty{id: ast::DUMMY_NODE_ID, node: ast::TyKind::Path(None, ast::Path{ span:sp(10,13), - global:false, segments: vec![Ident::from_str("i32").into()], }), span:sp(10,13) @@ -860,7 +857,6 @@ mod tests { node: ast::ExprKind::Path(None, ast::Path{ span:sp(17,18), - global:false, segments: vec![Ident::from_str("b").into()], }), span: sp(17,18), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 72462b74e68..cd4f255b5e3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1614,7 +1614,6 @@ impl<'a> Parser<'a> { } else { ast::Path { span: span, - global: false, segments: vec![] } }; @@ -1658,7 +1657,7 @@ impl<'a> Parser<'a> { // Parse any number of segments and bound sets. A segment is an // identifier followed by an optional lifetime and a set of types. // A bound set is a set of type parameter bounds. - let segments = match mode { + let mut segments = match mode { PathStyle::Type => { self.parse_path_segments_without_colons()? } @@ -1670,13 +1669,16 @@ impl<'a> Parser<'a> { } }; + if is_global { + segments.insert(0, ast::PathSegment::crate_root()); + } + // Assemble the span. let span = mk_sp(lo, self.prev_span.hi); // Assemble the result. Ok(ast::Path { span: span, - global: is_global, segments: segments, }) } @@ -5180,7 +5182,7 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(keywords::Crate) { pub_crate(self) } else { - let path = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?.default_to_global(); self.expect(&token::CloseDelim(token::Paren))?; Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }) } @@ -6068,9 +6070,9 @@ impl<'a> Parser<'a> { if self.check(&token::OpenDelim(token::Brace)) || self.check(&token::BinOp(token::Star)) || self.is_import_coupler() { // `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`. + self.eat(&token::ModSep); let prefix = ast::Path { - global: self.eat(&token::ModSep), - segments: Vec::new(), + segments: vec![ast::PathSegment::crate_root()], span: mk_sp(lo, self.span.hi), }; let view_path_kind = if self.eat(&token::BinOp(token::Star)) { @@ -6080,7 +6082,7 @@ impl<'a> Parser<'a> { }; Ok(P(spanned(lo, self.span.hi, view_path_kind))) } else { - let prefix = self.parse_path(PathStyle::Mod)?; + let prefix = self.parse_path(PathStyle::Mod)?.default_to_global(); if self.is_import_coupler() { // `foo::bar::{a, b}` or `foo::bar::*` self.bump(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 22e8391de93..e9c1cbcba61 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -371,7 +371,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String { } pub fn path_to_string(p: &ast::Path) -> String { - to_string(|s| s.print_path(p, false, 0)) + to_string(|s| s.print_path(p, false, 0, false)) } pub fn ident_to_string(id: ast::Ident) -> String { @@ -435,7 +435,8 @@ pub fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String { match *vis { ast::Visibility::Public => format!("pub {}", s), ast::Visibility::Crate(_) => format!("pub(crate) {}", s), - ast::Visibility::Restricted { ref path, .. } => format!("pub({}) {}", path, s), + ast::Visibility::Restricted { ref path, .. } => + format!("pub({}) {}", to_string(|s| s.print_path(path, false, 0, true)), s), ast::Visibility::Inherited => s.to_string() } } @@ -1021,7 +1022,7 @@ impl<'a> State<'a> { &generics)); } ast::TyKind::Path(None, ref path) => { - try!(self.print_path(path, false, 0)); + try!(self.print_path(path, false, 0, false)); } ast::TyKind::Path(Some(ref qself), ref path) => { try!(self.print_qpath(path, qself, false)) @@ -1332,7 +1333,7 @@ impl<'a> State<'a> { } ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => { try!(self.print_visibility(&item.vis)); - try!(self.print_path(&node.path, false, 0)); + try!(self.print_path(&node.path, false, 0, false)); try!(word(&mut self.s, "! ")); try!(self.print_ident(item.ident)); try!(self.cbox(INDENT_UNIT)); @@ -1347,7 +1348,7 @@ impl<'a> State<'a> { } fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> { - self.print_path(&t.path, false, 0) + self.print_path(&t.path, false, 0, false) } fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> { @@ -1405,8 +1406,10 @@ impl<'a> State<'a> { match *vis { ast::Visibility::Public => self.word_nbsp("pub"), ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"), - ast::Visibility::Restricted { ref path, .. } => - self.word_nbsp(&format!("pub({})", path)), + ast::Visibility::Restricted { ref path, .. } => { + let path = to_string(|s| s.print_path(path, false, 0, true)); + self.word_nbsp(&format!("pub({})", path)) + } ast::Visibility::Inherited => Ok(()) } } @@ -1571,7 +1574,7 @@ impl<'a> State<'a> { } ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => { // code copied from ItemKind::Mac: - self.print_path(&node.path, false, 0)?; + self.print_path(&node.path, false, 0, false)?; word(&mut self.s, "! ")?; self.cbox(INDENT_UNIT)?; self.popen()?; @@ -1607,7 +1610,7 @@ impl<'a> State<'a> { } ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => { // code copied from ItemKind::Mac: - try!(self.print_path(&node.path, false, 0)); + try!(self.print_path(&node.path, false, 0, false)); try!(word(&mut self.s, "! ")); try!(self.cbox(INDENT_UNIT)); try!(self.popen()); @@ -1793,7 +1796,7 @@ impl<'a> State<'a> { pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) -> io::Result<()> { - try!(self.print_path(&m.node.path, false, 0)); + try!(self.print_path(&m.node.path, false, 0, false)); try!(word(&mut self.s, "!")); match delim { token::Paren => try!(self.popen()), @@ -1885,7 +1888,7 @@ impl<'a> State<'a> { fields: &[ast::Field], wth: &Option<P<ast::Expr>>, attrs: &[Attribute]) -> io::Result<()> { - try!(self.print_path(path, true, 0)); + try!(self.print_path(path, true, 0, false)); try!(word(&mut self.s, "{")); try!(self.print_inner_attributes_inline(attrs)); try!(self.commasep_cmnt( @@ -2186,7 +2189,7 @@ impl<'a> State<'a> { } } ast::ExprKind::Path(None, ref path) => { - try!(self.print_path(path, true, 0)) + try!(self.print_path(path, true, 0, false)) } ast::ExprKind::Path(Some(ref qself), ref path) => { try!(self.print_qpath(path, qself, true)) @@ -2334,23 +2337,25 @@ impl<'a> State<'a> { fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, - depth: usize) + depth: usize, + defaults_to_global: bool) -> io::Result<()> { try!(self.maybe_print_comment(path.span.lo)); - let mut first = !path.global; - for segment in &path.segments[..path.segments.len()-depth] { - if first { - first = false - } else { + 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() { + if i > 0 { try!(word(&mut self.s, "::")) } - - try!(self.print_ident(segment.identifier)); - - if let Some(ref parameters) = segment.parameters { - try!(self.print_path_parameters(parameters, colons_before_params)) + if segment.identifier.name != keywords::CrateRoot.name() { + try!(self.print_ident(segment.identifier)); + if let Some(ref parameters) = segment.parameters { + try!(self.print_path_parameters(parameters, colons_before_params)); + } } } @@ -2369,7 +2374,7 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.word_space("as")); let depth = path.segments.len() - qself.position; - try!(self.print_path(&path, false, depth)); + try!(self.print_path(&path, false, depth, false)); } try!(word(&mut self.s, ">")); try!(word(&mut self.s, "::")); @@ -2472,7 +2477,7 @@ impl<'a> State<'a> { } } PatKind::TupleStruct(ref path, ref elts, ddpos) => { - try!(self.print_path(path, true, 0)); + try!(self.print_path(path, true, 0, false)); try!(self.popen()); if let Some(ddpos) = ddpos { try!(self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))); @@ -2490,13 +2495,13 @@ impl<'a> State<'a> { try!(self.pclose()); } PatKind::Path(None, ref path) => { - try!(self.print_path(path, true, 0)); + try!(self.print_path(path, true, 0, false)); } PatKind::Path(Some(ref qself), ref path) => { try!(self.print_qpath(path, qself, false)); } PatKind::Struct(ref path, ref fields, etc) => { - try!(self.print_path(path, true, 0)); + try!(self.print_path(path, true, 0, false)); try!(self.nbsp()); try!(self.word_space("{")); try!(self.commasep_cmnt( @@ -2843,7 +2848,7 @@ impl<'a> State<'a> { try!(self.print_lifetime_bounds(lifetime, bounds)); } ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => { - try!(self.print_path(path, false, 0)); + try!(self.print_path(path, false, 0, false)); try!(space(&mut self.s)); try!(self.word_space("=")); try!(self.print_type(&ty)); @@ -2857,7 +2862,7 @@ impl<'a> State<'a> { pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { - try!(self.print_path(path, false, 0)); + try!(self.print_path(path, false, 0, true)); if path.segments.last().unwrap().identifier.name != ident.name { @@ -2870,7 +2875,7 @@ impl<'a> State<'a> { } ast::ViewPathGlob(ref path) => { - try!(self.print_path(path, false, 0)); + try!(self.print_path(path, false, 0, true)); word(&mut self.s, "::*") } @@ -2878,7 +2883,7 @@ impl<'a> State<'a> { if path.segments.is_empty() { try!(word(&mut self.s, "{")); } else { - try!(self.print_path(path, false, 0)); + try!(self.print_path(path, false, 0, true)); try!(word(&mut self.s, "::{")); } try!(self.commasep(Inconsistent, &idents[..], |s, w| { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 4ad760a3caf..68d807b24a7 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -80,8 +80,7 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess, }], vis: ast::Visibility::Inherited, node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path { - global: false, - segments: vec![name, "prelude", "v1"].into_iter().map(|name| { + segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| { ast::Ident::from_str(name).into() }).collect(), span: span, diff --git a/src/libsyntax/symbol.rs b/src/libsyntax/symbol.rs index fe9a176179c..c2123ea5a07 100644 --- a/src/libsyntax/symbol.rs +++ b/src/libsyntax/symbol.rs @@ -221,6 +221,9 @@ declare_keywords! { (53, Default, "default") (54, StaticLifetime, "'static") (55, Union, "union") + + // A virtual keyword that resolves to the crate root when used in a lexical scope. + (56, CrateRoot, "{{root}}") } // If an interner exists in TLS, return it. Otherwise, prepare a fresh one. diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 7709d3bd1cf..b8e0b938814 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -579,7 +579,6 @@ fn nospan<T>(t: T) -> codemap::Spanned<T> { fn path_node(ids: Vec<Ident>) -> ast::Path { ast::Path { span: DUMMY_SP, - global: false, segments: ids.into_iter().map(Into::into).collect(), } } |
