Skip to content

Commit 49796c9

Browse files
authored
Merge pull request swiftlang#60145 from slavapestov/fix-rdar72407668-5.7
Sema: Don't allow opaque return types to reference DynamicSelfType [5.7]
2 parents 94b477f + 9605ec6 commit 49796c9

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4244,6 +4244,9 @@ NOTE(opaque_type_underlying_type_candidate_here,none,
42444244
ERROR(opaque_type_self_referential_underlying_type,none,
42454245
"function opaque return type was inferred as %0, which defines the "
42464246
"opaque type in terms of itself", (Type))
4247+
ERROR(opaque_type_cannot_contain_dynamic_self,none,
4248+
"function with opaque return type cannot return "
4249+
"the covariant 'Self' type of a class", ())
42474250
ERROR(opaque_type_var_no_init,none,
42484251
"property declares an opaque return type, but has no initializer "
42494252
"expression from which to infer an underlying type", ())

lib/Sema/MiscDiagnostics.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,20 +2815,26 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
28152815

28162816
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
28172817
if (auto underlyingToOpaque = dyn_cast<UnderlyingToOpaqueExpr>(E)) {
2818-
auto key =
2819-
underlyingToOpaque->substitutions.getCanonical().getOpaqueValue();
2818+
auto subMap = underlyingToOpaque->substitutions;
28202819

2820+
auto key = subMap.getCanonical().getOpaqueValue();
28212821
auto isUnique = UniqueSignatures.insert(key).second;
28222822

28232823
auto candidate =
2824-
std::make_tuple(underlyingToOpaque->getSubExpr(),
2825-
underlyingToOpaque->substitutions, isUnique);
2824+
std::make_tuple(underlyingToOpaque->getSubExpr(), subMap, isUnique);
28262825

28272826
if (isSelfReferencing(candidate)) {
28282827
HasInvalidReturn = true;
28292828
return {false, nullptr};
28302829
}
28312830

2831+
if (subMap.hasDynamicSelf()) {
2832+
Ctx.Diags.diagnose(E->getLoc(),
2833+
diag::opaque_type_cannot_contain_dynamic_self);
2834+
HasInvalidReturn = true;
2835+
return {false, nullptr};
2836+
}
2837+
28322838
Candidates.push_back({CurrentAvailability, candidate});
28332839
return {false, E};
28342840
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking
2+
3+
protocol P {
4+
init()
5+
}
6+
7+
extension P {
8+
static func opaqueProtocolExtensionFunc() -> some P { return Self() }
9+
}
10+
11+
class C: P {
12+
required init() {}
13+
14+
static func opaqueFunc1() -> some P {
15+
return Self()
16+
// expected-error@-1 {{function with opaque return type cannot return the covariant 'Self' type of a class}}
17+
}
18+
19+
static func opaqueFunc2() -> some P {
20+
return Self.opaqueProtocolExtensionFunc()
21+
// expected-error@-1 {{function with opaque return type cannot return the covariant 'Self' type of a class}}
22+
}
23+
24+
var opaqueProperty: some P {
25+
return Self()
26+
// expected-error@-1 {{function with opaque return type cannot return the covariant 'Self' type of a class}}
27+
}
28+
29+
subscript() -> some P {
30+
return Self()
31+
// expected-error@-1 {{function with opaque return type cannot return the covariant 'Self' type of a class}}
32+
}
33+
34+
var opaqueStoredProperty: some P = Self()
35+
// expected-error@-1 {{covariant 'Self' type cannot be referenced from a stored property initializer}}
36+
}

0 commit comments

Comments
 (0)