Skip to content

Commit e7be78b

Browse files
committed
[Parse] Skip type specifiers in middle of composition types
Like `P & inout P2`. Don't bother to construct wrapped TypeRepr for them.
1 parent 0bcaf90 commit e7be78b

File tree

3 files changed

+14
-34
lines changed

3 files changed

+14
-34
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,8 @@ ERROR(attr_interpolated_string,none,
12801280

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

12841286
// Access control
12851287
ERROR(attr_access_expected_set,none,

lib/Parse/ParseType.cpp

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -172,22 +172,14 @@ LayoutConstraint Parser::parseLayoutConstraint(Identifier LayoutConstraintID) {
172172
ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
173173
bool HandleCodeCompletion) {
174174
ParserResult<TypeRepr> ty;
175-
// If this is an "inout" marker for an identifier type, consume the inout.
176-
SourceLoc SpecifierLoc;
177-
VarDecl::Specifier TypeSpecifier;
178-
if (Tok.is(tok::kw_inout)) {
179-
SpecifierLoc = consumeToken();
180-
TypeSpecifier = VarDecl::Specifier::InOut;
181-
} else if (Tok.is(tok::identifier)) {
182-
if (Tok.getRawText().equals("__shared")) {
183-
assert(false);
184-
SpecifierLoc = consumeToken();
185-
TypeSpecifier = VarDecl::Specifier::Shared;
186-
} else if (Tok.getRawText().equals("__owned")) {
187-
assert(false);
188-
SpecifierLoc = consumeToken();
189-
TypeSpecifier = VarDecl::Specifier::Owned;
190-
}
175+
176+
if (Tok.is(tok::kw_inout) ||
177+
(Tok.is(tok::identifier) && (Tok.getRawText().equals("__shared") ||
178+
Tok.getRawText().equals("__owned")))) {
179+
// Type specifier should already be parsed before here. This only happens
180+
// for construct like 'P1 & inout P2'.
181+
diagnose(Tok.getLoc(), diag::attr_only_on_parameters_parse, Tok.getText());
182+
consumeToken();
191183
}
192184

193185
switch (Tok.getKind()) {
@@ -297,24 +289,6 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
297289
break;
298290
}
299291

300-
// If we parsed any specifier, prepend it.
301-
if (SpecifierLoc.isValid() && ty.isNonNull()) {
302-
TypeRepr *repr = ty.get();
303-
switch (TypeSpecifier) {
304-
case VarDecl::Specifier::InOut:
305-
repr = new (Context) InOutTypeRepr(repr, SpecifierLoc);
306-
break;
307-
case VarDecl::Specifier::Shared:
308-
repr = new (Context) SharedTypeRepr(repr, SpecifierLoc);
309-
break;
310-
case VarDecl::Specifier::Owned:
311-
break;
312-
case VarDecl::Specifier::Var:
313-
llvm_unreachable("tried to create var type specifier?");
314-
}
315-
ty = makeParserResult(repr);
316-
}
317-
318292
return ty;
319293
}
320294

test/type/protocol_composition.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,7 @@ takesP1AndP2([AnyObject & protocol_composition.P1 & P2]())
174174
takesP1AndP2([AnyObject & P1 & protocol_composition.P2]())
175175
takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{use of unresolved identifier 'DoesNotExist'}}
176176
takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}}
177+
178+
typealias T08 = P1 & inout P2 // expected-error {{'inout' may only be used on parameters}}
179+
typealias T09 = P1 & __shared P2 // expected-error {{'__shared' may only be used on parameters}}
180+
typealias T10 = P1 & __owned P2 // expected-error {{'__owned' may only be used on parameters}}

0 commit comments

Comments
 (0)