Rollup merge of #101602 - nnethercote:AttrTokenStream, r=petrochenkov
Streamline `AttrAnnotatedTokenStream` r? ```@petrochenkov```
This commit is contained in:
commit
db75d7e14b
11 changed files with 181 additions and 200 deletions
|
@ -24,7 +24,7 @@ pub use UnsafeSource::*;
|
|||
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Delimiter};
|
||||
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream};
|
||||
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -91,7 +91,7 @@ pub struct Path {
|
|||
/// The segments in the path: the things separated by `::`.
|
||||
/// Global paths begin with `kw::PathRoot`.
|
||||
pub segments: Vec<PathSegment>,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
impl PartialEq<Symbol> for Path {
|
||||
|
@ -534,7 +534,7 @@ pub struct Block {
|
|||
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
|
||||
pub rules: BlockCheckMode,
|
||||
pub span: Span,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
/// The following *isn't* a parse error, but will cause multiple errors in following stages.
|
||||
/// ```compile_fail
|
||||
/// let x = {
|
||||
|
@ -553,7 +553,7 @@ pub struct Pat {
|
|||
pub id: NodeId,
|
||||
pub kind: PatKind,
|
||||
pub span: Span,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
impl Pat {
|
||||
|
@ -937,8 +937,8 @@ impl Stmt {
|
|||
/// a trailing semicolon.
|
||||
///
|
||||
/// This only modifies the parsed AST struct, not the attached
|
||||
/// `LazyTokenStream`. The parser is responsible for calling
|
||||
/// `CreateTokenStream::add_trailing_semi` when there is actually
|
||||
/// `LazyAttrTokenStream`. The parser is responsible for calling
|
||||
/// `ToAttrTokenStream::add_trailing_semi` when there is actually
|
||||
/// a semicolon in the tokenstream.
|
||||
pub fn add_trailing_semicolon(mut self) -> Self {
|
||||
self.kind = match self.kind {
|
||||
|
@ -984,7 +984,7 @@ pub struct MacCallStmt {
|
|||
pub mac: P<MacCall>,
|
||||
pub style: MacStmtStyle,
|
||||
pub attrs: AttrVec,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)]
|
||||
|
@ -1009,7 +1009,7 @@ pub struct Local {
|
|||
pub kind: LocalKind,
|
||||
pub span: Span,
|
||||
pub attrs: AttrVec,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
|
@ -1108,7 +1108,7 @@ pub struct Expr {
|
|||
pub kind: ExprKind,
|
||||
pub span: Span,
|
||||
pub attrs: AttrVec,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
|
@ -1967,7 +1967,7 @@ pub struct Ty {
|
|||
pub id: NodeId,
|
||||
pub kind: TyKind,
|
||||
pub span: Span,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
impl Clone for Ty {
|
||||
|
@ -2532,7 +2532,7 @@ impl<D: Decoder> Decodable<D> for AttrId {
|
|||
pub struct AttrItem {
|
||||
pub path: Path,
|
||||
pub args: MacArgs,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
/// A list of attributes.
|
||||
|
@ -2552,7 +2552,7 @@ pub struct Attribute {
|
|||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct NormalAttr {
|
||||
pub item: AttrItem,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
|
@ -2603,7 +2603,7 @@ impl PolyTraitRef {
|
|||
pub struct Visibility {
|
||||
pub kind: VisibilityKind,
|
||||
pub span: Span,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
|
@ -2689,7 +2689,7 @@ pub struct Item<K = ItemKind> {
|
|||
///
|
||||
/// Note that the tokens here do not include the outer attributes, but will
|
||||
/// include inner attributes.
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
pub tokens: Option<LazyAttrTokenStream>,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use crate::ptr::P;
|
||||
use crate::token::Nonterminal;
|
||||
use crate::tokenstream::LazyTokenStream;
|
||||
use crate::tokenstream::LazyAttrTokenStream;
|
||||
use crate::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant};
|
||||
use crate::{AssocItem, Expr, ForeignItem, Item, NodeId};
|
||||
use crate::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility};
|
||||
|
@ -124,18 +124,18 @@ impl HasSpan for AttrItem {
|
|||
|
||||
/// A trait for AST nodes having (or not having) collected tokens.
|
||||
pub trait HasTokens {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream>;
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>>;
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream>;
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>>;
|
||||
}
|
||||
|
||||
macro_rules! impl_has_tokens {
|
||||
($($T:ty),+ $(,)?) => {
|
||||
$(
|
||||
impl HasTokens for $T {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
self.tokens.as_ref()
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
Some(&mut self.tokens)
|
||||
}
|
||||
}
|
||||
|
@ -147,10 +147,10 @@ macro_rules! impl_has_tokens_none {
|
|||
($($T:ty),+ $(,)?) => {
|
||||
$(
|
||||
impl HasTokens for $T {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
None
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -162,25 +162,25 @@ impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path,
|
|||
impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
|
||||
|
||||
impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
self.ast_deref().tokens()
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
self.ast_deref_mut().tokens_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HasTokens> HasTokens for Option<T> {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
self.as_ref().and_then(|inner| inner.tokens())
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
self.as_mut().and_then(|inner| inner.tokens_mut())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTokens for StmtKind {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
match self {
|
||||
StmtKind::Local(local) => local.tokens.as_ref(),
|
||||
StmtKind::Item(item) => item.tokens(),
|
||||
|
@ -189,7 +189,7 @@ impl HasTokens for StmtKind {
|
|||
StmtKind::MacCall(mac) => mac.tokens.as_ref(),
|
||||
}
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
match self {
|
||||
StmtKind::Local(local) => Some(&mut local.tokens),
|
||||
StmtKind::Item(item) => item.tokens_mut(),
|
||||
|
@ -201,16 +201,16 @@ impl HasTokens for StmtKind {
|
|||
}
|
||||
|
||||
impl HasTokens for Stmt {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
self.kind.tokens()
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
self.kind.tokens_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl HasTokens for Attribute {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
match &self.kind {
|
||||
AttrKind::Normal(normal) => normal.tokens.as_ref(),
|
||||
kind @ AttrKind::DocComment(..) => {
|
||||
|
@ -218,7 +218,7 @@ impl HasTokens for Attribute {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
Some(match &mut self.kind {
|
||||
AttrKind::Normal(normal) => &mut normal.tokens,
|
||||
kind @ AttrKind::DocComment(..) => {
|
||||
|
@ -229,7 +229,7 @@ impl HasTokens for Attribute {
|
|||
}
|
||||
|
||||
impl HasTokens for Nonterminal {
|
||||
fn tokens(&self) -> Option<&LazyTokenStream> {
|
||||
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
|
||||
match self {
|
||||
Nonterminal::NtItem(item) => item.tokens(),
|
||||
Nonterminal::NtStmt(stmt) => stmt.tokens(),
|
||||
|
@ -243,7 +243,7 @@ impl HasTokens for Nonterminal {
|
|||
Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None,
|
||||
}
|
||||
}
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyTokenStream>> {
|
||||
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
|
||||
match self {
|
||||
Nonterminal::NtItem(item) => item.tokens_mut(),
|
||||
Nonterminal::NtStmt(stmt) => stmt.tokens_mut(),
|
||||
|
|
|
@ -7,9 +7,8 @@ use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, Neste
|
|||
use crate::ast::{Path, PathSegment};
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Delimiter, Token};
|
||||
use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
|
||||
use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
|
||||
use crate::tokenstream::{LazyTokenStream, TokenStream};
|
||||
use crate::tokenstream::{LazyAttrTokenStream, TokenStream};
|
||||
use crate::util::comments;
|
||||
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
|
@ -296,20 +295,18 @@ impl Attribute {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn tokens(&self) -> AttrAnnotatedTokenStream {
|
||||
pub fn tokens(&self) -> TokenStream {
|
||||
match self.kind {
|
||||
AttrKind::Normal(ref normal) => normal
|
||||
.tokens
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self))
|
||||
.create_token_stream(),
|
||||
AttrKind::DocComment(comment_kind, data) => AttrAnnotatedTokenStream::from((
|
||||
AttrAnnotatedTokenTree::Token(Token::new(
|
||||
token::DocComment(comment_kind, self.style, data),
|
||||
self.span,
|
||||
)),
|
||||
.to_attr_token_stream()
|
||||
.to_tokenstream(),
|
||||
AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token(
|
||||
Token::new(token::DocComment(comment_kind, self.style, data), self.span),
|
||||
Spacing::Alone,
|
||||
)),
|
||||
)]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -356,7 +353,7 @@ pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attri
|
|||
|
||||
pub fn mk_attr_from_item(
|
||||
item: AttrItem,
|
||||
tokens: Option<LazyTokenStream>,
|
||||
tokens: Option<LazyAttrTokenStream>,
|
||||
style: AttrStyle,
|
||||
span: Span,
|
||||
) -> Attribute {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#![feature(if_let_guard)]
|
||||
#![cfg_attr(bootstrap, feature(label_break_value))]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(slice_internals)]
|
||||
|
|
|
@ -642,17 +642,17 @@ pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> Smal
|
|||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_attr_annotated_tt<T: MutVisitor>(tt: &mut AttrAnnotatedTokenTree, vis: &mut T) {
|
||||
pub fn visit_attr_tt<T: MutVisitor>(tt: &mut AttrTokenTree, vis: &mut T) {
|
||||
match tt {
|
||||
AttrAnnotatedTokenTree::Token(token) => {
|
||||
AttrTokenTree::Token(token, _) => {
|
||||
visit_token(token, vis);
|
||||
}
|
||||
AttrAnnotatedTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
|
||||
AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
|
||||
vis.visit_span(open);
|
||||
vis.visit_span(close);
|
||||
visit_attr_annotated_tts(tts, vis);
|
||||
visit_attr_tts(tts, vis);
|
||||
}
|
||||
AttrAnnotatedTokenTree::Attributes(data) => {
|
||||
AttrTokenTree::Attributes(data) => {
|
||||
for attr in &mut *data.attrs {
|
||||
match &mut attr.kind {
|
||||
AttrKind::Normal(normal) => {
|
||||
|
@ -690,27 +690,27 @@ pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn visit_attr_annotated_tts<T: MutVisitor>(
|
||||
AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream,
|
||||
vis: &mut T,
|
||||
) {
|
||||
pub fn visit_attr_tts<T: MutVisitor>(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) {
|
||||
if T::VISIT_TOKENS && !tts.is_empty() {
|
||||
let tts = Lrc::make_mut(tts);
|
||||
visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis));
|
||||
visit_vec(tts, |tree| visit_attr_tt(tree, vis));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) {
|
||||
pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(
|
||||
lazy_tts: Option<&mut LazyAttrTokenStream>,
|
||||
vis: &mut T,
|
||||
) {
|
||||
if T::VISIT_TOKENS {
|
||||
if let Some(lazy_tts) = lazy_tts {
|
||||
let mut tts = lazy_tts.create_token_stream();
|
||||
visit_attr_annotated_tts(&mut tts, vis);
|
||||
*lazy_tts = LazyTokenStream::new(tts);
|
||||
let mut tts = lazy_tts.to_attr_token_stream();
|
||||
visit_attr_tts(&mut tts, vis);
|
||||
*lazy_tts = LazyAttrTokenStream::new(tts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) {
|
||||
pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyAttrTokenStream>, vis: &mut T) {
|
||||
visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,12 +121,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub trait CreateTokenStream: sync::Send + sync::Sync {
|
||||
fn create_token_stream(&self) -> AttrAnnotatedTokenStream;
|
||||
pub trait ToAttrTokenStream: sync::Send + sync::Sync {
|
||||
fn to_attr_token_stream(&self) -> AttrTokenStream;
|
||||
}
|
||||
|
||||
impl CreateTokenStream for AttrAnnotatedTokenStream {
|
||||
fn create_token_stream(&self) -> AttrAnnotatedTokenStream {
|
||||
impl ToAttrTokenStream for AttrTokenStream {
|
||||
fn to_attr_token_stream(&self) -> AttrTokenStream {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
@ -135,68 +135,68 @@ impl CreateTokenStream for AttrAnnotatedTokenStream {
|
|||
/// of an actual `TokenStream` until it is needed.
|
||||
/// `Box` is here only to reduce the structure size.
|
||||
#[derive(Clone)]
|
||||
pub struct LazyTokenStream(Lrc<Box<dyn CreateTokenStream>>);
|
||||
pub struct LazyAttrTokenStream(Lrc<Box<dyn ToAttrTokenStream>>);
|
||||
|
||||
impl LazyTokenStream {
|
||||
pub fn new(inner: impl CreateTokenStream + 'static) -> LazyTokenStream {
|
||||
LazyTokenStream(Lrc::new(Box::new(inner)))
|
||||
impl LazyAttrTokenStream {
|
||||
pub fn new(inner: impl ToAttrTokenStream + 'static) -> LazyAttrTokenStream {
|
||||
LazyAttrTokenStream(Lrc::new(Box::new(inner)))
|
||||
}
|
||||
|
||||
pub fn create_token_stream(&self) -> AttrAnnotatedTokenStream {
|
||||
self.0.create_token_stream()
|
||||
pub fn to_attr_token_stream(&self) -> AttrTokenStream {
|
||||
self.0.to_attr_token_stream()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LazyTokenStream {
|
||||
impl fmt::Debug for LazyAttrTokenStream {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "LazyTokenStream({:?})", self.create_token_stream())
|
||||
write!(f, "LazyAttrTokenStream({:?})", self.to_attr_token_stream())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for LazyTokenStream {
|
||||
impl<S: Encoder> Encodable<S> for LazyAttrTokenStream {
|
||||
fn encode(&self, s: &mut S) {
|
||||
// Used by AST json printing.
|
||||
Encodable::encode(&self.create_token_stream(), s);
|
||||
Encodable::encode(&self.to_attr_token_stream(), s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for LazyTokenStream {
|
||||
impl<D: Decoder> Decodable<D> for LazyAttrTokenStream {
|
||||
fn decode(_d: &mut D) -> Self {
|
||||
panic!("Attempted to decode LazyTokenStream");
|
||||
panic!("Attempted to decode LazyAttrTokenStream");
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX> HashStable<CTX> for LazyTokenStream {
|
||||
impl<CTX> HashStable<CTX> for LazyAttrTokenStream {
|
||||
fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) {
|
||||
panic!("Attempted to compute stable hash for LazyTokenStream");
|
||||
panic!("Attempted to compute stable hash for LazyAttrTokenStream");
|
||||
}
|
||||
}
|
||||
|
||||
/// A `AttrAnnotatedTokenStream` is similar to a `TokenStream`, but with extra
|
||||
/// An `AttrTokenStream` is similar to a `TokenStream`, but with extra
|
||||
/// information about the tokens for attribute targets. This is used
|
||||
/// during expansion to perform early cfg-expansion, and to process attributes
|
||||
/// during proc-macro invocations.
|
||||
#[derive(Clone, Debug, Default, Encodable, Decodable)]
|
||||
pub struct AttrAnnotatedTokenStream(pub Lrc<Vec<(AttrAnnotatedTokenTree, Spacing)>>);
|
||||
pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>);
|
||||
|
||||
/// Like `TokenTree`, but for `AttrAnnotatedTokenStream`
|
||||
/// Like `TokenTree`, but for `AttrTokenStream`.
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
pub enum AttrAnnotatedTokenTree {
|
||||
Token(Token),
|
||||
Delimited(DelimSpan, Delimiter, AttrAnnotatedTokenStream),
|
||||
pub enum AttrTokenTree {
|
||||
Token(Token, Spacing),
|
||||
Delimited(DelimSpan, Delimiter, AttrTokenStream),
|
||||
/// Stores the attributes for an attribute target,
|
||||
/// along with the tokens for that attribute target.
|
||||
/// See `AttributesData` for more information
|
||||
Attributes(AttributesData),
|
||||
}
|
||||
|
||||
impl AttrAnnotatedTokenStream {
|
||||
pub fn new(tokens: Vec<(AttrAnnotatedTokenTree, Spacing)>) -> AttrAnnotatedTokenStream {
|
||||
AttrAnnotatedTokenStream(Lrc::new(tokens))
|
||||
impl AttrTokenStream {
|
||||
pub fn new(tokens: Vec<AttrTokenTree>) -> AttrTokenStream {
|
||||
AttrTokenStream(Lrc::new(tokens))
|
||||
}
|
||||
|
||||
/// Converts this `AttrAnnotatedTokenStream` to a plain `TokenStream
|
||||
/// During conversion, `AttrAnnotatedTokenTree::Attributes` get 'flattened'
|
||||
/// Converts this `AttrTokenStream` to a plain `TokenStream`.
|
||||
/// During conversion, `AttrTokenTree::Attributes` get 'flattened'
|
||||
/// back to a `TokenStream` of the form `outer_attr attr_target`.
|
||||
/// If there are inner attributes, they are inserted into the proper
|
||||
/// place in the attribute target tokens.
|
||||
|
@ -204,31 +204,27 @@ impl AttrAnnotatedTokenStream {
|
|||
let trees: Vec<_> = self
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|tree| match &tree.0 {
|
||||
AttrAnnotatedTokenTree::Token(inner) => {
|
||||
smallvec![TokenTree::Token(inner.clone(), tree.1)].into_iter()
|
||||
.flat_map(|tree| match &tree {
|
||||
AttrTokenTree::Token(inner, spacing) => {
|
||||
smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter()
|
||||
}
|
||||
AttrAnnotatedTokenTree::Delimited(span, delim, stream) => {
|
||||
AttrTokenTree::Delimited(span, delim, stream) => {
|
||||
smallvec![TokenTree::Delimited(*span, *delim, stream.to_tokenstream()),]
|
||||
.into_iter()
|
||||
}
|
||||
AttrAnnotatedTokenTree::Attributes(data) => {
|
||||
AttrTokenTree::Attributes(data) => {
|
||||
let mut outer_attrs = Vec::new();
|
||||
let mut inner_attrs = Vec::new();
|
||||
for attr in &data.attrs {
|
||||
match attr.style {
|
||||
crate::AttrStyle::Outer => {
|
||||
outer_attrs.push(attr);
|
||||
}
|
||||
crate::AttrStyle::Inner => {
|
||||
inner_attrs.push(attr);
|
||||
}
|
||||
crate::AttrStyle::Outer => outer_attrs.push(attr),
|
||||
crate::AttrStyle::Inner => inner_attrs.push(attr),
|
||||
}
|
||||
}
|
||||
|
||||
let mut target_tokens: Vec<_> = data
|
||||
.tokens
|
||||
.create_token_stream()
|
||||
.to_attr_token_stream()
|
||||
.to_tokenstream()
|
||||
.0
|
||||
.iter()
|
||||
|
@ -239,9 +235,9 @@ impl AttrAnnotatedTokenStream {
|
|||
// Check the last two trees (to account for a trailing semi)
|
||||
for tree in target_tokens.iter_mut().rev().take(2) {
|
||||
if let TokenTree::Delimited(span, delim, delim_tokens) = tree {
|
||||
// Inner attributes are only supported on extern blocks, functions, impls,
|
||||
// and modules. All of these have their inner attributes placed at
|
||||
// the beginning of the rightmost outermost braced group:
|
||||
// Inner attributes are only supported on extern blocks, functions,
|
||||
// impls, and modules. All of these have their inner attributes
|
||||
// placed at the beginning of the rightmost outermost braced group:
|
||||
// e.g. fn foo() { #![my_attr} }
|
||||
//
|
||||
// Therefore, we can insert them back into the right location
|
||||
|
@ -255,7 +251,7 @@ impl AttrAnnotatedTokenStream {
|
|||
|
||||
let mut builder = TokenStreamBuilder::new();
|
||||
for inner_attr in inner_attrs {
|
||||
builder.push(inner_attr.tokens().to_tokenstream());
|
||||
builder.push(inner_attr.tokens());
|
||||
}
|
||||
builder.push(delim_tokens.clone());
|
||||
*tree = TokenTree::Delimited(*span, *delim, builder.build());
|
||||
|
@ -273,7 +269,7 @@ impl AttrAnnotatedTokenStream {
|
|||
let mut flat: SmallVec<[_; 1]> = SmallVec::new();
|
||||
for attr in outer_attrs {
|
||||
// FIXME: Make this more efficient
|
||||
flat.extend(attr.tokens().to_tokenstream().0.clone().iter().cloned());
|
||||
flat.extend(attr.tokens().0.clone().iter().cloned());
|
||||
}
|
||||
flat.extend(target_tokens);
|
||||
flat.into_iter()
|
||||
|
@ -300,7 +296,7 @@ pub struct AttributesData {
|
|||
pub attrs: AttrVec,
|
||||
/// The underlying tokens for the attribute target that `attrs`
|
||||
/// are applied to
|
||||
pub tokens: LazyTokenStream,
|
||||
pub tokens: LazyAttrTokenStream,
|
||||
}
|
||||
|
||||
/// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s.
|
||||
|
@ -363,12 +359,6 @@ impl TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<(AttrAnnotatedTokenTree, Spacing)> for AttrAnnotatedTokenStream {
|
||||
fn from((tree, spacing): (AttrAnnotatedTokenTree, Spacing)) -> AttrAnnotatedTokenStream {
|
||||
AttrAnnotatedTokenStream::new(vec![(tree, spacing)])
|
||||
}
|
||||
}
|
||||
|
||||
impl iter::FromIterator<TokenTree> for TokenStream {
|
||||
fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self {
|
||||
TokenStream::new(iter.into_iter().collect::<Vec<TokenTree>>())
|
||||
|
@ -420,22 +410,6 @@ impl TokenStream {
|
|||
TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect()))
|
||||
}
|
||||
|
||||
fn opt_from_ast(node: &(impl HasAttrs + HasTokens)) -> Option<TokenStream> {
|
||||
let tokens = node.tokens()?;
|
||||
let attrs = node.attrs();
|
||||
let attr_annotated = if attrs.is_empty() {
|
||||
tokens.create_token_stream()
|
||||
} else {
|
||||
let attr_data =
|
||||
AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() };
|
||||
AttrAnnotatedTokenStream::new(vec![(
|
||||
AttrAnnotatedTokenTree::Attributes(attr_data),
|
||||
Spacing::Alone,
|
||||
)])
|
||||
};
|
||||
Some(attr_annotated.to_tokenstream())
|
||||
}
|
||||
|
||||
// Create a token stream containing a single token with alone spacing.
|
||||
pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream {
|
||||
TokenStream::new(vec![TokenTree::token_alone(kind, span)])
|
||||
|
@ -452,8 +426,18 @@ impl TokenStream {
|
|||
}
|
||||
|
||||
pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream {
|
||||
TokenStream::opt_from_ast(node)
|
||||
.unwrap_or_else(|| panic!("missing tokens for node at {:?}: {:?}", node.span(), node))
|
||||
let Some(tokens) = node.tokens() else {
|
||||
panic!("missing tokens for node at {:?}: {:?}", node.span(), node);
|
||||
};
|
||||
let attrs = node.attrs();
|
||||
let attr_stream = if attrs.is_empty() {
|
||||
tokens.to_attr_token_stream()
|
||||
} else {
|
||||
let attr_data =
|
||||
AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() };
|
||||
AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)])
|
||||
};
|
||||
attr_stream.to_tokenstream()
|
||||
}
|
||||
|
||||
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue