Skip to content

Commit 8d4b1cc

Browse files
authored
Merge pull request #3888 from CodaFi/some-type-of-wei
Finish up SE-0096
2 parents 4492e7c + 8d23005 commit 8d4b1cc

31 files changed

+214
-189
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ ERROR(expr_typeof_expected_expr,PointsToFirstBadToken,
11141114
"expected an expression within 'type(of: ...)'", ())
11151115
ERROR(expr_typeof_expected_rparen,PointsToFirstBadToken,
11161116
"expected ')' to complete 'type(of: ...)' expression", ())
1117-
WARNING(expr_dynamictype_deprecated,PointsToFirstBadToken,
1117+
ERROR(expr_dynamictype_deprecated,PointsToFirstBadToken,
11181118
"'.dynamicType' is deprecated. Use 'type(of: ...)' instead", ())
11191119

11201120
//------------------------------------------------------------------------------

include/swift/Parse/Tokens.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ KEYWORD(__COLUMN__)
147147
KEYWORD(__FUNCTION__)
148148
KEYWORD(__DSO_HANDLE__)
149149

150-
// FIXME(SE-0096): REMOVE ME
151-
KEYWORD(dynamicType)
152-
153150
// Pattern keywords.
154151
KEYWORD(_)
155152

lib/Basic/StringExtras.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ bool swift::canBeArgumentLabel(StringRef identifier) {
3636

3737
bool swift::canBeMemberName(StringRef identifier) {
3838
return llvm::StringSwitch<bool>(identifier)
39-
.Case("dynamicType", false)
4039
.Case("init", false)
4140
.Case("Protocol", false)
4241
.Case("self", false)

lib/Parse/ParseExpr.cpp

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,32 @@ getMagicIdentifierLiteralKind(tok Kind) {
950950
}
951951
}
952952

953+
/// See if type(of: <expr>) can be parsed backtracking on failure.
954+
static bool canParseTypeOf(Parser &P) {
955+
if (!(P.Tok.getText() == "type" && P.peekToken().is(tok::l_paren))) {
956+
return false;
957+
}
958+
// Look ahead to parse the parenthesized expression.
959+
Parser::BacktrackingScope Backtrack(P);
960+
P.consumeToken(tok::identifier);
961+
P.consumeToken(tok::l_paren);
962+
// The first argument label must be 'of'.
963+
if (!(P.Tok.getText() == "of" && P.peekToken().is(tok::colon))) {
964+
return false;
965+
}
966+
967+
// Parse to the closing paren.
968+
while (!P.Tok.is(tok::r_paren) && !P.Tok.is(tok::eof)) {
969+
// Anything that looks like another argument label is bogus. It is
970+
// sufficient to parse for a single trailing comma. Backtracking will
971+
// fall back to an unresolved decl.
972+
if (P.Tok.is(tok::comma)) {
973+
return false;
974+
}
975+
P.skipSingle();
976+
}
977+
return true;
978+
}
953979

954980
/// parseExprPostfix
955981
///
@@ -1095,8 +1121,8 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
10951121
}
10961122

10971123
case tok::identifier: // foo
1098-
// If starts with 'type(', parse the 'type(of: ...)' metatype expression
1099-
if (Tok.getText() == "type" && peekToken().is(tok::l_paren)) {
1124+
// Attempt to parse for 'type(of: <expr>)'.
1125+
if (canParseTypeOf(*this)) {
11001126
Result = parseExprTypeOf();
11011127
break;
11021128
}
@@ -1418,35 +1444,25 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
14181444
continue;
14191445
}
14201446

1421-
// Handle "x.dynamicType" - A metatype expr.
1422-
// Deprecated in SE-0096: `x.dynamicType` becomes `type(of: x)`
1423-
//
1424-
// FIXME(SE-0096): This will go away along with the keyword soon.
1425-
if (Tok.is(tok::kw_dynamicType)) {
1426-
// Fix-it
1447+
// Handle "x.self" expr.
1448+
if (Tok.is(tok::kw_self)) {
1449+
Result = makeParserResult(
1450+
new (Context) DotSelfExpr(Result.get(), TokLoc, consumeToken()));
1451+
continue;
1452+
}
1453+
1454+
// Handle the deprecated 'x.dynamicType' and migrate it to `type(of: x)`
1455+
if (Tok.getText() == "dynamicType") {
1456+
BacktrackingScope backtrackScope(*this);
14271457
auto range = Result.get()->getSourceRange();
14281458
auto dynamicTypeExprRange = SourceRange(TokLoc, consumeToken());
14291459
diagnose(TokLoc, diag::expr_dynamictype_deprecated)
14301460
.highlight(dynamicTypeExprRange)
14311461
.fixItReplace(dynamicTypeExprRange, ")")
14321462
.fixItInsert(range.Start, "type(of: ");
14331463

1434-
// HACK: Arbitrary.
1435-
auto loc = range.Start;
1436-
auto dt = new (Context) DynamicTypeExpr(loc, loc, Result.get(), loc, Type());
1437-
dt->setImplicit();
1438-
Result = makeParserResult(dt);
1439-
continue;
1464+
// fallthrough to an UnresolvedDotExpr.
14401465
}
1441-
1442-
1443-
// Handle "x.self" expr.
1444-
if (Tok.is(tok::kw_self)) {
1445-
Result = makeParserResult(
1446-
new (Context) DotSelfExpr(Result.get(), TokLoc, consumeToken()));
1447-
continue;
1448-
}
1449-
14501466

14511467
// If we have '.<keyword><code_complete>', try to recover by creating
14521468
// an identifier with the same spelling as the keyword.
@@ -3030,26 +3046,14 @@ ParserResult<Expr> Parser::parseExprTypeOf() {
30303046
SourceLoc lParenLoc = consumeToken(tok::l_paren);
30313047

30323048
// Parse `of` label.
3033-
auto ofRange = Tok.getRange();
3034-
if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) {
3035-
bool hasOf = Tok.getText() == "of";
3036-
if (!hasOf) {
3037-
// User mis-spelled the 'of' label.
3038-
diagnose(Tok, diag::expr_typeof_expected_label_of)
3039-
.fixItReplace({ ofRange.getStart(), ofRange.getEnd() }, "of");
3040-
}
3041-
3042-
// Consume either 'of' or the misspelling.
3049+
if (Tok.getText() == "of" && peekToken().is(tok::colon)) {
3050+
// Consume the label.
30433051
consumeToken();
30443052
consumeToken(tok::colon);
3045-
3046-
if (!hasOf) {
3047-
return makeParserError();
3048-
}
30493053
} else {
3050-
// No label at all; insert it.
3051-
diagnose(Tok, diag::expr_typeof_expected_label_of)
3052-
.fixItInsert(ofRange.getStart(), "of: ");
3054+
// There cannot be a richer diagnostic here because the user may have
3055+
// defined a function `type(...)` that conflicts with the magic expr.
3056+
diagnose(Tok, diag::expr_typeof_expected_label_of);
30533057
}
30543058

30553059
// Parse the subexpression.

lib/Parse/ParseType.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
7878
consumeToken(tok::code_complete);
7979
return makeParserCodeCompletionResult<TypeRepr>();
8080
case tok::kw_super:
81-
case tok::kw_dynamicType:
8281
case tok::kw_self:
8382
// These keywords don't start a decl or a statement, and thus should be
8483
// safe to skip over.

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ collectClassSelfUses(SILValue ClassPointer, SILType MemorySILType,
12401240
if (isSelfInitUse(VMI))
12411241
Kind = DIUseKind::SelfInit;
12421242
else
1243-
// Otherwise, this is a simple reference to "dynamicType", which is
1243+
// Otherwise, this is a simple reference to "type(of:)", which is
12441244
// always fine, even if self is uninitialized.
12451245
continue;
12461246
}
@@ -1386,7 +1386,7 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() {
13861386
if (isSelfInitUse(VMI))
13871387
Kind = DIUseKind::SelfInit;
13881388
else
1389-
// Otherwise, this is a simple reference to "dynamicType", which is
1389+
// Otherwise, this is a simple reference to "type(of:)", which is
13901390
// always fine, even if self is uninitialized.
13911391
continue;
13921392
}

test/1_stdlib/TestAffineTransform.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,9 @@ class TestAffineTransform : TestAffineTransformSuper {
337337
AffineTransform(m11: -55.66, m12: 22.7, m21: 1.5, m22: 0.0, tX: -22, tY: -33)
338338
]
339339
let anyHashables = values.map(AnyHashable.init)
340-
expectEqual("AffineTransform", String(describing: anyHashables[0].base.dynamicType))
341-
expectEqual("AffineTransform", String(describing: anyHashables[1].base.dynamicType))
342-
expectEqual("AffineTransform", String(describing: anyHashables[2].base.dynamicType))
340+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[0].base)))
341+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[1].base)))
342+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[2].base)))
343343
expectNotEqual(anyHashables[0], anyHashables[1])
344344
expectEqual(anyHashables[1], anyHashables[2])
345345
}
@@ -356,9 +356,9 @@ class TestAffineTransform : TestAffineTransformSuper {
356356
makeNSAffineTransform(rotatedByDegrees: 10),
357357
]
358358
let anyHashables = values.map(AnyHashable.init)
359-
expectEqual("AffineTransform", String(describing: anyHashables[0].base.dynamicType))
360-
expectEqual("AffineTransform", String(describing: anyHashables[1].base.dynamicType))
361-
expectEqual("AffineTransform", String(describing: anyHashables[2].base.dynamicType))
359+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[0].base)))
360+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[1].base)))
361+
expectEqual("AffineTransform", String(describing: type(of: anyHashables[2].base)))
362362
expectNotEqual(anyHashables[0], anyHashables[1])
363363
expectEqual(anyHashables[1], anyHashables[2])
364364
}

