Skip to content

Implement consume x operator with the accepted SE-0366 syntax. #64019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1360,10 +1360,13 @@ ERROR(expected_expr_after_try, none,
ERROR(expected_expr_after_await, none,
"expected expression after 'await'", ())
ERROR(expected_expr_after_move, none,
"expected expression after '_move'", ())
"expected expression after 'consume'", ())
ERROR(expected_expr_after_borrow, none,
"expected expression after '_borrow'", ())

WARNING(move_consume_final_spelling, none,
"'_move' has been renamed to 'consume', and the '_move' spelling will be removed shortly", ())

// Cast expressions
ERROR(expected_type_after_is,none,
"expected type after 'is'", ())
Expand Down
8 changes: 4 additions & 4 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -796,15 +796,15 @@ ERROR(sil_moveonlychecker_missed_copy, none,

// move kills copyable values checker diagnostics
ERROR(sil_movekillscopyablevalue_value_consumed_more_than_once, none,
"'%0' used after being moved", (StringRef))
"'%0' used after being consumed", (StringRef))
NOTE(sil_movekillscopyablevalue_move_here, none,
"move here", ())
"consume here", ())
NOTE(sil_movekillscopyablevalue_use_here, none,
"use here", ())
NOTE(sil_movekillscopyablevalue_value_consumed_in_loop, none,
"cyclic move here. move will occur multiple times in the loop", ())
"consume here would occur multiple times in loop", ())
ERROR(sil_movekillscopyablevalue_move_applied_to_unsupported_move, none,
"_move applied to value that the compiler does not support checking",
"'consume' applied to value that the compiler does not support checking",
())

#define UNDEFINE_DIAGNOSTIC_MACROS
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -6805,7 +6805,7 @@ ERROR(concurrency_task_to_thread_model_global_actor_annotation,none,
ERROR(moveOnly_not_allowed_here,none,
"'moveOnly' only applies to structs or enums", ())
ERROR(move_expression_not_passed_lvalue,none,
"'move' can only be applied to lvalues", ())
"'consume' can only be applied to lvalues", ())
ERROR(borrow_expression_not_passed_lvalue,none,
"'borrow' can only be applied to lvalues", ())

Expand Down
3 changes: 2 additions & 1 deletion include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@ class Parser {
return false;

// followed by either an identifier, `self`, or `Self`.
return peekToken().isAny(tok::identifier, tok::kw_self, tok::kw_Self);
return !peekToken().isAtStartOfLine()
&& peekToken().isAny(tok::identifier, tok::kw_self, tok::kw_Self);
}

/// Read tokens until we get to one of the specified tokens, then
Expand Down
17 changes: 17 additions & 0 deletions lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,27 @@ ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
return sub;
}

if (Tok.isContextualKeyword("consume")
&& peekToken().isAny(tok::identifier, tok::kw_self)
&& !peekToken().isAtStartOfLine()) {
Tok.setKind(tok::contextual_keyword);

SourceLoc consumeLoc = consumeToken();
ParserResult<Expr> sub =
parseExprSequenceElement(diag::expected_expr_after_move, isExprBasic);
if (!sub.hasCodeCompletion() && !sub.isNull()) {
sub = makeParserResult(new (Context) MoveExpr(consumeLoc, sub.get()));
}
return sub;
}

