Skip to content

Commit a3fe65d

Browse files
committed
[CSFix] Suppress ambiguity warning about non-Optional base with static member lookup
Disable non-Optional "assumption" warning for ambiguities related to a static member lookup in generic context because it's possible to declare a member with the same name on a concrete type and in an extension of a protocol that type conforms to e.g.: ```swift struct S : P { static var test: S { ... } extension P where Self == S { static var test: { ... } } ``` And use that in an optional context e.g. passing `.test` to a parameter of expecting `S?`. Resolves: rdar://77700261
1 parent 6f44ba4 commit a3fe65d

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/Sema/CSFix.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,26 @@ SpecifyBaseTypeForOptionalUnresolvedMember::attempt(
18961896
if (memberDecl->isInstanceMember())
18971897
continue;
18981898

1899+
// Disable this warning for ambiguities related to a
1900+
// static member lookup in generic context because it's
1901+
// possible to declare a member with the same name on
1902+
// a concrete type and in an extension of a protocol
1903+
// that type conforms to e.g.:
1904+
//
1905+
// struct S : P { static var test: S { ... }
1906+
//
1907+
// extension P where Self == S { static var test: { ... } }
1908+
//
1909+
// And use that in an optional context e.g. passing `.test`
1910+
// to a parameter of expecting `S?`.
1911+
if (auto *extension =
1912+
dyn_cast<ExtensionDecl>(memberDecl->getDeclContext())) {
1913+
if (extension->getSelfProtocolDecl()) {
1914+
allOptionalBase = false;
1915+
break;
1916+
}
1917+
}
1918+
18991919
allOptionalBase &= bool(choice.getBaseType()
19001920
->getMetatypeInstanceType()
19011921
->getOptionalObjectType());

test/Constraints/static_members_on_protocol_in_generic_context.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,20 @@ func test_fixit_with_where_clause() {
299299
func test_assoc<T: TestWithAssoc>(_: T) {}
300300
test_assoc(.intVar) // expected-error {{contextual member reference to static property 'intVar' requires 'Self' constraint in the protocol extension}}
301301
}
302+
303+
// rdar://77700261 - incorrect warning about assuming non-optional base for unresolved member lookup
304+
struct WithShadowedMember : P {}
305+
306+
extension WithShadowedMember {
307+
static var warnTest: WithShadowedMember { get { WithShadowedMember() } }
308+
}
309+
310+
extension P where Self == WithShadowedMember {
311+
static var warnTest: WithShadowedMember { get { fatalError() } }
312+
}
313+
314+
func test_no_warning_about_optional_base() {
315+
func test(_: WithShadowedMember?) {}
316+
317+
test(.warnTest) // Ok and no warning even though the `warnTest` name is shadowed
318+
}

0 commit comments

Comments
 (0)