Skip to content

Commit 19f37dd

Browse files
committed
[move-function] Add a new context sensitive move expr.
It doesn't do anything yet.
1 parent ff21023 commit 19f37dd

File tree

9 files changed

+84
-0
lines changed

9 files changed

+84
-0
lines changed

include/swift/AST/Expr.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,33 @@ class AwaitExpr final : public IdentityExpr {
21062106
}
21072107
};
21082108

2109+
/// MoveExpr - A 'move' surrounding an lvalue expression marking the lvalue as
2110+
/// needing to be moved.
2111+
///
2112+
/// getSemanticsProvidingExpr() looks through this because it doesn't
2113+
/// provide the value and only very specific clients care where the
2114+
/// 'move' was written.
2115+
class MoveExpr final : public IdentityExpr {
2116+
SourceLoc MoveLoc;
2117+
2118+
public:
2119+
MoveExpr(SourceLoc moveLoc, Expr *sub, Type type = Type(),
2120+
bool implicit = false)
2121+
: IdentityExpr(ExprKind::Move, sub, type, implicit), MoveLoc(moveLoc) {}
2122+
2123+
static MoveExpr *createImplicit(ASTContext &ctx, SourceLoc moveLoc, Expr *sub,
2124+
Type type = Type()) {
2125+
return new (ctx) MoveExpr(moveLoc, sub, type, /*implicit=*/true);
2126+
}
2127+
2128+
SourceLoc getLoc() const { return MoveLoc; }
2129+
2130+
SourceLoc getStartLoc() const { return MoveLoc; }
2131+
SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }
2132+
2133+
static bool classof(const Expr *e) { return e->getKind() == ExprKind::Move; }
2134+
};
2135+
21092136
/// TupleExpr - Parenthesized expressions like '(a: x+x)' and '(x, y, 4)'. Note
21102137
/// that expressions like '(4)' are represented with a ParenExpr.
21112138
class TupleExpr final : public Expr,

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ ABSTRACT_EXPR(Identity, Expr)
107107
EXPR(Paren, IdentityExpr)
108108
EXPR(DotSelf, IdentityExpr)
109109
EXPR(Await, IdentityExpr)
110+
EXPR(Move, IdentityExpr)
110111
EXPR(UnresolvedMemberChainResult, IdentityExpr)
111112
EXPR_RANGE(Identity, Paren, UnresolvedMemberChainResult)
112113
ABSTRACT_EXPR(AnyTry, Expr)

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,6 +2076,12 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
20762076
printRec(E->getSubExpr());
20772077
PrintWithColorRAII(OS, ParenthesisColor) << ')';
20782078
}
2079+
void visitMoveExpr(MoveExpr *E) {
2080+
printCommon(E, "move_expr");
2081+
OS << '\n';
2082+
printRec(E->getSubExpr());
2083+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2084+
}
20792085
void visitUnresolvedMemberChainResultExpr(UnresolvedMemberChainResultExpr *E){
20802086
printCommon(E, "unresolved_member_chain_expr");
20812087
OS << '\n';

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,6 +4525,11 @@ void PrintAST::visitAwaitExpr(AwaitExpr *expr) {
45254525
visit(expr->getSubExpr());
45264526
}
45274527

4528+
void PrintAST::visitMoveExpr(MoveExpr *expr) {
4529+
Printer << "move ";
4530+
visit(expr->getSubExpr());
4531+
}
4532+
45284533
void PrintAST::visitInOutExpr(InOutExpr *expr) {
45294534
visit(expr->getSubExpr());
45304535
}

lib/AST/Expr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
365365
PASS_THROUGH_REFERENCE(UnresolvedMemberChainResult, getSubExpr);
366366
PASS_THROUGH_REFERENCE(DotSelf, getSubExpr);
367367
PASS_THROUGH_REFERENCE(Await, getSubExpr);
368+
PASS_THROUGH_REFERENCE(Move, getSubExpr);
368369
PASS_THROUGH_REFERENCE(Try, getSubExpr);
369370
PASS_THROUGH_REFERENCE(ForceTry, getSubExpr);
370371
PASS_THROUGH_REFERENCE(OptionalTry, getSubExpr);
@@ -703,6 +704,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
703704
return true;
704705

705706
case ExprKind::Await:
707+
case ExprKind::Move:
706708
case ExprKind::Try:
707709
case ExprKind::ForceTry:
708710
case ExprKind::OptionalTry:
@@ -881,6 +883,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
881883
case ExprKind::Sequence:
882884
case ExprKind::Paren:
883885
case ExprKind::Await:
886+
case ExprKind::Move:
884887
case ExprKind::UnresolvedMemberChainResult:
885888
case ExprKind::Try:
886889
case ExprKind::ForceTry:

lib/Parse/ParseExpr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
393393
/// 'try' expr-sequence-element(Mode)
394394
/// 'try' '?' expr-sequence-element(Mode)
395395
/// 'try' '!' expr-sequence-element(Mode)
396+
/// '_move' expr-sequence-element(Mode)
396397
/// expr-unary(Mode)
397398
///
398399
/// 'try' is not actually allowed at an arbitrary position of a
@@ -432,6 +433,19 @@ ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
432433
return sub;
433434
}
434435

436+
if (Tok.isContextualKeyword("_move")) {
437+
Tok.setKind(tok::contextual_keyword);
438+
SourceLoc awaitLoc = consumeToken();
439+
ParserResult<Expr> sub =
440+
parseExprSequenceElement(diag::expected_expr_after_await, isExprBasic);
441+
if (!sub.hasCodeCompletion() && !sub.isNull()) {
442+
ElementContext.setCreateSyntax(SyntaxKind::MoveExpr);
443+
sub = makeParserResult(new (Context) MoveExpr(awaitLoc, sub.get()));
444+
}
445+
446+
return sub;
447+
}
448+
435449
SourceLoc tryLoc;
436450
bool hadTry = consumeIf(tok::kw_try, tryLoc);
437451
Optional<Token> trySuffix;

test/Parse/move_expr.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking
2+
3+
var global: Int = 5
4+
func testGlobal() {
5+
let _ = _move global
6+
}
7+
8+
func testLet() {
9+
let t = String()
10+
let _ = _move t
11+
}
12+
13+
func testVar() {
14+
var t = String()
15+
t = String()
16+
let _ = _move t
17+
}
18+
19+

utils/gyb_syntax_support/ExprNodes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@
5454
Child('Expression', kind='Expr'),
5555
]),
5656

57+
# The move expr
58+
Node('MoveExpr', kind='Expr',
59+
children=[
60+
Child('MoveKeyword', kind='ContextualKeywordToken',
61+
text_choices=['_move']),
62+
Child('Expression', kind='Expr'),
63+
]),
64+
5765
# declname-arguments -> '(' declname-argument-list ')'
5866
# declname-argument-list -> declname-argument*
5967
# declname-argument -> identifier ':'

utils/gyb_syntax_support/NodeSerializationCodes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
'PoundColumnExpr': 26,
3232
'TryExpr': 27,
3333
'AwaitExpr': 249,
34+
'MoveExpr': 267,
3435
'IdentifierExpr': 28,
3536
'SuperRefExpr': 29,
3637
'NilLiteralExpr': 30,

0 commit comments

Comments
 (0)