Skip to content

Commit 3902688

Browse files
Kacper20xedin
authored andcommitted
[Diagnostics] Resolves: SR-5324 Improved diagnostic when instance member of outer type is referenced from nested type (#11609)
* [Diagnostics] Improved error diagnostics when inner type references instance member of outer type Resolves: SR-5324.
1 parent 994a071 commit 3902688

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ ERROR(could_not_use_type_member_on_protocol_metatype,none,
105105
"static member %1 cannot be used on protocol metatype %0",
106106
(Type, DeclName))
107107
ERROR(could_not_use_instance_member_on_type,none,
108-
"instance member %1 cannot be used on type %0",
109-
(Type, DeclName))
108+
"instance member %1"
109+
"%select{| of type %2}3 cannot be used on"
110+
"%select{| instance of nested}3 type %0",
111+
(Type, DeclName, Type, bool))
110112
ERROR(could_not_use_member_on_existential,none,
111113
"member %1 cannot be used on value of protocol type %0; use a generic"
112114
" constraint instead",

lib/Sema/CSDiag.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2698,7 +2698,7 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
26982698
instanceTy, memberName)
26992699
.highlight(baseRange).highlight(nameLoc.getSourceRange());
27002700
return;
2701-
case MemberLookupResult::UR_InstanceMemberOnType:
2701+
case MemberLookupResult::UR_InstanceMemberOnType: {
27022702
// If the base is an implicit self type reference, and we're in a
27032703
// an initializer, then the user wrote something like:
27042704
//
@@ -2744,11 +2744,28 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
27442744
return;
27452745
}
27462746
}
2747-
2748-
diagnose(loc, diag::could_not_use_instance_member_on_type,
2749-
instanceTy, memberName)
2750-
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2747+
2748+
// Check whether the instance member is declared on parent context and if so
2749+
// provide more specialized message.
2750+
auto memberTypeContext = member->getDeclContext()->getInnermostTypeContext();
2751+
auto currentTypeContext = CS.DC->getInnermostTypeContext();
2752+
if (memberTypeContext && currentTypeContext &&
2753+
memberTypeContext->getSemanticDepth() <
2754+
currentTypeContext->getSemanticDepth()) {
2755+
diagnose(loc, diag::could_not_use_instance_member_on_type,
2756+
currentTypeContext->getDeclaredInterfaceType(), memberName,
2757+
memberTypeContext->getDeclaredTypeOfContext(),
2758+
true)
2759+
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2760+
} else {
2761+
diagnose(loc, diag::could_not_use_instance_member_on_type,
2762+
instanceTy, memberName,
2763+
instanceTy,
2764+
false)
2765+
.highlight(baseRange).highlight(nameLoc.getSourceRange());
2766+
}
27512767
return;
2768+
}
27522769

27532770
case MemberLookupResult::UR_TypeMemberOnInstance:
27542771
diagnoseTypeMemberOnInstanceLookup(baseObjTy, baseExpr,
@@ -5027,12 +5044,15 @@ diagnoseInstanceMethodAsCurriedMemberOnType(CalleeCandidateInfo &CCI,
50275044
}
50285045

50295046
// Otherwise, complain about use of instance value on type.
5030-
auto diagnostic = isa<TypeExpr>(baseExpr)
5031-
? diag::instance_member_use_on_type
5032-
: diag::could_not_use_instance_member_on_type;
5033-
5034-
TC.diagnose(UDE->getLoc(), diagnostic, instanceType, UDE->getName())
5047+
if (isa<TypeExpr>(baseExpr)) {
5048+
TC.diagnose(UDE->getLoc(), diag::instance_member_use_on_type,
5049+
instanceType, UDE->getName())
50355050
.highlight(baseExpr->getSourceRange());
5051+
} else {
5052+
TC.diagnose(UDE->getLoc(), diag::could_not_use_instance_member_on_type,
5053+
instanceType, UDE->getName(), instanceType, false)
5054+
.highlight(baseExpr->getSourceRange());
5055+
}
50365056
return true;
50375057
}
50385058
}

test/Constraints/members.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,18 @@ func rdar33914444() {
449449
_ = A.S(e: .e1)
450450
// expected-error@-1 {{type 'A.R<A.S.E>' has no member 'e1'}}
451451
}
452+
453+
// SR-5324: Better diagnostic when instance member of outer type is referenced from nested type
454+
455+
struct Outer {
456+
var outer: Int
457+
458+
struct Inner {
459+
var inner: Int
460+
461+
func sum() -> Int {
462+
return inner + outer
463+
// expected-error@-1 {{instance member 'outer' of type 'Outer' cannot be used on instance of nested type 'Outer.Inner'}}
464+
}
465+
}
466+
}

0 commit comments

Comments
 (0)