Skip to content

Commit aa565f5

Browse files
committed
[CSApply] Compare variable's type with the base type of the enum we're assigning to
1 parent 25e1bb5 commit aa565f5

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

lib/Sema/CSApply.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,13 +2476,17 @@ namespace {
24762476
memberName,
24772477
defaultMemberLookupOptions);
24782478

2479-
// Filter out any functions or instance members
2479+
// Filter out any functions, instance members or enum cases with
2480+
// associated values.
24802481
results.filter([](const LookupResultEntry entry, bool isOuter) {
24812482
if (auto member = entry.getValueDecl()) {
24822483
if (isa<FuncDecl>(member))
24832484
return false;
24842485
if (member->isInstanceMember())
24852486
return false;
2487+
if (auto EED = dyn_cast<EnumElementDecl>(member)) {
2488+
return !EED->hasAssociatedValues();
2489+
}
24862490
}
24872491

24882492
return true;
@@ -2493,20 +2497,13 @@ namespace {
24932497
}
24942498

24952499
if (auto member = results.front().getValueDecl()) {
2496-
// If we have something like 'static let none = 1', then ignore.
2500+
// If this is a variable whose type does not match the base type
2501+
// of the target then ignore it.
24972502
if (auto VD = dyn_cast<VarDecl>(member)) {
2498-
if (!VD->getInterfaceType()->isEqual(
2499-
baseTyNominalDecl->getDeclaredInterfaceType()))
2503+
auto baseType = DSCE->getType()->lookThroughAllOptionalTypes();
2504+
if (!VD->getInterfaceType()->isEqual(baseType))
25002505
return;
25012506
}
2502-
2503-
// Return if the member is an enum case w/ assoc values, as we only
2504-
// care (for now) about cases with no assoc values (like none)
2505-
if (auto EED = dyn_cast<EnumElementDecl>(member)) {
2506-
if (EED->hasAssociatedValues()) {
2507-
return;
2508-
}
2509-
}
25102507

25112508
// Emit a diagnostic with some fixits
25122509
auto baseTyName = baseTy->getCanonicalType().getString();

test/decl/enum/enumtest.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,29 @@ let _: EnumWithStaticNone4? = .none // expected-warning {{assuming you mean 'Opt
497497

498498
let _: EnumWithStaticFuncNone1? = .none // Okay
499499
let _: EnumWithStaticFuncNone2? = .none // Okay
500+
501+
/// Make sure we diagnose generic ones as well including conditional ones ///
502+
503+
enum GenericEnumWithStaticNone<T> {
504+
case a
505+
static var none: GenericEnumWithStaticNone<Int> { .a }
506+
}
507+
508+
let _: GenericEnumWithStaticNone<Int>? = .none // expected-warning {{assuming you mean 'Optional<GenericEnumWithStaticNone<Int>>.none'; did you mean 'GenericEnumWithStaticNone<Int>.none' instead?}}
509+
// expected-note@-1 {{explicitly specify 'Optional' to silence this warning}}{{42-42=Optional}}
510+
// expected-note@-2 {{use 'GenericEnumWithStaticNone<Int>.none' instead}}{{42-42=GenericEnumWithStaticNone<Int>}}
511+
let _: GenericEnumWithStaticNone<String>? = .none // Okay
512+
let _: GenericEnumWithStaticNone? = .none // Okay
513+
514+
enum GenericEnumWithoutNone<T> {
515+
case a
516+
}
517+
518+
extension GenericEnumWithoutNone where T == Int {
519+
static var none: GenericEnumWithoutNone<Int> { .a }
520+
}
521+
522+
let _: GenericEnumWithoutNone<Int>? = .none // expected-warning {{assuming you mean 'Optional<GenericEnumWithoutNone<Int>>.none'; did you mean 'GenericEnumWithoutNone<Int>.none' instead?}}
523+
// expected-note@-1 {{explicitly specify 'Optional' to silence this warning}}{{39-39=Optional}}
524+
// expected-note@-2 {{use 'GenericEnumWithoutNone<Int>.none' instead}}{{39-39=GenericEnumWithoutNone<Int>}}
525+
let _: GenericEnumWithoutNone<String>? = .none // Okay

0 commit comments

Comments
 (0)