@@ -77,7 +77,9 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
7777 SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedBitCasts;
7878
7979 // / 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;
8183
8284 bool IsExprStmt;
8385
@@ -141,30 +143,30 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
141143 checkUseOfMetaTypeName (Base);
142144
143145 if (auto *OLE = dyn_cast<ObjectLiteralExpr>(E)) {
144- CallArgs.insert (OLE->getArg ());
146+ CallArgs.insert ({ OLE->getArg (), E} );
145147 }
146148
147149 if (auto *SE = dyn_cast<SubscriptExpr>(E))
148- CallArgs.insert (SE->getIndex ());
150+ CallArgs.insert ({ SE->getIndex (), E} );
149151
150152 if (auto *DSE = dyn_cast<DynamicSubscriptExpr>(E))
151- CallArgs.insert (DSE->getIndex ());
153+ CallArgs.insert ({ DSE->getIndex (), E} );
152154
153155 if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
154156 // raise an error if this KeyPath contains an effectful member.
155157 checkForEffectfulKeyPath (KPE);
156158
157159 for (auto Comp : KPE->getComponents ()) {
158160 if (auto *Arg = Comp.getIndexExpr ())
159- CallArgs.insert (Arg);
161+ CallArgs.insert ({ Arg, E} );
160162 }
161163 }
162164
163165 // Check function calls, looking through implicit conversions on the
164166 // function and inspecting the arguments directly.
165167 if (auto *Call = dyn_cast<ApplyExpr>(E)) {
166168 // Record call arguments.
167- CallArgs.insert (Call->getArg ());
169+ CallArgs.insert ({ Call->getArg (), E} );
168170
169171 // Warn about surprising implicit optional promotions.
170172 checkOptionalPromotions (Call);
@@ -613,6 +615,11 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
613615 if (!AlreadyDiagnosedMetatypes.insert (E).second )
614616 return ;
615617
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+
616623 // Allow references to types as a part of:
617624 // - member references T.foo, T.Type, T.self, etc.
618625 // - constructor calls T()
@@ -632,11 +639,22 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
632639 isa<SubscriptExpr>(ParentExpr)) {
633640 return ;
634641 }
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+ }
635653 }
636654
637655 // 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 );
640658
641659 // Add fix-it to insert '()', only if this is a metatype of
642660 // non-existential type and has any initializers.
0 commit comments