about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2023-12-27 18:45:58 -0800
committerDavid Tolnay <dtolnay@gmail.com>2024-05-11 15:48:57 -0700
commitb431eec6f28d64cd3852584f9a59736c6c09ee68 (patch)
tree93188bc52a476e15f8671c0a5c7208862cd4805e
parent78a77512702ab786f6f9345872d36d852454612c (diff)
downloadrust-b431eec6f28d64cd3852584f9a59736c6c09ee68.tar.gz
rust-b431eec6f28d64cd3852584f9a59736c6c09ee68.zip
Expand on expr_requires_semi_to_be_stmt documentation
-rw-r--r--compiler/rustc_ast/src/util/classify.rs51
1 files changed, 41 insertions, 10 deletions
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index f21a9cabb81..7f9775a8e0c 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -1,16 +1,47 @@
-//! Routines the parser uses to classify AST nodes
-
-// Predicates on exprs and stmts that the pretty-printer and parser use
+//! Routines the parser and pretty-printer use to classify AST nodes.
 
 use crate::{ast, token::Delimiter};
 
-/// Does this expression require a semicolon to be treated
-/// as a statement? The negation of this: 'can this expression
-/// be used as a statement without a semicolon' -- is used
-/// as an early-bail-out in the parser so that, for instance,
-///     if true {...} else {...}
-///      |x| 5
-/// isn't parsed as (if true {...} else {...} | x) | 5
+/// Does this expression require a semicolon to be treated as a statement?
+///
+/// The negation of this: "can this expression be used as a statement without a
+/// semicolon" -- is used as an early bail-out in the parser so that, for
+/// instance,
+///
+/// ```ignore (illustrative)
+/// if true {...} else {...}
+/// |x| 5
+/// ```
+///
+/// isn't parsed as `(if true {...} else {...} | x) | 5`.
+///
+/// Nearly the same early bail-out also occurs in the right-hand side of match
+/// arms:
+///
+/// ```ignore (illustrative)
+/// match i {
+///     0 => if true {...} else {...}
+///     | x => {}
+/// }
+/// ```
+///
+/// Here the `|` is a leading vert in a second match arm. It is not a binary
+/// operator with the If as its left operand. If the first arm were some other
+/// expression for which `expr_requires_semi_to_be_stmt` returns true, then the
+/// `|` on the next line would be a binary operator (leading to a parse error).
+///
+/// The statement case and the match-arm case are "nearly" the same early
+/// bail-out because of 1 edge case. Macro calls with brace delimiter terminate
+/// a statement without a semicolon, but do not terminate a match-arm without
+/// comma.
+///
+/// ```ignore (illustrative)
+/// m! {} - 1;  // two statements: a macro call followed by -1 literal
+///
+/// match () {
+///     _ => m! {} - 1,  // binary subtraction operator
+/// }
+/// ```
 pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
     !matches!(
         e.kind,