Skip to content

Commit fca6072

Browse files
authored
Merge pull request #38291 from xedin/rdar-61749633-warning
[MiscDiagnostics] Downgrade plain type use error to a warning for certain positions
2 parents c35330e + 66815f9 commit fca6072

File tree

3 files changed

+52
-12
lines changed

3 files changed

+52
-12
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

test/Constraints/dynamic_lookup.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,20 @@ func testCallAsFunctionAnyObject(_ x: AnyObject) {
433433
x() // expected-error {{cannot call value of non-function type 'AnyObject'}}
434434
x.callAsFunction() // Okay.
435435
}
436+
437+
// Note: In Swift >= 6 mode this would become an error.
438+
func test_dynamic_subscript_accepts_type_name_argument() {
439+
@objc class A {
440+
@objc subscript(a: A.Type) -> Int { get { 42 } }
441+
}
442+
443+
func test(a: AnyObject, optA: AnyObject?) {
444+
let _ = a[A] // expected-warning {{expected member name or constructor call after type name}}
445+
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{16-16=()}}
446+
// expected-note@-2 {{use '.self' to reference the type object}} {{16-16=.self}}
447+
448+
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name}}
449+
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{20-20=()}}
450+
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
451+
}
452+
}

test/Constraints/subscript.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,19 @@ func rdar61084565() {
217217
a[] // expected-error {{value of type 'Foo' has no subscripts}}
218218
}
219219

220+
// Note: In Swift >= 6 mode this would become an error.
220221
func test_subscript_accepts_type_name_argument() {
221222
struct A {
222223
subscript(a: A.Type) -> Int { get { 42 } }
223224
}
224225

225-
func test(a: A?) {
226-
let _ = a?[A] // expected-error {{expected member name or constructor call after type name}}
227-
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{17-17=()}}
228-
// expected-note@-2 {{use '.self' to reference the type object}} {{17-17=.self}}
226+
func test(a: A, optA: A?) {
227+
let _ = a[A] // expected-warning {{expected member name or constructor call after type name}}
228+
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{16-16=()}}
229+
// expected-note@-2 {{use '.self' to reference the type object}} {{16-16=.self}}
230+
231+
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name}}
232+
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{20-20=()}}
233+
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
229234
}
230235
}

0 commit comments

Comments
 (0)