Skip to content

[Parse] Skip type specifiers in middle of composition types #13173

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 2 commits into from
Dec 1, 2017
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
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,8 @@ ERROR(attr_interpolated_string,none,

ERROR(attr_only_at_non_local_scope, none,
"attribute '%0' can only be used in a non-local scope", (StringRef))
ERROR(attr_only_on_parameters_parse, none,
"'%0' may only be used on parameters", (StringRef))

// Access control
ERROR(attr_access_expected_set,none,
Expand Down
2 changes: 0 additions & 2 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -933,12 +933,10 @@ class Parser {
bool HandleCodeCompletion = true,
bool IsSILFuncDecl = false);

ParserResult<TypeRepr> parseTypeSimpleOrComposition();
ParserResult<TypeRepr>
parseTypeSimpleOrComposition(Diag<> MessageID,
bool HandleCodeCompletion = true);

ParserResult<TypeRepr> parseTypeSimple();
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID,
bool HandleCodeCompletion = true);

Expand Down
50 changes: 8 additions & 42 deletions lib/Parse/ParseType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ LayoutConstraint Parser::parseLayoutConstraint(Identifier LayoutConstraintID) {
alignment, Context);
}

ParserResult<TypeRepr> Parser::parseTypeSimple() {
return parseTypeSimple(diag::expected_type);
}

/// parseTypeSimple
/// type-simple:
/// type-identifier
Expand All @@ -176,22 +172,14 @@ ParserResult<TypeRepr> Parser::parseTypeSimple() {
ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
bool HandleCodeCompletion) {
ParserResult<TypeRepr> ty;
// If this is an "inout" marker for an identifier type, consume the inout.
SourceLoc SpecifierLoc;
VarDecl::Specifier TypeSpecifier;
if (Tok.is(tok::kw_inout)) {
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::InOut;
} 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;
}

if (Tok.is(tok::kw_inout) ||
(Tok.is(tok::identifier) && (Tok.getRawText().equals("__shared") ||
Tok.getRawText().equals("__owned")))) {
// Type specifier should already be parsed before here. This only happens
// for construct like 'P1 & inout P2'.
diagnose(Tok.getLoc(), diag::attr_only_on_parameters_parse, Tok.getText());
consumeToken();
}

switch (Tok.getKind()) {
Expand Down Expand Up @@ -301,24 +289,6 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
break;
}

// If we parsed any specifier, prepend it.
if (SpecifierLoc.isValid() && ty.isNonNull()) {
TypeRepr *repr = ty.get();
switch (TypeSpecifier) {
case VarDecl::Specifier::InOut:
repr = new (Context) InOutTypeRepr(repr, SpecifierLoc);
break;
case VarDecl::Specifier::Shared:
repr = new (Context) SharedTypeRepr(repr, SpecifierLoc);
break;
case VarDecl::Specifier::Owned:
break;
case VarDecl::Specifier::Var:
llvm_unreachable("tried to create var type specifier?");
}
ty = makeParserResult(repr);
}

return ty;
}

Expand Down Expand Up @@ -677,10 +647,6 @@ SyntaxParserResult<TypeSyntax, TypeRepr> Parser::parseTypeIdentifier() {
return makeSyntaxResult(Status, SyntaxNode, ITR);
}

ParserResult<TypeRepr> Parser::parseTypeSimpleOrComposition() {
return parseTypeSimpleOrComposition(diag::expected_identifier_for_type);
}

/// parseTypeSimpleOrComposition
///
/// type-composition:
Expand Down
4 changes: 4 additions & 0 deletions test/type/protocol_composition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,7 @@ takesP1AndP2([AnyObject & protocol_composition.P1 & P2]())
takesP1AndP2([AnyObject & P1 & protocol_composition.P2]())
takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{use of unresolved identifier 'DoesNotExist'}}
takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}}

typealias T08 = P1 & inout P2 // expected-error {{'inout' may only be used on parameters}}
typealias T09 = P1 & __shared P2 // expected-error {{'__shared' may only be used on parameters}}
typealias T10 = P1 & __owned P2 // expected-error {{'__owned' may only be used on parameters}}