|
19 | 19 | #include "TypeCheckConcurrency.h"
|
20 | 20 | #include "TypeChecker.h"
|
21 | 21 | #include "swift/AST/ASTWalker.h"
|
| 22 | +#include "swift/AST/ExistentialLayout.h" |
22 | 23 | #include "swift/AST/NameLookup.h"
|
23 | 24 | #include "swift/AST/NameLookupRequests.h"
|
24 | 25 | #include "swift/AST/Pattern.h"
|
@@ -65,6 +66,7 @@ static Expr *isImplicitPromotionToOptional(Expr *E) {
|
65 | 66 | /// - Warn about promotions to optional in specific syntactic forms.
|
66 | 67 | /// - Error about collection literals that default to Any collections in
|
67 | 68 | /// invalid positions.
|
| 69 | +/// - Marker protocols cannot occur as the type of an as? or is expression. |
68 | 70 | ///
|
69 | 71 | static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
70 | 72 | bool isExprStmt) {
|
@@ -311,9 +313,31 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
|
311 | 313 | }
|
312 | 314 | }
|
313 | 315 |
|
| 316 | + // Diagnose checked casts that involve marker protocols. |
| 317 | + if (auto cast = dyn_cast<CheckedCastExpr>(E)) { |
| 318 | + checkCheckedCastExpr(cast); |
| 319 | + } |
| 320 | + |
314 | 321 | return { true, E };
|
315 | 322 | }
|
316 | 323 |
|
| 324 | + void checkCheckedCastExpr(CheckedCastExpr *cast) { |
| 325 | + if (!isa<ConditionalCheckedCastExpr>(cast) && !isa<IsExpr>(cast)) |
| 326 | + return; |
| 327 | + |
| 328 | + Type castType = cast->getCastType(); |
| 329 | + if (!castType || !castType->isExistentialType()) |
| 330 | + return; |
| 331 | + |
| 332 | + auto layout = castType->getExistentialLayout(); |
| 333 | + for (auto proto : layout.getProtocols()) { |
| 334 | + if (proto->getDecl()->isMarkerProtocol()) { |
| 335 | + Ctx.Diags.diagnose(cast->getLoc(), diag::marker_protocol_cast, |
| 336 | + proto->getDecl()->getName()); |
| 337 | + } |
| 338 | + } |
| 339 | + } |
| 340 | + |
317 | 341 | /// Visit the argument/s represented by either a ParenExpr or TupleExpr,
|
318 | 342 | /// unshuffling if needed. If any other kind of expression, will pass it
|
319 | 343 | /// straight back.
|
|
0 commit comments