if (Context.LangOpts.hasFeature(Feature::MoveOnly)) {
if (Tok.isContextualKeyword("_move")) {
Tok.setKind(tok::contextual_keyword);
SourceLoc awaitLoc = consumeToken();
diagnose(Tok, diag::move_consume_final_spelling)
.fixItReplace(awaitLoc, "consume");

ParserResult<Expr> sub =
parseExprSequenceElement(diag::expected_expr_after_move, isExprBasic);
if (!sub.hasCodeCompletion() && !sub.isNull()) {
Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/moveonly_constraints.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func testBasic(_ mo: __shared MO) {
func checkBasicBoxes() {
let mo = MO()

let vb = ValBox(_move mo) // expected-error 2{{move-only type 'MO' cannot be used with generics yet}}
let vb = ValBox(consume mo) // expected-error 2{{move-only type 'MO' cannot be used with generics yet}}
_ = vb.get()
_ = vb.val

Expand Down
36 changes: 18 additions & 18 deletions test/DebugInfo/move_function_dbginfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public var falseValue: Bool { false }
public func copyableValueTest() {
let k = Klass()
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
}

Expand Down Expand Up @@ -126,7 +126,7 @@ public func copyableValueTest() {
// DWARF-NEXT: DW_AT_type (
public func copyableArgTest(_ k: __owned Klass) {
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
}

Expand Down Expand Up @@ -168,7 +168,7 @@ public func copyableArgTest(_ k: __owned Klass) {
public func copyableVarTest() {
var k = Klass()
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
k = Klass()
k.doSomething()
Expand Down Expand Up @@ -211,7 +211,7 @@ public func copyableVarTest() {
// DWARF-NEXT: DW_AT_type (
public func copyableVarArgTest(_ k: inout Klass) {
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
k = Klass()
k.doSomething()
Expand Down Expand Up @@ -261,7 +261,7 @@ public func copyableVarArgTest(_ k: inout Klass) {
public func addressOnlyValueTest<T : P>(_ x: T) {
let k = x
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
}

Expand Down Expand Up @@ -303,7 +303,7 @@ public func addressOnlyValueTest<T : P>(_ x: T) {
// DWARF-NEXT: DW_AT_type (
public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
}

Expand Down Expand Up @@ -348,7 +348,7 @@ public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
public func addressOnlyVarTest<T : P>(_ x: T) {
var k = x
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
k = x
k.doSomething()
Expand Down Expand Up @@ -393,7 +393,7 @@ public func addressOnlyVarTest<T : P>(_ x: T) {
// DWARF-NEXT: DW_AT_artificial (true)
public func addressOnlyVarArgTest<T : P>(_ k: inout T, _ x: T) {
k.doSomething()
let m = _move k
let m = consume k
m.doSomething()
k = x
k.doSomething()
Expand All @@ -416,7 +416,7 @@ public func copyableValueCCFlowTest() {
let k = Klass()
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
}
Expand All @@ -433,7 +433,7 @@ public func copyableValueCCFlowTest() {
public func copyableValueArgCCFlowTest(_ k: __owned Klass) {
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
}
Expand Down Expand Up @@ -463,7 +463,7 @@ public func copyableVarTestCCFlowReinitOutOfBlockTest() {
var k = Klass()
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
k = Klass()
Expand Down Expand Up @@ -493,7 +493,7 @@ public func copyableVarTestCCFlowReinitOutOfBlockTest() {
public func copyableVarArgTestCCFlowReinitOutOfBlockTest(_ k: inout Klass) {
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
k = Klass()
Expand Down Expand Up @@ -528,7 +528,7 @@ public func copyableVarTestCCFlowReinitInBlockTest() {
var k = Klass()
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
k = Klass()
}
Expand Down Expand Up @@ -562,7 +562,7 @@ public func copyableVarTestCCFlowReinitInBlockTest() {
public func copyableVarArgTestCCFlowReinitInBlockTest(_ k: inout Klass) {
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
k = Klass()
}
Expand Down Expand Up @@ -594,7 +594,7 @@ public func addressOnlyVarTestCCFlowReinitOutOfBlockTest<T : P>(_ x: T.Type) {
var k = T.value
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
k = T.value
Expand Down Expand Up @@ -625,7 +625,7 @@ public func addressOnlyVarTestCCFlowReinitOutOfBlockTest<T : P>(_ x: T.Type) {
public func addressOnlyVarArgTestCCFlowReinitOutOfBlockTest<T : P>(_ k: inout (any P), _ x: T.Type) {
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
}
k = T.value
Expand Down Expand Up @@ -659,7 +659,7 @@ public func addressOnlyVarTestCCFlowReinitInBlockTest<T : P>(_ x: T.Type) {
var k = T.value
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
k = T.value
}
Expand Down Expand Up @@ -692,7 +692,7 @@ public func addressOnlyVarTestCCFlowReinitInBlockTest<T : P>(_ x: T.Type) {
public func addressOnlyVarArgTestCCFlowReinitInBlockTest<T : P>(_ k: inout (any P), _ x: T.Type) {
k.doSomething()
if trueValue {
let m = _move k
let m = consume k
m.doSomething()
k = T.value
}
Expand Down
16 changes: 8 additions & 8 deletions test/DebugInfo/move_function_dbginfo_async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public func forceSplit5() async {}
// DWARF-NEXT: DW_AT_name ("msg")
public func letSimpleTest<T>(_ msg: __owned T) async {
await forceSplit()
use(_move msg)
use(consume msg)
}

// CHECK-LABEL: define swifttailcc void @"$s27move_function_dbginfo_async13varSimpleTestyyxz_xtYalF"(%swift.context* swiftasync %0, %swift.opaque* %1, %swift.opaque* noalias %2, %swift.type* %T)
Expand Down Expand Up @@ -146,7 +146,7 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
// DWARF: DW_TAG_formal_parameter
// DWARF-NEXT: DW_AT_name ("msg")
//
// We reinitialize our value in this funclet and then _move it and then
// We reinitialize our value in this funclet and then consume it and then
// reinitialize it again. So we have two different live ranges. Sadly, we don't
// validate that the first live range doesn't start at the beginning of the
// function. But we have lldb tests to validate that.
Expand All @@ -161,7 +161,7 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
// DWARF-SAME: DW_OP_entry_value([[ASYNC_REG]]), DW_OP_plus_uconst 0x[[MSG_LOC]], DW_OP_plus_uconst 0x8, DW_OP_deref
// DWARF-NEXT: DW_AT_name ("msg")
//
// We did not _move the value again here, so we just get a normal entry value for
// We did not consume the value again here, so we just get a normal entry value for
// the entire function.
//
// DWARF: DW_AT_linkage_name ("$s3out13varSimpleTestyyxz_xtYalFTQ4_")
Expand All @@ -179,10 +179,10 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
// Change name to varSimpleTestArg
public func varSimpleTest<T>(_ msg: inout T, _ msg2: T) async {
await forceSplit()
use(_move msg)
use(consume msg)
await forceSplit()
msg = msg2
let msg3 = _move msg
let msg3 = consume msg
let _ = msg3
msg = msg2
await forceSplit()
Expand Down Expand Up @@ -277,7 +277,7 @@ public func varSimpleTestVar() async {
var k = Klass()
k.doSomething()
await forceSplit()
let m = _move k
let m = consume k
m.doSomething()
await forceSplit()
k = Klass()
Expand Down Expand Up @@ -383,7 +383,7 @@ public func varSimpleTestVar() async {
public func letArgCCFlowTrueTest<T>(_ msg: __owned T) async {
await forceSplit1()
if trueValue {
use(_move msg)
use(consume msg)
await forceSplit2()
} else {
await forceSplit3()
Expand Down Expand Up @@ -534,7 +534,7 @@ public func letArgCCFlowTrueTest<T>(_ msg: __owned T) async {
public func varArgCCFlowTrueTest<T : P>(_ msg: inout T) async {
await forceSplit1()
if trueValue {
use(_move msg)
use(consume msg)
await forceSplit2()
} else {
await forceSplit3()
Expand Down
4 changes: 2 additions & 2 deletions test/Interpreter/moveonly_bufferview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension Array {
}

func testBufferView(_ x: __owned [Int]) {
var y = _move x
var y = consume x
// CHECK: 1
// CHECK: 2
// CHECK: 3
Expand All @@ -46,7 +46,7 @@ func testBufferView(_ x: __owned [Int]) {
func getBool() -> Bool { return true }

func testConditionalBufferView(_ x: __owned [Int]) {
(_move x).withUnsafeBufferPointer {
(consume x).withUnsafeBufferPointer {
let y = BufferView(ptr: $0)
// CHECK: 4
// CHECK: 5
Expand Down
Loading