Skip to content

Commit 4d2b2f6

Browse files
committed
Sema: Allow member type expressions rooted on non-identifier qualifiers to omit .self until Swift 6
1 parent 75c1b6e commit 4d2b2f6

File tree

5 files changed

+51
-9
lines changed

5 files changed

+51
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4188,7 +4188,8 @@ ERROR(value_of_module_type,none,
41884188
"expected module member name after module name", ())
41894189

41904190
ERROR(value_of_metatype_type,none,
4191-
"expected member name or constructor call after type name", ())
4191+
"expected member name or constructor call after type name%select{|; this "
4192+
"will be an error in Swift 6}0", (bool))
41924193

41934194
NOTE(add_parens_to_type,none,
41944195
"add arguments after the type to construct a value of the type", ())

lib/Sema/MiscDiagnostics.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -701,15 +701,17 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
701701
if (!AlreadyDiagnosedMetatypes.insert(E).second)
702702
return;
703703

704-
// In Swift < 6 warn about plain type name passed as an
705-
// argument to a subscript, dynamic subscript, or ObjC
706-
// literal since it used to be accepted.
707704
DiagnosticBehavior behavior = DiagnosticBehavior::Error;
708705

709706
if (auto *ParentExpr = Parent.getAsExpr()) {
710707
if (ParentExpr->isValidParentOfTypeExpr(E))
711708
return;
712709

710+
// In Swift < 6 warn about
711+
// - plain type name passed as an argument to a subscript, dynamic
712+
// subscript, or ObjC literal since it used to be accepted.
713+
// - member type expressions rooted on non-identifier types, e.g.
714+
// '[X].Y' since they used to be accepted without the '.self'.
713715
if (!Ctx.LangOpts.isSwiftVersionAtLeast(6)) {
714716
if (isa<SubscriptExpr>(ParentExpr) ||
715717
isa<DynamicSubscriptExpr>(ParentExpr) ||
@@ -718,12 +720,21 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
718720
assert(argList);
719721
if (argList->isUnlabeledUnary())
720722
behavior = DiagnosticBehavior::Warning;
723+
} else if (auto *TE = dyn_cast<TypeExpr>(E)) {
724+
if (auto *TR =
725+
dyn_cast_or_null<MemberTypeRepr>(TE->getTypeRepr())) {
726+
if (!isa<IdentTypeRepr>(TR->getBaseComponent())) {
727+
behavior = DiagnosticBehavior::Warning;
728+
}
729+
}
721730
}
722731
}
723732
}
724733

725734
// Is this a protocol metatype?
726-
Ctx.Diags.diagnose(E->getStartLoc(), diag::value_of_metatype_type)
735+
Ctx.Diags
736+
.diagnose(E->getStartLoc(), diag::value_of_metatype_type,
737+
behavior == DiagnosticBehavior::Warning)
727738
.limitBehavior(behavior);
728739

729740
// Add fix-it to insert '()', only if this is a metatype of

test/Constraints/dynamic_lookup.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,11 @@ func test_dynamic_subscript_accepts_type_name_argument() {
454454
}
455455

456456
func test(a: AnyObject, optA: AnyObject?) {
457-
let _ = a[A] // expected-warning {{expected member name or constructor call after type name}}
457+
let _ = a[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
458458
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{16-16=()}}
459459
// expected-note@-2 {{use '.self' to reference the type object}} {{16-16=.self}}
460460

461-
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name}}
461+
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
462462
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{20-20=()}}
463463
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
464464
}

test/Constraints/subscript.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ func test_subscript_accepts_type_name_argument() {
230230
}
231231

232232
func test(a: A, optA: A?) {
233-
let _ = a[A] // expected-warning {{expected member name or constructor call after type name}}
233+
let _ = a[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
234234
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{16-16=()}}
235235
// expected-note@-2 {{use '.self' to reference the type object}} {{16-16=.self}}
236236

237-
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name}}
237+
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
238238
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{20-20=()}}
239239
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
240240
}

test/type/nested_types.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,33 @@ do {
8484
let _: (Int, Int).Undef // expected-error {{'Undef' is not a member type of type '(Swift.Int, Swift.Int)'}}
8585
let _: ((Int) -> Void).Undef // expected-error {{'Undef' is not a member type of type '(Swift.Int) -> Swift.Void'}}
8686
}
87+
88+
// Accept member type expressions rooted on 'Self' or non-identifier qualifiers
89+
// until Swift 6.
90+
do {
91+
struct Test {
92+
enum E {}
93+
94+
func blackHole<T>(_: T.Type) {}
95+
96+
func test() {
97+
blackHole(Self.E)
98+
// expected-warning@-1 {{expected member name or constructor call after type name; this will be an error in Swift 6}}
99+
// expected-note@-2 {{use '.self' to reference the type object}}
100+
blackHole((Test).E)
101+
// expected-warning@-1 {{expected member name or constructor call after type name; this will be an error in Swift 6}}
102+
// expected-note@-2 {{use '.self' to reference the type object}}
103+
blackHole([Test].Element)
104+
// expected-warning@-1 {{expected member name or constructor call after type name; this will be an error in Swift 6}}
105+
// expected-note@-2 {{use '.self' to reference the type object}}
106+
// expected-note@-3 {{add arguments after the type to construct a value of the type}}
107+
blackHole([Int : Test].Element)
108+
// expected-warning@-1 {{expected member name or constructor call after type name; this will be an error in Swift 6}}
109+
// expected-note@-2 {{use '.self' to reference the type object}}
110+
blackHole(Test?.Wrapped)
111+
// expected-warning@-1 {{expected member name or constructor call after type name; this will be an error in Swift 6}}
112+
// expected-note@-2 {{use '.self' to reference the type object}}
113+
// expected-note@-3 {{add arguments after the type to construct a value of the type}}
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)