Skip to content

Commit 1c0916a

Browse files
committed
Preserve yield position during pretty printing
1 parent edf65e7 commit 1c0916a

File tree

12 files changed

+55
-18
lines changed

12 files changed

+55
-18
lines changed

compiler/rustc_ast/src/ast.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ pub enum ExprKind {
16571657
Try(P<Expr>),
16581658

16591659
/// A `yield`, with an optional value to be yielded.
1660-
Yield(Option<P<Expr>>),
1660+
Yield(Option<P<Expr>>, YieldKind),
16611661

16621662
/// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
16631663
/// with an optional value to be returned.
@@ -1903,6 +1903,15 @@ pub enum MatchKind {
19031903
Postfix,
19041904
}
19051905

1906+
/// The kind of yield expression
1907+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
1908+
pub enum YieldKind {
1909+
/// yield expr { ... }
1910+
Prefix,
1911+
/// expr.yield { ... }
1912+
Postfix,
1913+
}
1914+
19061915
/// A literal in a meta item.
19071916
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
19081917
pub struct MetaItemLit {

compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
18131813
ExprKind::Paren(expr) => {
18141814
vis.visit_expr(expr);
18151815
}
1816-
ExprKind::Yield(expr) => {
1816+
ExprKind::Yield(expr, _) => {
18171817
visit_opt(expr, |expr| vis.visit_expr(expr));
18181818
}
18191819
ExprKind::Try(expr) => vis.visit_expr(expr),

compiler/rustc_ast/src/util/classify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
182182
| Range(_, Some(e), _)
183183
| Ret(Some(e))
184184
| Unary(_, e)
185-
| Yield(Some(e))
185+
| Yield(Some(e), _)
186186
| Yeet(Some(e))
187187
| Become(e) => {
188188
expr = e;
@@ -217,7 +217,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
217217
Break(_, None)
218218
| Range(_, None, _)
219219
| Ret(None)
220-
| Yield(None)
220+
| Yield(None, _)
221221
| Array(_)
222222
| Call(_, _)
223223
| MethodCall(_)

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
12691269
try_visit!(visitor.visit_ty(container));
12701270
walk_list!(visitor, visit_ident, fields.iter());
12711271
}
1272-
ExprKind::Yield(optional_expression) => {
1272+
ExprKind::Yield(optional_expression, _) => {
12731273
visit_opt!(visitor, visit_expr, optional_expression);
12741274
}
12751275
ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),

compiler/rustc_ast_lowering/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
351351
rest,
352352
)
353353
}
354-
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
354+
ExprKind::Yield(opt_expr, _) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
355355
ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
356356

357357
ExprKind::UnsafeBinderCast(kind, expr, ty) => hir::ExprKind::UnsafeBinderCast(

compiler/rustc_ast_lowering/src/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool {
642642
type Result = ControlFlow<()>;
643643

644644
fn visit_expr(&mut self, e: &ast::Expr) -> ControlFlow<()> {
645-
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_) = e.kind {
645+
if let ast::ExprKind::Await(_, _) | ast::ExprKind::Yield(_, _) = e.kind {
646646
ControlFlow::Break(())
647647
} else {
648648
visit::walk_expr(self, e)

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
88
use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
99
use rustc_ast::{
1010
self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
11-
FormatDebugHex, FormatSign, FormatTrait, token,
11+
FormatDebugHex, FormatSign, FormatTrait, YieldKind, token,
1212
};
1313

1414
use crate::pp::Breaks::Inconsistent;
@@ -761,7 +761,7 @@ impl<'a> State<'a> {
761761
self.print_expr(e, FixupContext::default());
762762
self.pclose();
763763
}
764-
ast::ExprKind::Yield(e) => {
764+
ast::ExprKind::Yield(e, YieldKind::Prefix) => {
765765
self.word("yield");
766766

767767
if let Some(expr) = e {
@@ -773,6 +773,16 @@ impl<'a> State<'a> {
773773
);
774774
}
775775
}
776+
ast::ExprKind::Yield(e, YieldKind::Postfix) => {
777+
// it's not possible to have a postfix yield with no expression.
778+
let e = e.as_ref().unwrap();
779+
self.print_expr_cond_paren(
780+
e,
781+
e.precedence() < ExprPrecedence::Unambiguous,
782+
fixup.leftmost_subexpression_with_dot(),
783+
);
784+
self.word(".yield");
785+
}
776786
ast::ExprKind::Try(e) => {
777787
self.print_expr_cond_paren(
778788
e,

compiler/rustc_builtin_macros/src/assert/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
323323
| ExprKind::While(_, _, _)
324324
| ExprKind::Yeet(_)
325325
| ExprKind::Become(_)
326-
| ExprKind::Yield(_)
326+
| ExprKind::Yield(_, _)
327327
| ExprKind::UnsafeBinderCast(..) => {}
328328
}
329329
}

compiler/rustc_parse/src/parser/expr.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_ast::{
1717
self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy,
1818
ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, FnRetTy, Label, MacCall,
1919
MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind,
20+
YieldKind,
2021
};
2122
use rustc_ast_pretty::pprust;
2223
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -1314,7 +1315,9 @@ impl<'a> Parser<'a> {
13141315
if self.eat_keyword(exp!(Yield)) {
13151316
let yield_span = self.prev_token.span;
13161317
self.psess.gated_spans.gate(sym::yield_expr, yield_span);
1317-
return Ok(self.mk_expr(yield_span, ExprKind::Yield(Some(self_arg))));
1318+
return Ok(
1319+
self.mk_expr(yield_span, ExprKind::Yield(Some(self_arg), YieldKind::Postfix))
1320+
);
13181321
}
13191322

13201323
let fn_span_lo = self.token.span;
@@ -1891,7 +1894,7 @@ impl<'a> Parser<'a> {
18911894
/// Parse `"yield" expr?`.
18921895
fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> {
18931896
let lo = self.prev_token.span;
1894-
let kind = ExprKind::Yield(self.parse_expr_opt()?);
1897+
let kind = ExprKind::Yield(self.parse_expr_opt()?, YieldKind::Prefix);
18951898
let span = lo.to(self.prev_token.span);
18961899
self.psess.gated_spans.gate(sym::yield_expr, span);
18971900
let expr = self.mk_expr(span, kind);
@@ -4045,7 +4048,7 @@ impl MutVisitor for CondChecker<'_> {
40454048
| ExprKind::MacCall(_)
40464049
| ExprKind::Struct(_)
40474050
| ExprKind::Repeat(_, _)
4048-
| ExprKind::Yield(_)
4051+
| ExprKind::Yield(_, _)
40494052
| ExprKind::Yeet(_)
40504053
| ExprKind::Become(_)
40514054
| ExprKind::IncludedBytes(_)

src/tools/rustfmt/src/utils.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
485485
| ast::ExprKind::Index(_, ref expr, _)
486486
| ast::ExprKind::Unary(_, ref expr)
487487
| ast::ExprKind::Try(ref expr)
488-
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
488+
| ast::ExprKind::Yield(Some(ref expr), _) => is_block_expr(context, expr, repr),
489489
ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr),
490490
// This can only be a string lit
491491
ast::ExprKind::Lit(_) => {
@@ -515,7 +515,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
515515
| ast::ExprKind::Tup(..)
516516
| ast::ExprKind::Use(..)
517517
| ast::ExprKind::Type(..)
518-
| ast::ExprKind::Yield(None)
518+
| ast::ExprKind::Yield(None, _)
519519
| ast::ExprKind::Underscore => false,
520520
}
521521
}

tests/pretty/postfix-yield.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// This demonstrates a proposed alternate or additional option of having yield in postfix position.
2+
//@ edition: 2024
3+
//@ pp-exact
4+
5+
#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
6+
7+
use std::ops::{Coroutine, CoroutineState};
8+
use std::pin::pin;
9+
10+
fn main() {
11+
let mut gn = gen { yield 1; 2.yield; (1 + 2).yield; };
12+
13+
let mut coro =
14+
pin!(#[coroutine] |_: i32| { let x = 1.yield; (x + 2).yield; });
15+
}

tests/ui/coroutine/postfix-yield.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::ops::{Coroutine, CoroutineState};
99
use std::pin::pin;
1010

1111
fn main() {
12-
// generators (i.e. yield doesn't return anything useful)
12+
// generators (i.e. yield doesn't return anything useful)
1313
let mut gn = gen {
1414
yield 1;
1515
2.yield;
@@ -23,8 +23,8 @@ fn main() {
2323
let mut coro = pin!(
2424
#[coroutine]
2525
|_: i32| {
26-
let x = yield 1;
27-
yield x + 2;
26+
let x = 1.yield;
27+
(x + 2).yield;
2828
}
2929
);
3030

0 commit comments

Comments
 (0)