]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_ast/src/ast.rs
Rollup merge of #96660 - jyn514:better-missing-path-error, r=Mark-Simulacrum
[rust.git] / compiler / rustc_ast / src / ast.rs
index cdcd221e811a77c2f21888b6eccd617897b94f2f..09a8954a9a7b6401a053dfc29b5883570d075c33 100644 (file)
@@ -23,7 +23,7 @@
 pub use UnsafeSource::*;
 
 use crate::ptr::P;
-use crate::token::{self, CommentKind, Delimiter, Token};
+use crate::token::{self, CommentKind, Delimiter, Token, TokenKind};
 use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -1275,6 +1275,7 @@ pub fn precedence(&self) -> ExprPrecedence {
             ExprKind::Paren(..) => ExprPrecedence::Paren,
             ExprKind::Try(..) => ExprPrecedence::Try,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
+            ExprKind::Yeet(..) => ExprPrecedence::Yeet,
             ExprKind::Err => ExprPrecedence::Err,
         }
     }
@@ -1462,6 +1463,10 @@ pub enum ExprKind {
     /// 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,
 }
@@ -1527,7 +1532,7 @@ pub fn span(&self) -> Span {
 }
 
 /// 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,
@@ -1537,11 +1542,20 @@ pub enum MacArgs {
     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<Delimiter> {
         match self {
@@ -1554,7 +1568,10 @@ pub fn span(&self) -> Option<Span> {
         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);
+            }
         }
     }
 
@@ -1564,7 +1581,23 @@ pub fn inner_tokens(&self) -> TokenStream {
         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)
+            }
         }
     }
 
@@ -1575,6 +1608,30 @@ pub fn need_semicolon(&self) -> bool {
     }
 }
 
+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,