pub use UnsafeSource::*;
use crate::ptr::P;
-use crate::token::{self, CommentKind, DelimToken, Token};
+use crate::token::{self, CommentKind, Delimiter, Token, TokenKind};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
pub bounds: GenericBounds,
pub is_placeholder: bool,
pub kind: GenericParamKind,
+ pub colon_span: Option<Span>,
}
impl GenericParam {
ExprKind::Paren(..) => ExprPrecedence::Paren,
ExprKind::Try(..) => ExprPrecedence::Try,
ExprKind::Yield(..) => ExprPrecedence::Yield,
+ ExprKind::Yeet(..) => ExprPrecedence::Yeet,
ExprKind::Err => ExprPrecedence::Err,
}
}
/// A `yield`, with an optional value to be yielded.
Yield(Option<P<Expr>>),
+ /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
+ /// with an optional value to be returned.
+ Yeet(Option<P<Expr>>),
+
/// Placeholder for an expression that wasn't syntactically well formed in some way.
Err,
}
}
/// Arguments passed to an attribute or a function-like macro.
-#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Clone, Encodable, Decodable, Debug)]
pub enum MacArgs {
/// No arguments - `#[attr]`.
Empty,
Eq(
/// Span of the `=` token.
Span,
- /// "value" as a nonterminal token.
- Token,
+ /// The "value".
+ MacArgsEq,
),
}
+// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion
+// is completed, all cases end up either as a literal, which is the form used
+// after lowering to HIR, or as an error.
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub enum MacArgsEq {
+ Ast(P<Expr>),
+ Hir(Lit),
+}
+
impl MacArgs {
- pub fn delim(&self) -> Option<DelimToken> {
+ pub fn delim(&self) -> Option<Delimiter> {
match self {
MacArgs::Delimited(_, delim, _) => Some(delim.to_token()),
MacArgs::Empty | MacArgs::Eq(..) => None,
match self {
MacArgs::Empty => None,
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
- MacArgs::Eq(eq_span, token) => Some(eq_span.to(token.span)),
+ MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
+ MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
+ unreachable!("in literal form when getting span: {:?}", lit);
+ }
}
}
match self {
MacArgs::Empty => TokenStream::default(),
MacArgs::Delimited(.., tokens) => tokens.clone(),
- MacArgs::Eq(.., token) => TokenTree::Token(token.clone()).into(),
+ MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
+ // Currently only literals are allowed here. If more complex expression kinds are
+ // allowed in the future, then `nt_to_tokenstream` should be used to extract the
+ // token stream. This will require some cleverness, perhaps with a function
+ // pointer, because `nt_to_tokenstream` is not directly usable from this crate.
+ // It will also require changing the `parse_expr` call in `parse_mac_args_common`
+ // to `parse_expr_force_collect`.
+ if let ExprKind::Lit(lit) = &expr.kind {
+ let token = Token::new(TokenKind::Literal(lit.token), lit.span);
+ TokenTree::Token(token).into()
+ } else {
+ unreachable!("couldn't extract literal when getting inner tokens: {:?}", expr)
+ }
+ }
+ MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
+ unreachable!("in literal form when getting inner tokens: {:?}", lit)
+ }
}
}
}
}
+impl<CTX> HashStable<CTX> for MacArgs
+where
+ CTX: crate::HashStableContext,
+{
+ fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
+ mem::discriminant(self).hash_stable(ctx, hasher);
+ match self {
+ MacArgs::Empty => {}
+ MacArgs::Delimited(dspan, delim, tokens) => {
+ dspan.hash_stable(ctx, hasher);
+ delim.hash_stable(ctx, hasher);
+ tokens.hash_stable(ctx, hasher);
+ }
+ MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => {
+ unreachable!("hash_stable {:?}", expr);
+ }
+ MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => {
+ eq_span.hash_stable(ctx, hasher);
+ lit.hash_stable(ctx, hasher);
+ }
+ }
+ }
+}
+
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MacDelimiter {
Parenthesis,
}
impl MacDelimiter {
- pub fn to_token(self) -> DelimToken {
+ pub fn to_token(self) -> Delimiter {
match self {
- MacDelimiter::Parenthesis => DelimToken::Paren,
- MacDelimiter::Bracket => DelimToken::Bracket,
- MacDelimiter::Brace => DelimToken::Brace,
+ MacDelimiter::Parenthesis => Delimiter::Parenthesis,
+ MacDelimiter::Bracket => Delimiter::Bracket,
+ MacDelimiter::Brace => Delimiter::Brace,
}
}
- pub fn from_token(delim: DelimToken) -> Option<MacDelimiter> {
+ pub fn from_token(delim: Delimiter) -> Option<MacDelimiter> {
match delim {
- token::Paren => Some(MacDelimiter::Parenthesis),
- token::Bracket => Some(MacDelimiter::Bracket),
- token::Brace => Some(MacDelimiter::Brace),
- token::NoDelim => None,
+ Delimiter::Parenthesis => Some(MacDelimiter::Parenthesis),
+ Delimiter::Bracket => Some(MacDelimiter::Bracket),
+ Delimiter::Brace => Some(MacDelimiter::Brace),
+ Delimiter::Invisible => None,
}
}
}