test/1_stdlib/TestCalendar.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,9 @@ class TestCalendar : TestCalendarSuper {
263263
Calendar(identifier: .japanese)
264264
]
265265
let anyHashables = values.map(AnyHashable.init)
266-
expectEqual("Calendar", String(describing: anyHashables[0].base.dynamicType))
267-
expectEqual("Calendar", String(describing: anyHashables[1].base.dynamicType))
268-
expectEqual("Calendar", String(describing: anyHashables[2].base.dynamicType))
266+
expectEqual("Calendar", String(describing: type(of: anyHashables[0].base)))
267+
expectEqual("Calendar", String(describing: type(of: anyHashables[1].base)))
268+
expectEqual("Calendar", String(describing: type(of: anyHashables[2].base)))
269269
expectNotEqual(anyHashables[0], anyHashables[1])
270270
expectEqual(anyHashables[1], anyHashables[2])
271271
}
@@ -278,9 +278,9 @@ class TestCalendar : TestCalendarSuper {
278278
NSCalendar(identifier: .japanese)!,
279279
]
280280
let anyHashables = values.map(AnyHashable.init)
281-
expectEqual("Calendar", String(describing: anyHashables[0].base.dynamicType))
282-
expectEqual("Calendar", String(describing: anyHashables[1].base.dynamicType))
283-
expectEqual("Calendar", String(describing: anyHashables[2].base.dynamicType))
281+
expectEqual("Calendar", String(describing: type(of: anyHashables[0].base)))
282+
expectEqual("Calendar", String(describing: type(of: anyHashables[1].base)))
283+
expectEqual("Calendar", String(describing: type(of: anyHashables[2].base)))
284284
expectNotEqual(anyHashables[0], anyHashables[1])
285285
expectEqual(anyHashables[1], anyHashables[2])
286286
}

