From 93c80da77c9aa8086c5bf9d466099f88a8b7856e Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 24 Oct 2017 17:26:07 -0700 Subject: [PATCH] Parse: __shared and __owned should be contextual keywords This was a source compatibility regression, someone actually had an identifier named __shared. --- include/swift/Parse/Parser.h | 5 ++++- include/swift/Parse/Token.h | 16 ++++++++++------ include/swift/Syntax/TokenKinds.def | 2 -- lib/Parse/ParseDecl.cpp | 19 +++++++++++-------- lib/Parse/ParsePattern.cpp | 9 ++++++--- lib/Parse/ParseType.cpp | 17 ++++++++++------- .../shared_owned_identifiers.swift | 10 ++++++++++ .../complete_override.swift.response | 18 ------------------ 8 files changed, 51 insertions(+), 45 deletions(-) create mode 100644 test/Compatibility/shared_owned_identifiers.swift diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index bdc2eb77435..4a31d0dfe27 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -787,7 +787,10 @@ public: bool parseTypeAttributeList(VarDecl::Specifier &Specifier, SourceLoc &SpecifierLoc, TypeAttributes &Attributes) { - if (Tok.isAny(tok::at_sign, tok::kw_inout, tok::kw___shared, tok::kw___owned)) + if (Tok.isAny(tok::at_sign, tok::kw_inout) || + (Tok.is(tok::identifier) && + (Tok.getRawText().equals("__shared") || + Tok.getRawText().equals("__owned")))) return parseTypeAttributeListPresent(Specifier, SpecifierLoc, Attributes); return false; } diff --git a/include/swift/Parse/Token.h b/include/swift/Parse/Token.h index 571223db2c9..0d61930e0d8 100644 --- a/include/swift/Parse/Token.h +++ b/include/swift/Parse/Token.h @@ -179,13 +179,17 @@ public: /// used bool canBeArgumentLabel() const { // Identifiers, escaped identifiers, and '_' can be argument labels. - if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__)) - return true; + if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__)) { + // ... except for '__shared' and '__owned'. + if (getRawText().equals("__shared") || + getRawText().equals("__owned")) + return false; - // 'let', 'var', 'inout', '__shared', and '__owned' - // cannot be argument labels. - if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout, - tok::kw___owned, tok::kw___shared)) + return true; + } + + // 'let', 'var', and 'inout' cannot be argument labels. + if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout)) return false; // All other keywords can be argument labels. diff --git a/include/swift/Syntax/TokenKinds.def b/include/swift/Syntax/TokenKinds.def index 4b0a05d331c..02c4f578641 100644 --- a/include/swift/Syntax/TokenKinds.def +++ b/include/swift/Syntax/TokenKinds.def @@ -140,8 +140,6 @@ DECL_KEYWORD(struct) DECL_KEYWORD(subscript) DECL_KEYWORD(typealias) DECL_KEYWORD(var) -DECL_KEYWORD(__shared) -DECL_KEYWORD(__owned) DECL_KEYWORD(fileprivate) DECL_KEYWORD(internal) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c19c54ed81b..f52ae923606 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1820,19 +1820,22 @@ bool Parser::parseTypeAttributeListPresent(VarDecl::Specifier &Specifier, SourceLoc &SpecifierLoc, TypeAttributes &Attributes) { Specifier = VarDecl::Specifier::Owned; - while (Tok.isAny(tok::kw_inout, tok::kw___shared, tok::kw___owned)) { + while (Tok.is(tok::kw_inout) || + (Tok.is(tok::identifier) && + (Tok.getRawText().equals("__shared") || + Tok.getRawText().equals("__owned")))) { if (SpecifierLoc.isValid()) { diagnose(Tok, diag::parameter_specifier_repeated) .fixItRemove(SpecifierLoc); } else { - if (Tok.is(tok::kw___owned)) { - Specifier = VarDecl::Specifier::Owned; - } else if (Tok.is(tok::kw_inout)) { + if (Tok.is(tok::kw_inout)) { Specifier = VarDecl::Specifier::InOut; - } else if (Tok.is(tok::kw___shared)) { - Specifier = VarDecl::Specifier::Shared; - } else { - llvm_unreachable("unhandled specifier kind?"); + } else if (Tok.is(tok::identifier)) { + if (Tok.getRawText().equals("__shared")) { + Specifier = VarDecl::Specifier::Shared; + } else if (Tok.getRawText().equals("__owned")) { + Specifier = VarDecl::Specifier::Owned; + } } } SpecifierLoc = consumeToken(); diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index 8106374fb37..09c2496e83a 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -182,15 +182,18 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, // ('inout' | 'let' | 'var' | '__shared' | '__owned')? bool hasSpecifier = false; - while (Tok.isAny(tok::kw_inout, tok::kw_let, tok::kw_var, - tok::kw___shared, tok::kw___owned)) { + while (Tok.isAny(tok::kw_inout, tok::kw_let, tok::kw_var) || + (Tok.is(tok::identifier) && + (Tok.getRawText().equals("__shared") || + Tok.getRawText().equals("__owned")))) { if (!hasSpecifier) { if (Tok.is(tok::kw_inout)) { // This case is handled later when mapping to ParamDecls for // better fixits. param.SpecifierKind = VarDecl::Specifier::InOut; param.SpecifierLoc = consumeToken(); - } else if (Tok.is(tok::kw___shared)) { + } else if (Tok.is(tok::identifier) && + Tok.getRawText().equals("__shared")) { // This case is handled later when mapping to ParamDecls for // better fixits. param.SpecifierKind = VarDecl::Specifier::Shared; diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index f9f69f0ab08..bf668640dc5 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -175,13 +175,16 @@ ParserResult Parser::parseTypeSimple(Diag<> MessageID, if (Tok.is(tok::kw_inout)) { SpecifierLoc = consumeToken(); TypeSpecifier = VarDecl::Specifier::InOut; - } else if (Tok.is(tok::kw___shared)) { - SpecifierLoc = consumeToken(); - TypeSpecifier = VarDecl::Specifier::Shared; - } else if (Tok.is(tok::kw___owned)) { - SpecifierLoc = consumeToken(); - TypeSpecifier = VarDecl::Specifier::Owned; - + } else if (Tok.is(tok::identifier)) { + if (Tok.getRawText().equals("__shared")) { + assert(false); + SpecifierLoc = consumeToken(); + TypeSpecifier = VarDecl::Specifier::Shared; + } else if (Tok.getRawText().equals("__owned")) { + assert(false); + SpecifierLoc = consumeToken(); + TypeSpecifier = VarDecl::Specifier::Owned; + } } switch (Tok.getKind()) { diff --git a/test/Compatibility/shared_owned_identifiers.swift b/test/Compatibility/shared_owned_identifiers.swift new file mode 100644 index 00000000000..57164f3f3a0 --- /dev/null +++ b/test/Compatibility/shared_owned_identifiers.swift @@ -0,0 +1,10 @@ +// RUN: %target-swift-frontend -typecheck %s + +func __shared() {} + +func __owned() {} + +func foo() { + __shared() + __owned() +} diff --git a/test/SourceKit/CodeComplete/complete_override.swift.response b/test/SourceKit/CodeComplete/complete_override.swift.response index e64d861c89f..87fb5e9939e 100644 --- a/test/SourceKit/CodeComplete/complete_override.swift.response +++ b/test/SourceKit/CodeComplete/complete_override.swift.response @@ -1,23 +1,5 @@ { key.results: [ - { - key.kind: source.lang.swift.keyword, - key.name: "__owned", - key.sourcetext: "__owned", - key.description: "__owned", - key.typename: "", - key.context: source.codecompletion.context.none, - key.num_bytes_to_erase: 0 - }, - { - key.kind: source.lang.swift.keyword, - key.name: "__shared", - key.sourcetext: "__shared", - key.description: "__shared", - key.typename: "", - key.context: source.codecompletion.context.none, - key.num_bytes_to_erase: 0 - }, { key.kind: source.lang.swift.keyword, key.name: "associatedtype",