Auto merge of #48917 - petrochenkov:import, r=oli-obk

syntax: Make imports in AST closer to the source and cleanup their parsing

This is a continuation of https://github.com/rust-lang/rust/pull/45846 in some sense.
This commit is contained in:
bors 2018-03-18 01:50:52 +00:00
commit 5e3ecdce4e
39 changed files with 228 additions and 260 deletions

View file

@ -1508,7 +1508,7 @@ impl<'a> Parser<'a> {
if self.eat(&token::RArrow) {
Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?))
} else {
Ok(FunctionRetTy::Default(self.span.with_hi(self.span.lo())))
Ok(FunctionRetTy::Default(self.span.shrink_to_lo()))
}
}
@ -1986,7 +1986,7 @@ impl<'a> Parser<'a> {
let lo = self.meta_var_span.unwrap_or(self.span);
let mut segments = Vec::new();
if self.eat(&token::ModSep) {
segments.push(PathSegment::crate_root(lo));
segments.push(PathSegment::crate_root(lo.shrink_to_lo()));
}
self.parse_path_segments(&mut segments, style, enable_warning)?;
@ -2021,7 +2021,7 @@ impl<'a> Parser<'a> {
loop {
segments.push(self.parse_path_segment(style, enable_warning)?);
if self.is_import_coupler(false) || !self.eat(&token::ModSep) {
if self.is_import_coupler() || !self.eat(&token::ModSep) {
return Ok(());
}
}
@ -5863,7 +5863,7 @@ impl<'a> Parser<'a> {
// `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),
@ -5876,7 +5876,7 @@ impl<'a> Parser<'a> {
{
// `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),
@ -6285,23 +6285,17 @@ impl<'a> Parser<'a> {
lo: Span,
visibility: Visibility,
attrs: Vec<Attribute>)
-> PResult<'a, P<Item>> {
let crate_name = self.parse_ident()?;
let (maybe_path, ident) = if let Some(ident) = self.parse_rename()? {
(Some(crate_name.name), ident)
-> PResult<'a, P<Item>> {
let orig_name = self.parse_ident()?;
let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
(rename, Some(orig_name.name))
} else {
(None, crate_name)
(orig_name, None)
};
self.expect(&token::Semi)?;
let prev_span = self.prev_span;
Ok(self.mk_item(lo.to(prev_span),
ident,
ItemKind::ExternCrate(maybe_path),
visibility,
attrs))
let span = lo.to(self.prev_span);
Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
}
/// Parse `extern` for foreign ABIs
@ -6480,12 +6474,11 @@ impl<'a> Parser<'a> {
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;
let invalid = keywords::Invalid.ident();
let item = self.mk_item(lo.to(prev_span), invalid, item_, visibility, attrs);
let span = lo.to(self.prev_span);
let item = self.mk_item(span, keywords::Invalid.ident(), item_, visibility, attrs);
return Ok(Some(item));
}
@ -6960,90 +6953,53 @@ impl<'a> Parser<'a> {
}))
}
/// `{` or `::{` or `*` or `::*`
/// `::{` or `::*` (also `{` or `*` if unprefixed is true)
fn is_import_coupler(&mut self, unprefixed: bool) -> bool {
self.is_import_coupler_inner(&token::OpenDelim(token::Brace), unprefixed) ||
self.is_import_coupler_inner(&token::BinOp(token::Star), unprefixed)
}
fn is_import_coupler_inner(&mut self, token: &token::Token, unprefixed: bool) -> bool {
if self.check(&token::ModSep) {
self.look_ahead(1, |t| t == token)
} else if unprefixed {
self.check(token)
} else {
false
}
/// `::{` or `::*`
fn is_import_coupler(&mut self) -> bool {
self.check(&token::ModSep) &&
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) ||
*t == token::BinOp(token::Star))
}
/// Parse UseTree
///
/// USE_TREE = `*` |
/// `{` USE_TREE_LIST `}` |
/// USE_TREE = [`::`] `*` |
/// [`::`] `{` USE_TREE_LIST `}` |
/// 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 {
segments: vec![],
span: lo.to(self.span),
};
let kind = if self.is_import_coupler(true) {
// `use *;` or `use ::*;` or `use {...};` `use ::{...};`
// Remove the first `::`
let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
let kind = if self.check(&token::OpenDelim(token::Brace)) ||
self.check(&token::BinOp(token::Star)) ||
self.is_import_coupler() {
// `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
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));
prefix.segments.push(PathSegment::crate_root(lo.shrink_to_lo()));
}
if self.eat(&token::BinOp(token::Star)) {
// `use *;`
UseTreeKind::Glob
} else if self.check(&token::OpenDelim(token::Brace)) {
// `use {...};`
UseTreeKind::Nested(self.parse_use_tree_list()?)
} else {
return self.unexpected();
UseTreeKind::Nested(self.parse_use_tree_list()?)
}
} 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);
// `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
prefix = self.parse_path(PathStyle::Mod)?;
if self.eat(&token::ModSep) {
if self.eat(&token::BinOp(token::Star)) {
// `use path::*;`
UseTreeKind::Glob
} else if self.check(&token::OpenDelim(token::Brace)) {
// `use path::{...};`
UseTreeKind::Nested(self.parse_use_tree_list()?)
} else {
return self.unexpected();
UseTreeKind::Nested(self.parse_use_tree_list()?)
}
} else {
// `use path::foo;` or `use path::foo as bar;`
let rename = self.parse_rename()?.
unwrap_or(prefix.segments.last().unwrap().identifier);
UseTreeKind::Simple(rename)
UseTreeKind::Simple(self.parse_rename()?)
}
};
Ok(UseTree {
span: lo.to(self.prev_span),
kind,
prefix,
})
Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) })
}
/// Parse UseTreeKind::Nested(list)
@ -7053,7 +7009,7 @@ impl<'a> Parser<'a> {
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))
})
}