Skip to content

Commit d4e06b1

Browse files
authored
Merge pull request #5290 from rintaro/composition-typerepr
[SR-2843] Reorder precedence of '&' in type parsing
2 parents 2aa4def + e61a6d9 commit d4e06b1

20 files changed

+475
-241
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ ERROR(expected_identifier_for_type,PointsToFirstBadToken,
608608
"expected identifier for type name", ())
609609
ERROR(expected_rangle_generic_arg_list,PointsToFirstBadToken,
610610
"expected '>' to complete generic argument list", ())
611+
ERROR(expected_ident_type_in_inheritance,none,
612+
"inheritance from non-named type %0", (TypeLoc))
611613

612614

613615
// Function types

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,9 @@ ERROR(protocol_composition_not_protocol,none,
15061506
"non-protocol type %0 cannot be used within a protocol composition", (Type))
15071507
ERROR(objc_protocol_inherits_non_objc_protocol,none,
15081508
"@objc protocol %0 cannot refine non-@objc protocol %1", (Type, Type))
1509+
WARNING(protocol_composition_with_postfix,none,
1510+
"protocol composition with postfix '%0' is ambiguous "
1511+
"and will be rejected in future version of Swift", (StringRef))
15091512

15101513
ERROR(requires_conformance_nonprotocol,none,
15111514
"type %0 constrained to non-protocol type %1", (TypeLoc, TypeLoc))

include/swift/AST/TypeRepr.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -634,41 +634,41 @@ class NamedTypeRepr : public TypeRepr {
634634
friend class TypeRepr;
635635
};
636636

637-
/// \brief A protocol composite type.
637+
/// \brief A type composite type.
638638
/// \code
639639
/// Foo & Bar
640640
/// \endcode
641-
class ProtocolCompositionTypeRepr : public TypeRepr {
642-
ArrayRef<IdentTypeRepr *> Protocols;
641+
class CompositionTypeRepr : public TypeRepr {
642+
ArrayRef<TypeRepr *> Types;
643643
SourceLoc FirstTypeLoc;
644644
SourceRange CompositionRange;
645645

646646
public:
647-
ProtocolCompositionTypeRepr(ArrayRef<IdentTypeRepr *> Protocols,
648-
SourceLoc FirstTypeLoc,
649-
SourceRange CompositionRange)
650-
: TypeRepr(TypeReprKind::ProtocolComposition), Protocols(Protocols),
647+
CompositionTypeRepr(ArrayRef<TypeRepr *> Types,
648+
SourceLoc FirstTypeLoc,
649+
SourceRange CompositionRange)
650+
: TypeRepr(TypeReprKind::Composition), Types(Types),
651651
FirstTypeLoc(FirstTypeLoc), CompositionRange(CompositionRange) {
652652
}
653653

654-
ArrayRef<IdentTypeRepr *> getProtocols() const { return Protocols; }
654+
ArrayRef<TypeRepr *> getTypes() const { return Types; }
655655
SourceLoc getSourceLoc() const { return FirstTypeLoc; }
656656
SourceRange getCompositionRange() const { return CompositionRange; }
657657

658-
static ProtocolCompositionTypeRepr *create(ASTContext &C,
659-
ArrayRef<IdentTypeRepr*> Protocols,
660-
SourceLoc FirstTypeLoc,
661-
SourceRange CompositionRange);
658+
static CompositionTypeRepr *create(ASTContext &C,
659+
ArrayRef<TypeRepr*> Protocols,
660+
SourceLoc FirstTypeLoc,
661+
SourceRange CompositionRange);
662662

663-
static ProtocolCompositionTypeRepr *createEmptyComposition(ASTContext &C,
664-
SourceLoc AnyLoc) {
665-
return ProtocolCompositionTypeRepr::create(C, {}, AnyLoc, {AnyLoc, AnyLoc});
663+
static CompositionTypeRepr *createEmptyComposition(ASTContext &C,
664+
SourceLoc AnyLoc) {
665+
return CompositionTypeRepr::create(C, {}, AnyLoc, {AnyLoc, AnyLoc});
666666
}
667667

668668
static bool classof(const TypeRepr *T) {
669-
return T->getKind() == TypeReprKind::ProtocolComposition;
669+
return T->getKind() == TypeReprKind::Composition;
670670
}
671-
static bool classof(const ProtocolCompositionTypeRepr *T) { return true; }
671+
static bool classof(const CompositionTypeRepr *T) { return true; }
672672

673673
private:
674674
SourceLoc getStartLocImpl() const { return FirstTypeLoc; }
@@ -812,7 +812,7 @@ inline bool TypeRepr::isSimple() const {
812812
case TypeReprKind::Dictionary:
813813
case TypeReprKind::Optional:
814814
case TypeReprKind::ImplicitlyUnwrappedOptional:
815-
case TypeReprKind::ProtocolComposition:
815+
case TypeReprKind::Composition:
816816
case TypeReprKind::Tuple:
817817
case TypeReprKind::Fixed:
818818
case TypeReprKind::Array:

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ TYPEREPR(Optional, TypeRepr)
4747
TYPEREPR(ImplicitlyUnwrappedOptional, TypeRepr)
4848
TYPEREPR(Tuple, TypeRepr)
4949
TYPEREPR(Named, TypeRepr)
50-
TYPEREPR(ProtocolComposition, TypeRepr)
50+
TYPEREPR(Composition, TypeRepr)
5151
TYPEREPR(Metatype, TypeRepr)
5252
TYPEREPR(Protocol, TypeRepr)
5353
TYPEREPR(InOut, TypeRepr)

include/swift/Parse/Parser.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -824,18 +824,24 @@ class Parser {
824824
ParserResult<TypeRepr> parseType(Diag<> MessageID,
825825
bool HandleCodeCompletion = true);
826826

827-
/// \brief Parse any type, but diagnose all types except type-identifier.
827+
/// \brief Parse any type, but diagnose all types except type-identifier or
828+
/// type-composition with non-type-identifier.
828829
///
829-
/// In some places the grammar allows type-identifier, but when it is not
830-
/// ambiguous, we want to parse any type for recovery purposes.
830+
/// In some places the grammar allows only type-identifier, but when it is
831+
/// not ambiguous, we want to parse any type for recovery purposes.
831832
///
832833
/// \param MessageID a generic diagnostic for a syntax error in the type
833834
/// \param NonIdentifierTypeMessageID a diagnostic for a non-identifier type
834835
///
835-
/// \returns null, IdentTypeRepr or ErrorTypeRepr.
836+
/// \returns null, IdentTypeRepr, CompositionTypeRepr or ErrorTypeRepr.
836837
ParserResult<TypeRepr>
837-
parseTypeIdentifierWithRecovery(Diag<> MessageID,
838-
Diag<TypeLoc> NonIdentifierTypeMessageID);
838+
parseTypeForInheritance(Diag<> MessageID,
839+
Diag<TypeLoc> NonIdentifierTypeMessageID);
840+
841+
ParserResult<TypeRepr> parseTypeSimpleOrComposition();
842+
ParserResult<TypeRepr>
843+
parseTypeSimpleOrComposition(Diag<> MessageID,
844+
bool HandleCodeCompletion = true);
839845

840846
ParserResult<TypeRepr> parseTypeSimple();
841847
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID,
@@ -845,8 +851,8 @@ class Parser {
845851
SourceLoc &RAngleLoc);
846852

847853
ParserResult<TypeRepr> parseTypeIdentifier();
848-
ParserResult<TypeRepr> parseTypeIdentifierOrTypeComposition();
849-
ParserResult<ProtocolCompositionTypeRepr> parseAnyType();
854+
ParserResult<TypeRepr> parseOldStyleProtocolComposition();
855+
ParserResult<CompositionTypeRepr> parseAnyType();
850856

851857
ParserResult<TupleTypeRepr> parseTypeTupleBody();
852858
ParserResult<TypeRepr> parseTypeArray(TypeRepr *Base);

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,9 +2438,9 @@ class PrintTypeRepr : public TypeReprVisitor<PrintTypeRepr> {
24382438
OS << ')';
24392439
}
24402440

2441-
void visitProtocolCompositionTypeRepr(ProtocolCompositionTypeRepr *T) {
2441+
void visitCompositionTypeRepr(CompositionTypeRepr *T) {
24422442
printCommon(T, "type_composite");
2443-
for (auto elem : T->getProtocols()) {
2443+
for (auto elem : T->getTypes()) {
24442444
OS << '\n';
24452445
printRec(elem);
24462446
}

lib/AST/ASTWalker.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,9 +1540,8 @@ bool Traversal::visitNamedTypeRepr(NamedTypeRepr *T) {
15401540
return false;
15411541
}
15421542

1543-
bool Traversal::visitProtocolCompositionTypeRepr(
1544-
ProtocolCompositionTypeRepr *T) {
1545-
for (auto elem : T->getProtocols()) {
1543+
bool Traversal::visitCompositionTypeRepr(CompositionTypeRepr *T) {
1544+
for (auto elem : T->getTypes()) {
15461545
if (doIt(elem))
15471546
return true;
15481547
}

lib/AST/TypeRepr.cpp

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -200,17 +200,16 @@ TypeRepr *CloneVisitor::visitNamedTypeRepr(NamedTypeRepr *T) {
200200
T->getNameLoc(), T->getUnderscoreLoc());
201201
}
202202

203-
TypeRepr *CloneVisitor::visitProtocolCompositionTypeRepr(
204-
ProtocolCompositionTypeRepr *T) {
203+
TypeRepr *CloneVisitor::visitCompositionTypeRepr(CompositionTypeRepr *T) {
205204
// Clone the protocols.
206-
auto protocols = Ctx.Allocate<IdentTypeRepr*>(T->getProtocols().size());
207-
for (unsigned argI : indices(protocols)) {
208-
protocols[argI] = cast<IdentTypeRepr>(visit(T->getProtocols()[argI]));
205+
auto types = Ctx.Allocate<TypeRepr*>(T->getTypes().size());
206+
for (unsigned argI : indices(types)) {
207+
types[argI] = cast<TypeRepr>(visit(T->getTypes()[argI]));
209208
}
210209

211-
return new (Ctx) ProtocolCompositionTypeRepr(protocols,
212-
T->getStartLoc(),
213-
T->getCompositionRange());
210+
return new (Ctx) CompositionTypeRepr(types,
211+
T->getStartLoc(),
212+
T->getCompositionRange());
214213
}
215214

216215
TypeRepr *CloneVisitor::visitMetatypeTypeRepr(MetatypeTypeRepr *T) {
@@ -249,9 +248,9 @@ void TypeRepr::visitTopLevelTypeReprs(
249248
}
250249

251250
// Recurse into protocol compositions.
252-
if (auto composition = dyn_cast<ProtocolCompositionTypeRepr>(typeRepr)) {
253-
for (auto ident : composition->getProtocols())
254-
ident->visitTopLevelTypeReprs(visitor);
251+
if (auto composition = dyn_cast<CompositionTypeRepr>(typeRepr)) {
252+
for (auto type: composition->getTypes())
253+
type->visitTopLevelTypeReprs(visitor);
255254
return;
256255
}
257256
}
@@ -445,27 +444,27 @@ void NamedTypeRepr::printImpl(ASTPrinter &Printer,
445444
printTypeRepr(Ty, Printer, Opts);
446445
}
447446

448-
ProtocolCompositionTypeRepr *
449-
ProtocolCompositionTypeRepr::create(ASTContext &C,
450-
ArrayRef<IdentTypeRepr *> Protocols,
451-
SourceLoc FirstTypeLoc,
452-
SourceRange CompositionRange) {
453-
return new (C) ProtocolCompositionTypeRepr(C.AllocateCopy(Protocols),
454-
FirstTypeLoc, CompositionRange);
447+
CompositionTypeRepr *
448+
CompositionTypeRepr::create(ASTContext &C,
449+
ArrayRef<TypeRepr *> Types,
450+
SourceLoc FirstTypeLoc,
451+
SourceRange CompositionRange) {
452+
return new (C) CompositionTypeRepr(C.AllocateCopy(Types),
453+
FirstTypeLoc, CompositionRange);
455454
}
456455

457-
void ProtocolCompositionTypeRepr::printImpl(ASTPrinter &Printer,
458-
const PrintOptions &Opts) const {
459-
if (Protocols.empty()) {
456+
void CompositionTypeRepr::printImpl(ASTPrinter &Printer,
457+
const PrintOptions &Opts) const {
458+
if (Types.empty()) {
460459
Printer << "Any";
461460
} else {
462461
bool First = true;
463-
for (auto Proto : Protocols) {
462+
for (auto T : Types) {
464463
if (First)
465464
First = false;
466465
else
467466
Printer << " & ";
468-
printTypeRepr(Proto, Printer, Opts);
467+
printTypeRepr(T, Printer, Opts);
469468
}
470469
}
471470
}

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,17 +2412,21 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
24122412
continue;
24132413
}
24142414

2415-
bool usesDeprecatedCompositionSyntax = Tok.is(tok::kw_protocol) && startsWithLess(peekToken());
2415+
bool usesDeprecatedCompositionSyntax =
2416+
Tok.is(tok::kw_protocol) && startsWithLess(peekToken());
24162417
bool isAny = Tok.is(tok::kw_Any); // We allow (redundant) inheritance from Any
24172418

2418-
auto ParsedTypeResult = parseTypeIdentifierOrTypeComposition();
2419+
auto ParsedTypeResult = parseTypeForInheritance(
2420+
diag::expected_identifier_for_type,
2421+
diag::expected_ident_type_in_inheritance);
24192422
Status |= ParsedTypeResult;
24202423

2421-
// Cannot inherit from composition
2422-
if (auto Composition = dyn_cast_or_null<ProtocolCompositionTypeRepr>(ParsedTypeResult.getPtrOrNull())) {
2424+
// Recover and emit nice diagnostic for composition.
2425+
if (auto Composition = dyn_cast_or_null<CompositionTypeRepr>(
2426+
ParsedTypeResult.getPtrOrNull())) {
24232427
// Record the protocols inside the composition.
2424-
Inherited.append(Composition->getProtocols().begin(),
2425-
Composition->getProtocols().end());
2428+
Inherited.append(Composition->getTypes().begin(),
2429+
Composition->getTypes().end());
24262430
// We can inherit from Any
24272431
if (!isAny) {
24282432
if (usesDeprecatedCompositionSyntax) {

lib/Parse/ParseGeneric.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ Parser::parseGenericParameters(SourceLoc LAngleLoc) {
7171
ParserResult<TypeRepr> Ty;
7272

7373
if (Tok.isAny(tok::identifier, tok::code_complete, tok::kw_protocol, tok::kw_Any)) {
74-
Ty = parseTypeIdentifierOrTypeComposition();
74+
Ty = parseTypeForInheritance(diag::expected_identifier_for_type,
75+
diag::expected_ident_type_in_inheritance);
7576
} else if (Tok.is(tok::kw_class)) {
7677
diagnose(Tok, diag::unexpected_class_constraint);
7778
diagnose(Tok, diag::suggest_anyobject, Name)
@@ -267,7 +268,9 @@ ParserStatus Parser::parseGenericWhereClause(
267268
SourceLoc ColonLoc = consumeToken();
268269

269270
// Parse the protocol or composition.
270-
ParserResult<TypeRepr> Protocol = parseTypeIdentifierOrTypeComposition();
271+
ParserResult<TypeRepr> Protocol = parseTypeForInheritance(
272+
diag::expected_identifier_for_type,
273+
diag::expected_ident_type_in_inheritance);
271274

272275
if (Protocol.isNull()) {
273276
Status.setIsParseError();

0 commit comments

Comments
 (0)