[move-function] Add a new context sensitive move expr.

It doesn't do anything yet.
This commit is contained in:
Michael Gottesman
2022-08-02 16:20:43 -07:00
parent a3941bf215
commit c10c0f6285
9 changed files with 84 additions and 0 deletions

View File

@@ -2106,6 +2106,33 @@ public:
}
};
/// MoveExpr - A 'move' surrounding an lvalue expression marking the lvalue as
/// needing to be moved.
///
/// getSemanticsProvidingExpr() looks through this because it doesn't
/// provide the value and only very specific clients care where the
/// 'move' was written.
class MoveExpr final : public IdentityExpr {
SourceLoc MoveLoc;
public:
MoveExpr(SourceLoc moveLoc, Expr *sub, Type type = Type(),
bool implicit = false)
: IdentityExpr(ExprKind::Move, sub, type, implicit), MoveLoc(moveLoc) {}
static MoveExpr *createImplicit(ASTContext &ctx, SourceLoc moveLoc, Expr *sub,
Type type = Type()) {
return new (ctx) MoveExpr(moveLoc, sub, type, /*implicit=*/true);
}
SourceLoc getLoc() const { return MoveLoc; }
SourceLoc getStartLoc() const { return MoveLoc; }
SourceLoc getEndLoc() const { return getSubExpr()->getEndLoc(); }
static bool classof(const Expr *e) { return e->getKind() == ExprKind::Move; }
};
/// TupleExpr - Parenthesized expressions like '(a: x+x)' and '(x, y, 4)'. Note
/// that expressions like '(4)' are represented with a ParenExpr.
class TupleExpr final : public Expr,

View File

@@ -107,6 +107,7 @@ ABSTRACT_EXPR(Identity, Expr)
EXPR(Paren, IdentityExpr)
EXPR(DotSelf, IdentityExpr)
EXPR(Await, IdentityExpr)
EXPR(Move, IdentityExpr)
EXPR(UnresolvedMemberChainResult, IdentityExpr)
EXPR_RANGE(Identity, Paren, UnresolvedMemberChainResult)
ABSTRACT_EXPR(AnyTry, Expr)

View File

@@ -2076,6 +2076,12 @@ public:
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitMoveExpr(MoveExpr *E) {
printCommon(E, "move_expr");
OS << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitUnresolvedMemberChainResultExpr(UnresolvedMemberChainResultExpr *E){
printCommon(E, "unresolved_member_chain_expr");
OS << '\n';

View File

@@ -4526,6 +4526,11 @@ void PrintAST::visitAwaitExpr(AwaitExpr *expr) {
visit(expr->getSubExpr());
}
void PrintAST::visitMoveExpr(MoveExpr *expr) {
Printer << "move ";
visit(expr->getSubExpr());
}
void PrintAST::visitInOutExpr(InOutExpr *expr) {
visit(expr->getSubExpr());
}

View File

@@ -365,6 +365,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
PASS_THROUGH_REFERENCE(UnresolvedMemberChainResult, getSubExpr);
PASS_THROUGH_REFERENCE(DotSelf, getSubExpr);
PASS_THROUGH_REFERENCE(Await, getSubExpr);
PASS_THROUGH_REFERENCE(Move, getSubExpr);
PASS_THROUGH_REFERENCE(Try, getSubExpr);
PASS_THROUGH_REFERENCE(ForceTry, getSubExpr);
PASS_THROUGH_REFERENCE(OptionalTry, getSubExpr);
@@ -703,6 +704,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
return true;
case ExprKind::Await:
case ExprKind::Move:
case ExprKind::Try:
case ExprKind::ForceTry:
case ExprKind::OptionalTry:
@@ -881,6 +883,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
case ExprKind::Sequence:
case ExprKind::Paren:
case ExprKind::Await:
case ExprKind::Move:
case ExprKind::UnresolvedMemberChainResult:
case ExprKind::Try:
case ExprKind::ForceTry:

View File

@@ -393,6 +393,7 @@ done:
/// 'try' expr-sequence-element(Mode)
/// 'try' '?' expr-sequence-element(Mode)
/// 'try' '!' expr-sequence-element(Mode)
/// '_move' expr-sequence-element(Mode)
/// expr-unary(Mode)
///
/// 'try' is not actually allowed at an arbitrary position of a
@@ -432,6 +433,19 @@ ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
return sub;
}
if (Tok.isContextualKeyword("_move")) {
Tok.setKind(tok::contextual_keyword);
SourceLoc awaitLoc = consumeToken();
ParserResult<Expr> sub =
parseExprSequenceElement(diag::expected_expr_after_await, isExprBasic);
if (!sub.hasCodeCompletion() && !sub.isNull()) {
ElementContext.setCreateSyntax(SyntaxKind::MoveExpr);
sub = makeParserResult(new (Context) MoveExpr(awaitLoc, sub.get()));
}
return sub;
}
SourceLoc tryLoc;
bool hadTry = consumeIf(tok::kw_try, tryLoc);
Optional<Token> trySuffix;

View File

@@ -0,0 +1,19 @@
// RUN: %target-typecheck-verify-swift -disable-availability-checking
var global: Int = 5
func testGlobal() {
let _ = _move global
}
func testLet() {
let t = String()
let _ = _move t
}
func testVar() {
var t = String()
t = String()
let _ = _move t
}

View File

@@ -54,6 +54,14 @@ EXPR_NODES = [
Child('Expression', kind='Expr'),
]),
# The move expr
Node('MoveExpr', kind='Expr',
children=[
Child('MoveKeyword', kind='ContextualKeywordToken',
text_choices=['_move']),
Child('Expression', kind='Expr'),
]),
# declname-arguments -> '(' declname-argument-list ')'
# declname-argument-list -> declname-argument*
# declname-argument -> identifier ':'

View File

@@ -31,6 +31,7 @@ SYNTAX_NODE_SERIALIZATION_CODES = {
'PoundColumnExpr': 26,
'TryExpr': 27,
'AwaitExpr': 249,
'MoveExpr': 267,
'IdentifierExpr': 28,
'SuperRefExpr': 29,
'NilLiteralExpr': 30,