Attach `TokenStream` to `ast::Visibility`

A `Visibility` does not have outer attributes, so we only capture tokens
when parsing a `macro_rules!` matcher
This commit is contained in:
Aaron Hill 2020-08-21 19:11:00 -04:00
parent 55082ce413
commit c1011165e6
No known key found for this signature in database
GPG Key ID: B4087E510E98B164
22 changed files with 120 additions and 50 deletions

View File

@ -2490,7 +2490,12 @@ pub enum CrateSugar {
JustCrate,
}
pub type Visibility = Spanned<VisibilityKind>;
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Visibility {
pub kind: VisibilityKind,
pub span: Span,
pub tokens: Option<TokenStream>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum VisibilityKind {

View File

@ -14,7 +14,7 @@ use crate::tokenstream::*;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::sync::Lrc;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident;
use rustc_span::Span;
@ -978,11 +978,13 @@ pub fn noop_visit_mod<T: MutVisitor>(module: &mut Mod, vis: &mut T) {
pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
visit_clobber(krate, |Crate { module, attrs, span, proc_macros }| {
let item_vis =
Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None };
let item = P(Item {
ident: Ident::invalid(),
attrs,
id: DUMMY_NODE_ID,
vis: respan(span.shrink_to_lo(), VisibilityKind::Public),
vis: item_vis,
span,
kind: ItemKind::Mod(module),
tokens: None,
@ -1314,13 +1316,13 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
}
}
pub fn noop_visit_vis<T: MutVisitor>(Spanned { node, span }: &mut Visibility, vis: &mut T) {
match node {
pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
match &mut visibility.kind {
VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {}
VisibilityKind::Restricted { path, id } => {
vis.visit_path(path);
vis.visit_id(id);
}
}
vis.visit_span(span);
vis.visit_span(&mut visibility.span);
}

View File

@ -879,7 +879,7 @@ pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
}
pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
if let VisibilityKind::Restricted { ref path, id } = vis.node {
if let VisibilityKind::Restricted { ref path, id } = vis.kind {
visitor.visit_path(path, id);
}
}

View File

@ -930,7 +930,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
v: &Visibility,
explicit_owner: Option<NodeId>,
) -> hir::Visibility<'hir> {
let node = match v.node {
let node = match v.kind {
VisibilityKind::Public => hir::VisibilityKind::Public,
VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
VisibilityKind::Restricted { ref path, id } => {

View File

@ -198,13 +198,13 @@ impl<'a> AstValidator<'a> {
}
fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
if let VisibilityKind::Inherited = vis.node {
if let VisibilityKind::Inherited = vis.kind {
return;
}
let mut err =
struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier");
if vis.node.is_pub() {
if vis.kind.is_pub() {
err.span_label(vis.span, "`pub` not permitted here because it's implied");
}
if let Some(note) = note {

View File

@ -594,7 +594,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
fn visit_vis(&mut self, vis: &'a ast::Visibility) {
if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.kind {
gate_feature_post!(
&self,
crate_visibility_modifier,

View File

@ -1359,7 +1359,7 @@ impl<'a> State<'a> {
}
crate fn print_visibility(&mut self, vis: &ast::Visibility) {
match vis.node {
match vis.kind {
ast::VisibilityKind::Public => self.word_nbsp("pub"),
ast::VisibilityKind::Crate(sugar) => match sugar {
ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"),

View File

@ -187,7 +187,6 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr;
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::source_map::respan;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
@ -532,7 +531,11 @@ impl<'a> TraitDef<'a> {
id: ast::DUMMY_NODE_ID,
span: self.span,
ident,
vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: self.span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
attrs: Vec::new(),
kind: ast::AssocItemKind::TyAlias(
ast::Defaultness::Final,
@ -933,7 +936,11 @@ impl<'a> MethodDef<'a> {
id: ast::DUMMY_NODE_ID,
attrs: self.attributes.clone(),
span: trait_.span,
vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: trait_lo_sp,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
ident: method_ident,
kind: ast::AssocItemKind::Fn(def, sig, fn_generics, Some(body_block)),
tokens: None,

View File

@ -14,7 +14,6 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::DiagnosticBuilder;
use rustc_expand::base::{self, *};
use rustc_span::source_map::respan;
use rustc_span::symbol::Ident;
use rustc_span::Span;
use smallvec::smallvec;
@ -30,7 +29,11 @@ pub fn expand_global_asm<'cx>(
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
kind: ast::ItemKind::GlobalAsm(P(global_asm)),
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: sp.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span: cx.with_def_site_ctxt(sp),
tokens: None,
})]),

View File

@ -98,7 +98,7 @@ pub fn inject(
impl<'a> CollectProcMacros<'a> {
fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
if self.is_proc_macro_crate && self.in_root && vis.node.is_pub() {
if self.is_proc_macro_crate && self.in_root && vis.kind.is_pub() {
self.handler.span_err(
sp,
"`proc-macro` crate types currently cannot export any items other \
@ -184,7 +184,7 @@ impl<'a> CollectProcMacros<'a> {
Vec::new()
};
if self.in_root && item.vis.node.is_pub() {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Derive(ProcMacroDerive {
id: item.id,
span: item.span,
@ -204,7 +204,7 @@ impl<'a> CollectProcMacros<'a> {
}
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
if self.in_root && item.vis.node.is_pub() {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Def(ProcMacroDef {
id: item.id,
span: item.span,
@ -223,7 +223,7 @@ impl<'a> CollectProcMacros<'a> {
}
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
if self.in_root && item.vis.node.is_pub() {
if self.in_root && item.vis.kind.is_pub() {
self.macros.push(ProcMacro::Def(ProcMacroDef {
id: item.id,
span: item.span,

View File

@ -7,7 +7,6 @@ use rustc_ast::attr;
use rustc_ast_pretty::pprust;
use rustc_expand::base::*;
use rustc_session::Session;
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@ -35,7 +34,11 @@ pub fn expand_test_case(
let sp = ecx.with_def_site_ctxt(attr_sp);
let mut item = anno_item.expect_item();
item = item.map(|mut item| {
item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
item.vis = ast::Visibility {
span: item.vis.span,
kind: ast::VisibilityKind::Public,
tokens: None,
};
item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
item.attrs.push(ecx.attribute(ecx.meta_word(sp, sym::rustc_test_marker)));
item
@ -292,7 +295,7 @@ pub fn expand_test_or_bench(
),
);
test_const = test_const.map(|mut tc| {
tc.vis.node = ast::VisibilityKind::Public;
tc.vis.kind = ast::VisibilityKind::Public;
tc
});

View File

@ -10,7 +10,6 @@ use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
use rustc_session::Session;
use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::PanicStrategy;
@ -333,7 +332,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
attrs: vec![main_attr],
id: ast::DUMMY_NODE_ID,
kind: main,
vis: respan(sp, ast::VisibilityKind::Public),
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },
span: sp,
tokens: None,
});

View File

@ -3,7 +3,7 @@ use crate::base::ExtCtxt;
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, PatKind, UnOp};
use rustc_span::source_map::{respan, Spanned};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
@ -584,7 +584,11 @@ impl<'a> ExtCtxt<'a> {
attrs,
id: ast::DUMMY_NODE_ID,
kind,
vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span,
tokens: None,
})
@ -598,7 +602,11 @@ impl<'a> ExtCtxt<'a> {
span: ty.span,
ty,
ident: None,
vis: respan(vis_span, ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
@ -617,7 +625,11 @@ impl<'a> ExtCtxt<'a> {
disr_expr: None,
id: ast::DUMMY_NODE_ID,
ident,
vis: respan(vis_span, ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span,
is_placeholder: false,
}

View File

@ -26,7 +26,6 @@ use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::parse::{feature_err, ParseSess};
use rustc_session::Limit;
use rustc_span::source_map::respan;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{ExpnId, FileName, Span, DUMMY_SP};
@ -358,7 +357,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
kind: ast::ItemKind::Mod(krate.module),
ident: Ident::invalid(),
id: ast::DUMMY_NODE_ID,
vis: respan(krate.span.shrink_to_lo(), ast::VisibilityKind::Public),
vis: ast::Visibility {
span: krate.span.shrink_to_lo(),
kind: ast::VisibilityKind::Public,
tokens: None,
},
tokens: None,
})]);

View File

@ -4,7 +4,7 @@ use crate::expand::{AstFragment, AstFragmentKind};
use rustc_ast as ast;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_span::source_map::{dummy_spanned, DUMMY_SP};
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::Ident;
use smallvec::{smallvec, SmallVec};
@ -26,7 +26,11 @@ pub fn placeholder(
let ident = Ident::invalid();
let attrs = Vec::new();
let vis = vis.unwrap_or_else(|| dummy_spanned(ast::VisibilityKind::Inherited));
let vis = vis.unwrap_or(ast::Visibility {
span: DUMMY_SP,
kind: ast::VisibilityKind::Inherited,
tokens: None,
});
let span = DUMMY_SP;
let expr_placeholder = || {
P(ast::Expr {

View File

@ -18,7 +18,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::utils::NativeLibKind;
use rustc_session::{CrateDisambiguator, Session};
use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::Symbol;
use rustc_data_structures::sync::Lrc;
@ -421,7 +421,11 @@ impl CStore {
span,
attrs: attrs.to_vec(),
kind: ast::ItemKind::MacroDef(data.get_macro(id.index, sess)),
vis: source_map::respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
vis: ast::Visibility {
span: span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
tokens: None,
},
data.root.edition,

View File

@ -279,6 +279,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
}
Nonterminal::NtMeta(ref attr) => attr.tokens.clone(),
Nonterminal::NtPath(ref path) => path.tokens.clone(),
Nonterminal::NtVis(ref vis) => vis.tokens.clone(),
Nonterminal::NtTT(ref tt) => Some(tt.clone().into()),
Nonterminal::NtExpr(ref expr) | Nonterminal::NtLiteral(ref expr) => {
if expr.tokens.is_none() {
@ -286,7 +287,6 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke
}
prepend_attrs(sess, &expr.attrs, expr.tokens.as_ref(), span)
}
_ => None,
};
// FIXME(#43081): Avoid this pretty-print + reparse hack

View File

@ -187,7 +187,7 @@ impl<'a> Parser<'a> {
/// Error in-case a non-inherited visibility was parsed but no item followed.
fn error_on_unmatched_vis(&self, vis: &Visibility) {
if let VisibilityKind::Inherited = vis.node {
if let VisibilityKind::Inherited = vis.kind {
return;
}
let vs = pprust::vis_to_string(&vis);
@ -296,7 +296,7 @@ impl<'a> Parser<'a> {
} else if self.is_macro_rules_item() {
// MACRO_RULES ITEM
self.parse_item_macro_rules(vis)?
} else if vis.node.is_pub() && self.isnt_macro_invocation() {
} else if vis.kind.is_pub() && self.isnt_macro_invocation() {
self.recover_missing_kw_before_item()?;
return Ok(None);
} else if macros_allowed && self.check_path() {
@ -1418,7 +1418,7 @@ impl<'a> Parser<'a> {
/// Item macro invocations or `macro_rules!` definitions need inherited visibility.
/// If that's not the case, emit an error.
fn complain_if_pub_macro(&self, vis: &Visibility, macro_rules: bool) {
if let VisibilityKind::Inherited = vis.node {
if let VisibilityKind::Inherited = vis.kind {
return;
}

View File

@ -22,7 +22,7 @@ use rustc_ast::{Async, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, Vi
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError, PResult};
use rustc_session::parse::ParseSess;
use rustc_span::source_map::{respan, Span, DUMMY_SP};
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use tracing::debug;
@ -1022,14 +1022,22 @@ impl<'a> Parser<'a> {
if self.is_crate_vis() {
self.bump(); // `crate`
self.sess.gated_spans.gate(sym::crate_visibility_modifier, self.prev_token.span);
return Ok(respan(self.prev_token.span, VisibilityKind::Crate(CrateSugar::JustCrate)));
return Ok(Visibility {
span: self.prev_token.span,
kind: VisibilityKind::Crate(CrateSugar::JustCrate),
tokens: None,
});
}
if !self.eat_keyword(kw::Pub) {
// We need a span for our `Spanned<VisibilityKind>`, but there's inherently no
// keyword to grab a span from for inherited visibility; an empty span at the
// beginning of the current token would seem to be the "Schelling span".
return Ok(respan(self.token.span.shrink_to_lo(), VisibilityKind::Inherited));
return Ok(Visibility {
span: self.token.span.shrink_to_lo(),
kind: VisibilityKind::Inherited,
tokens: None,
});
}
let lo = self.prev_token.span;
@ -1046,7 +1054,11 @@ impl<'a> Parser<'a> {
self.bump(); // `crate`
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let vis = VisibilityKind::Crate(CrateSugar::PubCrate);
return Ok(respan(lo.to(self.prev_token.span), vis));
return Ok(Visibility {
span: lo.to(self.prev_token.span),
kind: vis,
tokens: None,
});
} else if self.is_keyword_ahead(1, &[kw::In]) {
// Parse `pub(in path)`.
self.bump(); // `(`
@ -1054,7 +1066,11 @@ impl<'a> Parser<'a> {
let path = self.parse_path(PathStyle::Mod)?; // `path`
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
return Ok(respan(lo.to(self.prev_token.span), vis));
return Ok(Visibility {
span: lo.to(self.prev_token.span),
kind: vis,
tokens: None,
});
} else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren))
&& self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
{
@ -1063,7 +1079,11 @@ impl<'a> Parser<'a> {
let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
self.expect(&token::CloseDelim(token::Paren))?; // `)`
let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
return Ok(respan(lo.to(self.prev_token.span), vis));
return Ok(Visibility {
span: lo.to(self.prev_token.span),
kind: vis,
tokens: None,
});
} else if let FollowedByType::No = fbt {
// Provide this diagnostic if a type cannot follow;
// in particular, if this is not a tuple struct.
@ -1072,7 +1092,7 @@ impl<'a> Parser<'a> {
}
}
Ok(respan(lo, VisibilityKind::Public))
Ok(Visibility { span: lo, kind: VisibilityKind::Public, tokens: None })
}
/// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`

View File

@ -186,7 +186,15 @@ impl<'a> Parser<'a> {
token::NtMeta(P(attr))
}
NonterminalKind::TT => token::NtTT(self.parse_token_tree()),
NonterminalKind::Vis => token::NtVis(self.parse_visibility(FollowedByType::Yes)?),
NonterminalKind::Vis => {
let (mut vis, tokens) =
self.collect_tokens(|this| this.parse_visibility(FollowedByType::Yes))?;
// We may have etan an `NtVis`, which could already have tokens
if vis.tokens.is_none() {
vis.tokens = Some(tokens);
}
token::NtVis(vis)
}
NonterminalKind::Lifetime => {
if self.check_lifetime() {
token::NtLifetime(self.expect_lifetime().ident)

View File

@ -218,7 +218,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
speculative: bool,
) -> Result<ty::Visibility, VisResolutionError<'ast>> {
let parent_scope = &self.parent_scope;
match vis.node {
match vis.kind {
ast::VisibilityKind::Public => Ok(ty::Visibility::Public),
ast::VisibilityKind::Crate(..) => {
Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))

View File

@ -105,7 +105,7 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> {
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if let ast::ItemKind::Use(..) = item.kind {
if item.vis.node.is_pub() || item.span.is_dummy() {
if item.vis.kind.is_pub() || item.span.is_dummy() {
return;
}
}