test/1_stdlib/TestCharacterSet.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ class TestCharacterSet : TestCharacterSetSuper {
160160
CharacterSet(charactersIn: "XYZ")
161161
]
162162
let anyHashables = values.map(AnyHashable.init)
163-
expectEqual("CharacterSet", String(describing: anyHashables[0].base.dynamicType))
164-
expectEqual("CharacterSet", String(describing: anyHashables[1].base.dynamicType))
165-
expectEqual("CharacterSet", String(describing: anyHashables[2].base.dynamicType))
163+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[0].base)))
164+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[1].base)))
165+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[2].base)))
166166
expectNotEqual(anyHashables[0], anyHashables[1])
167167
expectEqual(anyHashables[1], anyHashables[2])
168168
}
@@ -174,9 +174,9 @@ class TestCharacterSet : TestCharacterSetSuper {
174174
NSCharacterSet(charactersIn: "XYZ"),
175175
]
176176
let anyHashables = values.map(AnyHashable.init)
177-
expectEqual("CharacterSet", String(describing: anyHashables[0].base.dynamicType))
178-
expectEqual("CharacterSet", String(describing: anyHashables[1].base.dynamicType))
179-
expectEqual("CharacterSet", String(describing: anyHashables[2].base.dynamicType))
177+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[0].base)))
178+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[1].base)))
179+
expectEqual("CharacterSet", String(describing: type(of: anyHashables[2].base)))
180180
expectNotEqual(anyHashables[0], anyHashables[1])
181181
expectEqual(anyHashables[1], anyHashables[2])
182182
}

test/1_stdlib/TestData.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -875,9 +875,9 @@ class TestData : TestDataSuper {
875875
Data(base64Encoded: "AAAB")!,
876876
]
877877
let anyHashables = values.map(AnyHashable.init)
878-
expectEqual("Data", String(describing: anyHashables[0].base.dynamicType))
879-
expectEqual("Data", String(describing: anyHashables[1].base.dynamicType))
880-
expectEqual("Data", String(describing: anyHashables[2].base.dynamicType))
878+
expectEqual("Data", String(describing: type(of: anyHashables[0].base)))
879+
expectEqual("Data", String(describing: type(of: anyHashables[1].base)))
880+
expectEqual("Data", String(describing: type(of: anyHashables[2].base)))
881881
expectNotEqual(anyHashables[0], anyHashables[1])
882882
expectEqual(anyHashables[1], anyHashables[2])
883883
}
@@ -889,9 +889,9 @@ class TestData : TestDataSuper {
889889
NSData(base64Encoded: "AAAB")!,
890890
]
891891
let anyHashables = values.map(AnyHashable.init)
892-
expectEqual("Data", String(describing: anyHashables[0].base.dynamicType))
893-
expectEqual("Data", String(describing: anyHashables[1].base.dynamicType))
894-
expectEqual("Data", String(describing: anyHashables[2].base.dynamicType))
892+
expectEqual("Data", String(describing: type(of: anyHashables[0].base)))
893+
expectEqual("Data", String(describing: type(of: anyHashables[1].base)))
894+
expectEqual("Data", String(describing: type(of: anyHashables[2].base)))
895895
expectNotEqual(anyHashables[0], anyHashables[1])
896896
expectEqual(anyHashables[1], anyHashables[2])
897897
}

0 commit comments

Comments
 (0)