Attach TokenStream
to ast::Path
This commit is contained in:
parent
3815e91ccd
commit
55082ce413
15 changed files with 41 additions and 21 deletions
|
@ -96,6 +96,7 @@ pub struct Path {
|
||||||
/// The segments in the path: the things separated by `::`.
|
/// The segments in the path: the things separated by `::`.
|
||||||
/// Global paths begin with `kw::PathRoot`.
|
/// Global paths begin with `kw::PathRoot`.
|
||||||
pub segments: Vec<PathSegment>,
|
pub segments: Vec<PathSegment>,
|
||||||
|
pub tokens: Option<TokenStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<Symbol> for Path {
|
impl PartialEq<Symbol> for Path {
|
||||||
|
@ -117,7 +118,7 @@ impl Path {
|
||||||
// Convert a span and an identifier to the corresponding
|
// Convert a span and an identifier to the corresponding
|
||||||
// one-segment path.
|
// one-segment path.
|
||||||
pub fn from_ident(ident: Ident) -> Path {
|
pub fn from_ident(ident: Ident) -> Path {
|
||||||
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span }
|
Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_global(&self) -> bool {
|
pub fn is_global(&self) -> bool {
|
||||||
|
@ -1069,7 +1070,7 @@ pub struct Expr {
|
||||||
|
|
||||||
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
rustc_data_structures::static_assert_size!(Expr, 104);
|
rustc_data_structures::static_assert_size!(Expr, 112);
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
/// Returns `true` if this expression would be valid somewhere that expects a value;
|
/// Returns `true` if this expression would be valid somewhere that expects a value;
|
||||||
|
|
|
@ -415,7 +415,7 @@ impl MetaItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
let span = span.with_hi(segments.last().unwrap().ident.span.hi());
|
||||||
Path { span, segments }
|
Path { span, segments, tokens: None }
|
||||||
}
|
}
|
||||||
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
|
||||||
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
|
||||||
|
|
|
@ -513,7 +513,7 @@ pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis:
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noop_visit_path<T: MutVisitor>(Path { segments, span }: &mut Path, vis: &mut T) {
|
pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens: _ }: &mut Path, vis: &mut T) {
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
for PathSegment { ident, id, args } in segments {
|
for PathSegment { ident, id, args } in segments {
|
||||||
vis.visit_ident(ident);
|
vis.visit_ident(ident);
|
||||||
|
|
|
@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
|
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
|
||||||
ItemKind::Use(ref use_tree) => {
|
ItemKind::Use(ref use_tree) => {
|
||||||
// Start with an empty prefix.
|
// Start with an empty prefix.
|
||||||
let prefix = Path { segments: vec![], span: use_tree.span };
|
let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
|
||||||
|
|
||||||
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
|
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
*ident = tree.ident();
|
*ident = tree.ident();
|
||||||
|
|
||||||
// First, apply the prefix to the path.
|
// First, apply the prefix to the path.
|
||||||
let mut path = Path { segments, span: path.span };
|
let mut path = Path { segments, span: path.span, tokens: None };
|
||||||
|
|
||||||
// Correctly resolve `self` imports.
|
// Correctly resolve `self` imports.
|
||||||
if path.segments.len() > 1
|
if path.segments.len() > 1
|
||||||
|
@ -540,8 +540,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::ItemKind::Use(path, hir::UseKind::Single)
|
hir::ItemKind::Use(path, hir::UseKind::Single)
|
||||||
}
|
}
|
||||||
UseTreeKind::Glob => {
|
UseTreeKind::Glob => {
|
||||||
let path =
|
let path = self.lower_path(
|
||||||
self.lower_path(id, &Path { segments, span: path.span }, ParamMode::Explicit);
|
id,
|
||||||
|
&Path { segments, span: path.span, tokens: None },
|
||||||
|
ParamMode::Explicit,
|
||||||
|
);
|
||||||
hir::ItemKind::Use(path, hir::UseKind::Glob)
|
hir::ItemKind::Use(path, hir::UseKind::Glob)
|
||||||
}
|
}
|
||||||
UseTreeKind::Nested(ref trees) => {
|
UseTreeKind::Nested(ref trees) => {
|
||||||
|
@ -569,7 +572,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// for that we return the `{}` import (called the
|
// for that we return the `{}` import (called the
|
||||||
// `ListStem`).
|
// `ListStem`).
|
||||||
|
|
||||||
let prefix = Path { segments, span: prefix.span.to(path.span) };
|
let prefix = Path { segments, span: prefix.span.to(path.span), tokens: None };
|
||||||
|
|
||||||
// Add all the nested `PathListItem`s to the HIR.
|
// Add all the nested `PathListItem`s to the HIR.
|
||||||
for &(ref use_tree, id) in trees {
|
for &(ref use_tree, id) in trees {
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
args,
|
args,
|
||||||
});
|
});
|
||||||
ast::Path { span, segments }
|
ast::Path { span, segments, tokens: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
|
pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn placeholder(
|
||||||
) -> AstFragment {
|
) -> AstFragment {
|
||||||
fn mac_placeholder() -> ast::MacCall {
|
fn mac_placeholder() -> ast::MacCall {
|
||||||
ast::MacCall {
|
ast::MacCall {
|
||||||
path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
|
path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None },
|
||||||
args: P(ast::MacArgs::Empty),
|
args: P(ast::MacArgs::Empty),
|
||||||
prior_type_ascription: None,
|
prior_type_ascription: None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,6 +278,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
|
||||||
Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into())
|
Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into())
|
||||||
}
|
}
|
||||||
Nonterminal::NtMeta(ref attr) => attr.tokens.clone(),
|
Nonterminal::NtMeta(ref attr) => attr.tokens.clone(),
|
||||||
|
Nonterminal::NtPath(ref path) => path.tokens.clone(),
|
||||||
Nonterminal::NtTT(ref tt) => Some(tt.clone().into()),
|
Nonterminal::NtTT(ref tt) => Some(tt.clone().into()),
|
||||||
Nonterminal::NtExpr(ref expr) | Nonterminal::NtLiteral(ref expr) => {
|
Nonterminal::NtExpr(ref expr) | Nonterminal::NtLiteral(ref expr) => {
|
||||||
if expr.tokens.is_none() {
|
if expr.tokens.is_none() {
|
||||||
|
|
|
@ -901,7 +901,7 @@ impl<'a> Parser<'a> {
|
||||||
) -> PResult<'a, P<T>> {
|
) -> PResult<'a, P<T>> {
|
||||||
self.expect(&token::ModSep)?;
|
self.expect(&token::ModSep)?;
|
||||||
|
|
||||||
let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP };
|
let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP, tokens: None };
|
||||||
self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
|
self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?;
|
||||||
path.span = ty_span.to(self.prev_token.span);
|
path.span = ty_span.to(self.prev_token.span);
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,7 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
|
fn parse_use_tree(&mut self) -> PResult<'a, UseTree> {
|
||||||
let lo = self.token.span;
|
let lo = self.token.span;
|
||||||
|
|
||||||
let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() };
|
let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None };
|
||||||
let kind = if self.check(&token::OpenDelim(token::Brace))
|
let kind = if self.check(&token::OpenDelim(token::Brace))
|
||||||
|| self.check(&token::BinOp(token::Star))
|
|| self.check(&token::BinOp(token::Star))
|
||||||
|| self.is_import_coupler()
|
|| self.is_import_coupler()
|
||||||
|
|
|
@ -168,7 +168,15 @@ impl<'a> Parser<'a> {
|
||||||
return Err(self.struct_span_err(self.token.span, msg));
|
return Err(self.struct_span_err(self.token.span, msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NonterminalKind::Path => token::NtPath(self.parse_path(PathStyle::Type)?),
|
NonterminalKind::Path => {
|
||||||
|
let (mut path, tokens) =
|
||||||
|
self.collect_tokens(|this| this.parse_path(PathStyle::Type))?;
|
||||||
|
// We have have eaten an NtPath, which could already have tokens
|
||||||
|
if path.tokens.is_none() {
|
||||||
|
path.tokens = Some(tokens);
|
||||||
|
}
|
||||||
|
token::NtPath(path)
|
||||||
|
}
|
||||||
NonterminalKind::Meta => {
|
NonterminalKind::Meta => {
|
||||||
let (mut attr, tokens) = self.collect_tokens(|this| this.parse_attr_item())?;
|
let (mut attr, tokens) = self.collect_tokens(|this| this.parse_attr_item())?;
|
||||||
// We may have eaten a nonterminal, which could already have tokens
|
// We may have eaten a nonterminal, which could already have tokens
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a> Parser<'a> {
|
||||||
path_span = path_lo.to(self.prev_token.span);
|
path_span = path_lo.to(self.prev_token.span);
|
||||||
} else {
|
} else {
|
||||||
path_span = self.token.span.to(self.token.span);
|
path_span = self.token.span.to(self.token.span);
|
||||||
path = ast::Path { segments: Vec::new(), span: path_span };
|
path = ast::Path { segments: Vec::new(), span: path_span, tokens: None };
|
||||||
}
|
}
|
||||||
|
|
||||||
// See doc comment for `unmatched_angle_bracket_count`.
|
// See doc comment for `unmatched_angle_bracket_count`.
|
||||||
|
@ -81,7 +81,10 @@ impl<'a> Parser<'a> {
|
||||||
let qself = QSelf { ty, path_span, position: path.segments.len() };
|
let qself = QSelf { ty, path_span, position: path.segments.len() };
|
||||||
self.parse_path_segments(&mut path.segments, style)?;
|
self.parse_path_segments(&mut path.segments, style)?;
|
||||||
|
|
||||||
Ok((qself, Path { segments: path.segments, span: lo.to(self.prev_token.span) }))
|
Ok((
|
||||||
|
qself,
|
||||||
|
Path { segments: path.segments, span: lo.to(self.prev_token.span), tokens: None },
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recover from an invalid single colon, when the user likely meant a qualified path.
|
/// Recover from an invalid single colon, when the user likely meant a qualified path.
|
||||||
|
@ -144,7 +147,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
self.parse_path_segments(&mut segments, style)?;
|
self.parse_path_segments(&mut segments, style)?;
|
||||||
|
|
||||||
Ok(Path { segments, span: lo.to(self.prev_token.span) })
|
Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn parse_path_segments(
|
pub(super) fn parse_path_segments(
|
||||||
|
|
|
@ -794,7 +794,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
segms.push(ast::PathSegment::from_ident(ident));
|
segms.push(ast::PathSegment::from_ident(ident));
|
||||||
let path = Path { span: name_binding.span, segments: segms };
|
let path = Path { span: name_binding.span, segments: segms, tokens: None };
|
||||||
let did = match res {
|
let did = match res {
|
||||||
Res::Def(DefKind::Ctor(..), did) => this.parent(did),
|
Res::Def(DefKind::Ctor(..), did) => this.parent(did),
|
||||||
_ => res.opt_def_id(),
|
_ => res.opt_def_id(),
|
||||||
|
|
|
@ -1967,7 +1967,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
|
|
||||||
if qself.is_none() {
|
if qself.is_none() {
|
||||||
let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
|
let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
|
||||||
let path = Path { segments: path.iter().map(path_seg).collect(), span };
|
let path = Path { segments: path.iter().map(path_seg).collect(), span, tokens: None };
|
||||||
if let Ok((_, res)) =
|
if let Ok((_, res)) =
|
||||||
self.r.resolve_macro_path(&path, None, &self.parent_scope, false, false)
|
self.r.resolve_macro_path(&path, None, &self.parent_scope, false, false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,6 +83,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str
|
||||||
let enum_path = ast::Path {
|
let enum_path = ast::Path {
|
||||||
span: suggestion.path.span,
|
span: suggestion.path.span,
|
||||||
segments: suggestion.path.segments[0..path_len - 1].to_vec(),
|
segments: suggestion.path.segments[0..path_len - 1].to_vec(),
|
||||||
|
tokens: None,
|
||||||
};
|
};
|
||||||
let enum_path_string = path_names_to_string(&enum_path);
|
let enum_path_string = path_names_to_string(&enum_path);
|
||||||
|
|
||||||
|
@ -1065,7 +1066,8 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||||
path_segments.push(ast::PathSegment::from_ident(ident));
|
path_segments.push(ast::PathSegment::from_ident(ident));
|
||||||
let module_def_id = module.def_id().unwrap();
|
let module_def_id = module.def_id().unwrap();
|
||||||
if module_def_id == def_id {
|
if module_def_id == def_id {
|
||||||
let path = Path { span: name_binding.span, segments: path_segments };
|
let path =
|
||||||
|
Path { span: name_binding.span, segments: path_segments, tokens: None };
|
||||||
result = Some((
|
result = Some((
|
||||||
module,
|
module,
|
||||||
ImportSuggestion {
|
ImportSuggestion {
|
||||||
|
@ -1095,7 +1097,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||||
if let Res::Def(DefKind::Variant, _) = name_binding.res() {
|
if let Res::Def(DefKind::Variant, _) = name_binding.res() {
|
||||||
let mut segms = enum_import_suggestion.path.segments.clone();
|
let mut segms = enum_import_suggestion.path.segments.clone();
|
||||||
segms.push(ast::PathSegment::from_ident(ident));
|
segms.push(ast::PathSegment::from_ident(ident));
|
||||||
variants.push(Path { span: name_binding.span, segments: segms });
|
variants.push(Path { span: name_binding.span, segments: segms, tokens: None });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
variants
|
variants
|
||||||
|
|
|
@ -3189,6 +3189,7 @@ impl<'a> Resolver<'a> {
|
||||||
.chain(path_str.split("::").skip(1).map(Ident::from_str))
|
.chain(path_str.split("::").skip(1).map(Ident::from_str))
|
||||||
.map(|i| self.new_ast_path_segment(i))
|
.map(|i| self.new_ast_path_segment(i))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
tokens: None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ast::Path {
|
ast::Path {
|
||||||
|
@ -3198,6 +3199,7 @@ impl<'a> Resolver<'a> {
|
||||||
.map(Ident::from_str)
|
.map(Ident::from_str)
|
||||||
.map(|i| self.new_ast_path_segment(i))
|
.map(|i| self.new_ast_path_segment(i))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
tokens: None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let module = self.get_module(module_id);
|
let module = self.get_module(module_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue