Skip to content

Commit 67dccb2

Browse files
joewillsherDougGregor
authored andcommitted
[SE-0095] Code feedback changes; Any is parsed as a keyword
- Any is made into a keyword which is always resolved into a TypeExpr, allowing the removal of the type system code to find TheAnyType before an unconstrained lookup. - Types called `Any` can be declared, they are looked up as any other identifier is - Renaming/redefining behaviour of source loc methods on ProtocolCompositionTypeRepr. Added a createEmptyComposition static method too. - Code highlighting treats Any as a type - simplifyTypeExpr also does not rely on source to get operator name. - Any is now handled properly in canParseType() which was causing generic param lists containing ‘Any’ to fail - The import objc id as Any work has been relying on getting a decl for the Any type. I fix up the clang importer to use Context.TheAnyType (instead of getAnyDecl()->getDeclaredType()). When importing the id typedef, we create a typealias to Any and declare it unavaliable.
1 parent da94183 commit 67dccb2

36 files changed

+264
-2188
lines changed

CHANGELOG.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ Swift 3.0
44
---------
55

66
* [SE-0095](https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md):
7-
The `protocol<...>` composition construct has been removed. In its
8-
place, an infix type operator `&` has been introduced.
7+
The `protocol<...>` composition construct has been removed. In its
8+
place, an infix type operator `&` has been introduced.
99

10-
```swift
11-
let a: Foo & Bar
12-
let b = value as? A & B & C
13-
func foo<T : Foo & Bar>(x: T) { }
14-
func bar(x: Foo & Bar) { }
15-
typealias G = GenericStruct<Foo & Bar>
16-
```
10+
```swift
11+
let a: Foo & Bar
12+
let b = value as? A & B & C
13+
func foo<T : Foo & Bar>(x: T) { }
14+
func bar(x: Foo & Bar) { }
15+
typealias G = GenericStruct<Foo & Bar>
16+
```
1717

18-
The empty protocol composition, the `Any` type, was previously
19-
defined as being `protocol<>`. This has been removed from the
20-
standard library and `Any` is now a keyword with the same behaviour.
18+
The empty protocol composition, the `Any` type, was previously
19+
defined as being `protocol<>`. This has been removed from the
20+
standard library and `Any` is now a keyword with the same behaviour.
2121

2222
* [SE-0091](https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md):
2323
Operators can now be defined within types or extensions thereof. For example:

docs/ABI.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ contain the following fields:
461461
`protocol descriptor`_ records, but are pre-calculated for convenience.
462462

463463
- The **number of protocols** that make up the protocol composition is stored at
464-
**offset 2**. For the "any" types ``Any`` or ``Any : Class``, this
464+
**offset 2**. For the "any" types ``Any`` or ``Any : class``, this
465465
is zero. For a single-protocol type ``P``, this is one. For a protocol
466466
composition type ``P & Q & ...``, this is the number of protocols.
467467

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,9 +655,9 @@ ERROR(expected_rangle_protocol,PointsToFirstBadToken,
655655
ERROR(disallowed_protocol_composition,PointsToFirstBadToken,
656656
"protocol composition is neither allowed nor needed here", ())
657657

658-
WARNING(deprecated_protocol_composition,PointsToFirstBadToken,
658+
WARNING(deprecated_protocol_composition,none,
659659
"'protocol<...>' composition syntax is deprecated; join the protocols using '&'", ())
660-
WARNING(deprecated_any_composition,PointsToFirstBadToken,
660+
WARNING(deprecated_any_composition,none,
661661
"'protocol<>' syntax is deprecated; use 'Any' instead", ())
662662

663663
//------------------------------------------------------------------------------

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ ERROR(reserved_member_name,none,
517517
ERROR(invalid_redecl,none,"invalid redeclaration of %0", (DeclName))
518518
NOTE(invalid_redecl_prev,none,
519519
"%0 previously declared here", (DeclName))
520-
ERROR(invalid_redecl_any,none,"invalid redeclaration of 'Any'; cannot overload type keyword", ())
521520

522521
ERROR(ambiguous_type_base,none,
523522
"%0 is ambiguous for type lookup in this context", (Identifier))

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
IDENTIFIER(alloc)
2626
IDENTIFIER(allocWithZone)
2727
IDENTIFIER(allZeros)
28+
IDENTIFIER(Any)
2829
IDENTIFIER(atIndexedSubscript)
2930
IDENTIFIER_(bridgeToObjectiveC)
3031
IDENTIFIER_WITH_NAME(code_, "_code")
@@ -60,7 +61,6 @@ IDENTIFIER(RawValue)
6061
IDENTIFIER(Selector)
6162
IDENTIFIER(self)
6263
IDENTIFIER(Self)
63-
IDENTIFIER(Any)
6464
IDENTIFIER(setObject)
6565
IDENTIFIER(simd)
6666
IDENTIFIER(some)

include/swift/AST/TypeRepr.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,21 +629,27 @@ class ProtocolCompositionTypeRepr : public TypeRepr {
629629
}
630630

631631
ArrayRef<IdentTypeRepr *> getProtocols() const { return Protocols; }
632-
SourceLoc getStartLoc() const { return FirstTypeLoc; }
632+
SourceLoc getSourceLoc() const { return FirstTypeLoc; }
633633
SourceRange getCompositionRange() const { return CompositionRange; }
634634

635635
static ProtocolCompositionTypeRepr *create(ASTContext &C,
636636
ArrayRef<IdentTypeRepr*> Protocols,
637637
SourceLoc FirstTypeLoc,
638638
SourceRange CompositionRange);
639-
639+
640+
static ProtocolCompositionTypeRepr *createEmptyComposition(ASTContext &C,
641+
SourceLoc AnyLoc) {
642+
return ProtocolCompositionTypeRepr::create(C, {}, AnyLoc, {AnyLoc, AnyLoc});
643+
}
644+
640645
static bool classof(const TypeRepr *T) {
641646
return T->getKind() == TypeReprKind::ProtocolComposition;
642647
}
643648
static bool classof(const ProtocolCompositionTypeRepr *T) { return true; }
644649

645650
private:
646651
SourceLoc getStartLocImpl() const { return FirstTypeLoc; }
652+
SourceLoc getLocImpl() const { return CompositionRange.Start; }
647653
SourceLoc getEndLocImpl() const { return CompositionRange.End; }
648654
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
649655
friend class TypeRepr;

include/swift/Parse/Parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,8 +877,9 @@ class Parser {
877877
SourceLoc &LAngleLoc,
878878
SourceLoc &RAngleLoc);
879879

880-
ParserResult<IdentTypeRepr> parseTypeIdentifier();
880+
ParserResult<TypeRepr> parseTypeIdentifier();
881881
ParserResult<TypeRepr> parseTypeIdentifierOrTypeComposition();
882+
ParserResult<ProtocolCompositionTypeRepr> parseAnyType();
882883

883884
ParserResult<TupleTypeRepr> parseTypeTupleBody();
884885
ParserResult<TypeRepr> parseTypeArray(TypeRepr *Base);
@@ -1083,7 +1084,7 @@ class Parser {
10831084
bool canParseType();
10841085
bool canParseTypeIdentifier();
10851086
bool canParseTypeIdentifierOrTypeComposition();
1086-
bool canParseTypeComposition();
1087+
bool canParseOldStyleProtocolComposition();
10871088
bool canParseTypeTupleBody();
10881089
bool canParseTypeAttribute();
10891090
bool canParseGenericArguments();

include/swift/Parse/Tokens.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ STMT_KEYWORD(catch)
128128

129129
// Expression keywords.
130130
KEYWORD(as)
131+
KEYWORD(Any)
131132
KEYWORD(dynamicType)
132133
KEYWORD(false)
133134
KEYWORD(is)

lib/AST/Type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ bool TypeBase::hasReferenceSemantics() {
9090
}
9191

9292
bool TypeBase::isAny() {
93-
return isEqual(getASTContext().getAnyDecl()->getDeclaredType());
93+
return isEqual(getASTContext().TheAnyType);
9494
}
9595

9696
bool TypeBase::isAnyClassReferenceType() {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,22 @@ namespace {
15351535
if (Name.str() == "id" && Impl.SwiftContext.LangOpts.EnableIdAsAny) {
15361536
Impl.SpecialTypedefNames[Decl->getCanonicalDecl()] =
15371537
MappedTypeNameKind::DoNothing;
1538-
return Impl.SwiftContext.getAnyDecl();
1538+
1539+
auto DC = Impl.importDeclContextOf(Decl, importedName.EffectiveContext);
1540+
if (!DC) return nullptr;
1541+
1542+
auto loc = Impl.importSourceLoc(Decl->getLocStart());
1543+
auto Result = Impl.createDeclWithClangNode<TypeAliasDecl>(
1544+
Decl, loc, Name, loc,
1545+
TypeLoc::withoutLoc(Impl.SwiftContext.TheAnyType),
1546+
/*genericparams*/nullptr, DC);
1547+
1548+
auto attr = AvailableAttr::createUnconditional(
1549+
Impl.SwiftContext, "'id' is not available in Swift; use 'Any'",
1550+
"", UnconditionalAvailabilityKind::UnavailableInSwift);
1551+
1552+
Result->getAttrs().add(attr);
1553+
return Result;
15391554
}
15401555

15411556
bool IsError;

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ namespace {
972972
return {
973973
proto->getDeclaredType(),
974974
ImportHint(ImportHint::ObjCBridged,
975-
Impl.SwiftContext.getAnyDecl()->getDeclaredType())};
975+
Impl.SwiftContext.TheAnyType)};
976976
return {proto->getDeclaredType(), ImportHint::ObjCPointer};
977977
}
978978

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4652,9 +4652,9 @@ static void addAnyTypeKeyword(CodeCompletionResultSink &Sink) {
46524652
CodeCompletionResultBuilder Builder(
46534653
Sink, CodeCompletionResult::ResultKind::Keyword,
46544654
SemanticContextKind::None, {});
4655-
// pretend 'Any' is from another module
46564655
Builder.setKeywordKind(CodeCompletionKeywordKind::None);
46574656
Builder.addTextChunk("Any");
4657+
Builder.addTypeAnnotation("Any");
46584658
}
46594659

46604660

lib/IDE/SyntaxModel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile)
9292
LiteralStartLoc = Optional<SourceLoc>();
9393
continue;
9494
}
95-
95+
9696
switch(Tok.getKind()) {
9797
#define KEYWORD(X) case tok::kw_##X: Kind = SyntaxNodeKind::Keyword; break;
9898
#include "swift/Parse/Tokens.def"

lib/IRGen/GenType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,12 +1657,12 @@ llvm::StructType *IRGenModule::createNominalType(CanType type) {
16571657
llvm::StructType *
16581658
IRGenModule::createNominalType(ProtocolCompositionType *type) {
16591659
llvm::SmallString<32> typeName;
1660-
1660+
16611661
SmallVector<ProtocolDecl *, 4> protocols;
16621662
type->getAnyExistentialTypeProtocols(protocols);
16631663

16641664
if (protocols.empty()) {
1665-
typeName.append("swift.Any");
1665+
typeName.append("Any");
16661666
} else {
16671667
for (unsigned i = 0, e = protocols.size(); i != e; ++i) {
16681668
if (i) typeName.push_back('&');

lib/Parse/ParseDecl.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,38 +2433,43 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
24332433
continue;
24342434
}
24352435

2436-
auto usesDeprecatedCompositionSyntax = Tok.is(tok::kw_protocol) && startsWithLess(peekToken());
2437-
2436+
bool usesDeprecatedCompositionSyntax = Tok.is(tok::kw_protocol) && startsWithLess(peekToken());
2437+
bool isAny = Tok.is(tok::kw_Any); // We allow (redundant) inheritance from Any
2438+
24382439
auto ParsedTypeResult = parseTypeIdentifierOrTypeComposition();
24392440
Status |= ParsedTypeResult;
2440-
2441-
// cannot inherit from composition
2441+
2442+
// Cannot inherit from composition
24422443
if (auto Composition = dyn_cast_or_null<ProtocolCompositionTypeRepr>(ParsedTypeResult.getPtrOrNull())) {
24432444
// Record the protocols inside the composition.
24442445
Inherited.append(Composition->getProtocols().begin(),
24452446
Composition->getProtocols().end());
2446-
if (usesDeprecatedCompositionSyntax) {
2447-
// Provide fixits to remove the composition, leaving the types intact.
2448-
auto compositionRange = Composition->getCompositionRange();
2449-
diagnose(Composition->getStartLoc(),
2450-
diag::disallowed_protocol_composition)
2451-
.highlight({Composition->getStartLoc(), compositionRange.End})
2452-
.fixItRemove({Composition->getStartLoc(), compositionRange.Start})
2453-
.fixItRemove(startsWithGreater(L->getTokenAt(compositionRange.End))
2454-
? compositionRange.End
2455-
: SourceLoc());
2456-
} else {
2457-
diagnose(Composition->getStartLoc(),
2458-
diag::disallowed_protocol_composition)
2459-
.highlight(Composition->getCompositionRange());
2460-
// TODO: Decompose 'A & B & C' list to 'A, B, C'
2447+
// We can inherit from Any
2448+
if (!isAny) {
2449+
if (usesDeprecatedCompositionSyntax) {
2450+
// Provide fixits to remove the composition, leaving the types intact.
2451+
auto compositionRange = Composition->getCompositionRange();
2452+
diagnose(Composition->getSourceLoc(),
2453+
diag::disallowed_protocol_composition)
2454+
.highlight({Composition->getStartLoc(), compositionRange.End})
2455+
.fixItRemove({Composition->getSourceLoc(), compositionRange.Start})
2456+
.fixItRemove(startsWithGreater(L->getTokenAt(compositionRange.End))
2457+
? compositionRange.End
2458+
: SourceLoc());
2459+
} else {
2460+
diagnose(Composition->getStartLoc(),
2461+
diag::disallowed_protocol_composition)
2462+
.highlight(Composition->getSourceRange());
2463+
// TODO: Decompose 'A & B & C' list to 'A, B, C'
2464+
}
24612465
}
2462-
} else {
2463-
// Record the type if its a single type.
2464-
if (ParsedTypeResult.isNonNull())
2465-
Inherited.push_back(ParsedTypeResult.get());
2466+
continue;
24662467
}
24672468

2469+
// Record the type if its a single type.
2470+
if (ParsedTypeResult.isNonNull())
2471+
Inherited.push_back(ParsedTypeResult.get());
2472+
24682473
// Check for a ',', which indicates that there are more protocols coming.
24692474
} while (consumeIf(tok::comma, prevComma));
24702475

lib/Parse/ParseExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,14 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
11761176
}
11771177

11781178
break;
1179+
1180+
case tok::kw_Any: { // Any
1181+
ParserResult<TypeRepr> repr = parseAnyType();
1182+
auto expr = new (Context) TypeExpr(TypeLoc(repr.get()));
1183+
Result = makeParserResult(expr);
1184+
break;
1185+
}
1186+
11791187
case tok::dollarident: // $1
11801188
Result = makeParserResult(parseExprAnonClosureArg());
11811189
break;

lib/Parse/ParseGeneric.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Parser::parseGenericParameters(SourceLoc LAngleLoc) {
7070
(void)consumeToken();
7171
ParserResult<TypeRepr> Ty;
7272

73-
if (Tok.isAny(tok::identifier, tok::code_complete, tok::kw_protocol)) {
73+
if (Tok.isAny(tok::identifier, tok::code_complete, tok::kw_protocol, tok::kw_Any)) {
7474
Ty = parseTypeIdentifierOrTypeComposition();
7575
} else if (Tok.is(tok::kw_class)) {
7676
diagnose(Tok, diag::unexpected_class_constraint);

0 commit comments

Comments
 (0)