@@ -77,7 +77,9 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
77
77
SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedBitCasts;
78
78
79
79
// / Keep track of the arguments to CallExprs.
80
- SmallPtrSet<Expr *, 2 > CallArgs;
80
+ // / Key -> an argument expression,
81
+ // / Value -> a call argument is associated with.
82
+ llvm::SmallDenseMap<Expr *, Expr *, 2 > CallArgs;
81
83
82
84
bool IsExprStmt;
83
85
@@ -141,30 +143,30 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
141
143
checkUseOfMetaTypeName (Base);
142
144
143
145
if (auto *OLE = dyn_cast<ObjectLiteralExpr>(E)) {
144
- CallArgs.insert (OLE->getArg ());
146
+ CallArgs.insert ({ OLE->getArg (), E} );
145
147
}
146
148
147
149
if (auto *SE = dyn_cast<SubscriptExpr>(E))
148
- CallArgs.insert (SE->getIndex ());
150
+ CallArgs.insert ({ SE->getIndex (), E} );
149
151
150
152
if (auto *DSE = dyn_cast<DynamicSubscriptExpr>(E))
151
- CallArgs.insert (DSE->getIndex ());
153
+ CallArgs.insert ({ DSE->getIndex (), E} );
152
154
153
155
if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
154
156
// raise an error if this KeyPath contains an effectful member.
155
157
checkForEffectfulKeyPath (KPE);
156
158
157
159
for (auto Comp : KPE->getComponents ()) {
158
160
if (auto *Arg = Comp.getIndexExpr ())
159
- CallArgs.insert (Arg);
161
+ CallArgs.insert ({ Arg, E} );
160
162
}
161
163
}
162
164
163
165
// Check function calls, looking through implicit conversions on the
164
166
// function and inspecting the arguments directly.
165
167
if (auto *Call = dyn_cast<ApplyExpr>(E)) {
166
168
// Record call arguments.
167
- CallArgs.insert (Call->getArg ());
169
+ CallArgs.insert ({ Call->getArg (), E} );
168
170
169
171
// Warn about surprising implicit optional promotions.
170
172
checkOptionalPromotions (Call);
@@ -613,6 +615,11 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
613
615
if (!AlreadyDiagnosedMetatypes.insert (E).second )
614
616
return ;
615
617
618
+ // In Swift < 6 warn about plain type name passed as an
619
+ // argument to a subscript, dynamic subscript, or ObjC
620
+ // literal since it used to be accepted.
621
+ DiagnosticBehavior behavior = DiagnosticBehavior::Error;
622
+
616
623
// Allow references to types as a part of:
617
624
// - member references T.foo, T.Type, T.self, etc.
618
625
// - constructor calls T()
@@ -632,11 +639,22 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
632
639
isa<SubscriptExpr>(ParentExpr)) {
633
640
return ;
634
641
}
642
+
643
+ if (!Ctx.LangOpts .isSwiftVersionAtLeast (6 )) {
644
+ auto argument = CallArgs.find (ParentExpr);
645
+ if (argument != CallArgs.end ()) {
646
+ auto *callExpr = argument->second ;
647
+ if (isa<SubscriptExpr>(callExpr) ||
648
+ isa<DynamicSubscriptExpr>(callExpr) ||
649
+ isa<ObjectLiteralExpr>(callExpr))
650
+ behavior = DiagnosticBehavior::Warning;
651
+ }
652
+ }
635
653
}
636
654
637
655
// Is this a protocol metatype?
638
-
639
- Ctx. Diags . diagnose (E-> getStartLoc (), diag::value_of_metatype_type );
656
+ Ctx. Diags . diagnose (E-> getStartLoc (), diag::value_of_metatype_type)
657
+ . limitBehavior (behavior );
640
658
641
659
// Add fix-it to insert '()', only if this is a metatype of
642
660
// non-existential type and has any initializers.
0 commit comments