Skip to content

Commit 3c87474

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents ffa9166 + fc0ab61 commit 3c87474

File tree

7 files changed

+93
-63
lines changed

7 files changed

+93
-63
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,17 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
738738
instanceTy = MTT->getInstanceType();
739739

740740
if (sameProblem) {
741+
// If the problem is the same for all of the choices, let's
742+
// just pick one which has a declaration.
743+
auto choice = llvm::find_if(
744+
result.UnviableCandidates,
745+
[&](const OverloadChoice &choice) { return choice.isDecl(); });
746+
747+
// This code can't currently diagnose key path application
748+
// related failures.
749+
if (!choice)
750+
return;
751+
741752
switch (firstProblem) {
742753
case MemberLookupResult::UR_LabelMismatch:
743754
case MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember:
@@ -755,7 +766,7 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
755766
? ConstraintLocator::SubscriptMember
756767
: ConstraintLocator::Member;
757768
AllowTypeOrInstanceMemberFailure failure(
758-
nullptr, CS, baseObjTy, memberName,
769+
expr, CS, baseObjTy, choice->getDecl(), memberName,
759770
CS.getConstraintLocator(E, locatorKind));
760771
auto diagnosed = failure.diagnoseAsError();
761772
assert(diagnosed &&
@@ -778,24 +789,27 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
778789
}
779790

780791
case MemberLookupResult::UR_Inaccessible: {
781-
auto decl = result.UnviableCandidates[0].getDecl();
782792
// FIXME: What if the unviable candidates have different levels of access?
783793
//
784794
// If we found an inaccessible member of a protocol extension, it might
785795
// be declared 'public'. This can only happen if the protocol is not
786796
// visible to us, but the conforming type is. In this case, we need to
787797
// clamp the formal access for diagnostics purposes to the formal access
788798
// of the protocol itself.
789-
InaccessibleMemberFailure failure(expr, CS, decl,
799+
InaccessibleMemberFailure failure(expr, CS, choice->getDecl(),
790800
CS.getConstraintLocator(E));
791801
auto diagnosed = failure.diagnoseAsError();
792802
assert(diagnosed && "failed to produce expected diagnostic");
793803
for (auto cand : result.UnviableCandidates) {
794-
auto *choice = cand.getDecl();
804+
if (!cand.isDecl())
805+
continue;
806+
807+
auto *candidate = cand.getDecl();
795808
// failure is going to highlight candidate given to it,
796809
// we just need to handle the rest here.
797-
if (choice != decl)
798-
diagnose(choice, diag::decl_declared_here, choice->getFullName());
810+
if (candidate != choice->getDecl())
811+
diagnose(candidate, diag::decl_declared_here,
812+
candidate->getFullName());
799813
}
800814
return;
801815
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,26 +1974,6 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
19741974
Expr *expr = getParentExpr();
19751975
SourceRange baseRange = expr ? expr->getSourceRange() : SourceRange();
19761976

1977-
auto overload = getOverloadChoiceIfAvailable(locator);
1978-
if (!overload)
1979-
return false;
1980-
1981-
ValueDecl *decl = nullptr;
1982-
1983-
if (!overload->choice.isDecl()) {
1984-
auto baseTy = overload->choice.getBaseType();
1985-
if (auto MT = baseTy->getAs<MetatypeType>()) {
1986-
if (auto VD = dyn_cast<ValueDecl>(
1987-
MT->getMetatypeInstanceType()->getAnyNominal()->getAsDecl())) {
1988-
decl = VD;
1989-
}
1990-
} else {
1991-
return true;
1992-
}
1993-
}
1994-
1995-
auto member = decl ? decl : overload->choice.getDecl();
1996-
19971977
// If the base is an implicit self type reference, and we're in a
19981978
// an initializer, then the user wrote something like:
19991979
//
@@ -2062,7 +2042,7 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
20622042
}
20632043
}
20642044

2065-
if (BaseType->is<AnyMetatypeType>() && !member->isStatic()) {
2045+
if (BaseType->is<AnyMetatypeType>() && !Member->isStatic()) {
20662046
auto instanceTy = BaseType;
20672047

20682048
if (auto *AMT = instanceTy->getAs<AnyMetatypeType>()) {
@@ -2117,7 +2097,8 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
21172097

21182098
// Check whether the instance member is declared on parent context and if so
21192099
// provide more specialized message.
2120-
auto memberTypeContext = member->getDeclContext()->getInnermostTypeContext();
2100+
auto memberTypeContext =
2101+
Member->getDeclContext()->getInnermostTypeContext();
21212102
auto currentTypeContext = cs.DC->getInnermostTypeContext();
21222103

21232104
if (memberTypeContext && currentTypeContext &&
@@ -2127,7 +2108,7 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
21272108
currentTypeContext->getDeclaredInterfaceType(), Name,
21282109
memberTypeContext->getDeclaredInterfaceType(), true)
21292110
.highlight(baseRange)
2130-
.highlight(member->getSourceRange());
2111+
.highlight(Member->getSourceRange());
21312112
return true;
21322113
}
21332114

@@ -2164,13 +2145,13 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
21642145
// Give a customized message if we're accessing a member type
21652146
// of a protocol -- otherwise a diagnostic talking about
21662147
// static members doesn't make a whole lot of sense
2167-
if (auto TAD = dyn_cast<TypeAliasDecl>(member)) {
2148+
if (auto TAD = dyn_cast<TypeAliasDecl>(Member)) {
21682149
Diag.emplace(emitDiagnostic(loc, diag::typealias_outside_of_protocol,
21692150
TAD->getName()));
2170-
} else if (auto ATD = dyn_cast<AssociatedTypeDecl>(member)) {
2151+
} else if (auto ATD = dyn_cast<AssociatedTypeDecl>(Member)) {
21712152
Diag.emplace(emitDiagnostic(loc, diag::assoc_type_outside_of_protocol,
21722153
ATD->getName()));
2173-
} else if (isa<ConstructorDecl>(member)) {
2154+
} else if (isa<ConstructorDecl>(Member)) {
21742155
Diag.emplace(emitDiagnostic(loc, diag::construct_protocol_by_name,
21752156
instanceTy));
21762157
} else {
@@ -2200,11 +2181,11 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
22002181
// components, let's provide a tailored diagnostic and return because
22012182
// that is unsupported so there is no fix-it.
22022183
if (locator->isForKeyPathComponent()) {
2203-
InvalidStaticMemberRefInKeyPath failure(expr, cs, member, locator);
2184+
InvalidStaticMemberRefInKeyPath failure(expr, cs, Member, locator);
22042185
return failure.diagnoseAsError();
22052186
}
22062187

2207-
if (isa<EnumElementDecl>(member)) {
2188+
if (isa<EnumElementDecl>(Member)) {
22082189
Diag.emplace(emitDiagnostic(
22092190
loc, diag::could_not_use_enum_element_on_instance, Name));
22102191
} else {
@@ -2232,13 +2213,11 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
22322213
}
22332214

22342215
// Try to provide a fix-it that only contains a '.'
2235-
if (contextualType) {
2236-
if (baseTy->isEqual(contextualType)) {
2237-
Diag->fixItInsert(loc, ".");
2238-
return true;
2239-
}
2216+
if (contextualType && baseTy->isEqual(contextualType)) {
2217+
Diag->fixItInsert(loc, ".");
2218+
return true;
22402219
}
2241-
2220+
22422221
// Check if the expression is the matching operator ~=, most often used in
22432222
// case statements. If so, try to provide a single dot fix-it
22442223
const Expr *contextualTypeNode = nullptr;
@@ -2273,17 +2252,22 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
22732252
}
22742253

22752254
// Fall back to a fix-it with a full type qualifier
2276-
auto nominal = member->getDeclContext()->getSelfNominalTypeDecl();
2277-
SmallString<32> typeName;
2278-
llvm::raw_svector_ostream typeNameStream(typeName);
2279-
typeNameStream << nominal->getSelfInterfaceType() << ".";
2280-
2281-
Diag->fixItInsert(loc, typeNameStream.str());
2255+
if (auto *NTD = Member->getDeclContext()->getSelfNominalTypeDecl()) {
2256+
auto typeName = NTD->getSelfInterfaceType()->getString();
2257+
if (auto *SE = dyn_cast<SubscriptExpr>(getRawAnchor())) {
2258+
auto *baseExpr = SE->getBase();
2259+
Diag->fixItReplace(baseExpr->getSourceRange(), typeName);
2260+
} else {
2261+
Diag->fixItInsert(loc, typeName + ".");
2262+
}
2263+
}
2264+
22822265
return true;
22832266
}
2284-
2267+
22852268
return false;
22862269
}
2270+
22872271
bool PartialApplicationFailure::diagnoseAsError() {
22882272
auto &cs = getConstraintSystem();
22892273
auto *anchor = cast<UnresolvedDotExpr>(getRawAnchor());

lib/Sema/CSDiagnostics.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -807,17 +807,21 @@ class MissingMemberFailure final : public FailureDiagnostic {
807807
/// ```
808808
class AllowTypeOrInstanceMemberFailure final : public FailureDiagnostic {
809809
Type BaseType;
810+
ValueDecl *Member;
810811
DeclName Name;
811812

812813
public:
813814
AllowTypeOrInstanceMemberFailure(Expr *root, ConstraintSystem &cs,
814-
Type baseType, DeclName memberName,
815-
ConstraintLocator *locator)
815+
Type baseType, ValueDecl *member,
816+
DeclName name, ConstraintLocator *locator)
816817
: FailureDiagnostic(root, cs, locator),
817-
BaseType(baseType->getRValueType()), Name(memberName) {}
818+
BaseType(baseType->getRValueType()), Member(member), Name(name) {
819+
assert(member);
820+
}
818821

819822
bool diagnoseAsError() override;
820823
};
824+
821825
class PartialApplicationFailure final : public FailureDiagnostic {
822826
enum RefKind : unsigned {
823827
MutatingMethod,

lib/Sema/CSFix.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,19 @@ DefineMemberBasedOnUse::create(ConstraintSystem &cs, Type baseType,
284284
}
285285

286286
bool AllowTypeOrInstanceMember::diagnose(Expr *root, bool asNote) const {
287-
auto failure = AllowTypeOrInstanceMemberFailure(root, getConstraintSystem(),
288-
BaseType, Name, getLocator());
287+
auto failure = AllowTypeOrInstanceMemberFailure(
288+
root, getConstraintSystem(), BaseType, Member, UsedName, getLocator());
289289
return failure.diagnose(asNote);
290290
}
291291

292-
AllowTypeOrInstanceMember *AllowTypeOrInstanceMember::create(ConstraintSystem &cs,
293-
Type baseType,
294-
DeclName member,
295-
ConstraintLocator *locator) {
296-
return new (cs.getAllocator()) AllowTypeOrInstanceMember(cs, baseType, member, locator);
292+
AllowTypeOrInstanceMember *
293+
AllowTypeOrInstanceMember::create(ConstraintSystem &cs, Type baseType,
294+
ValueDecl *member, DeclName usedName,
295+
ConstraintLocator *locator) {
296+
return new (cs.getAllocator())
297+
AllowTypeOrInstanceMember(cs, baseType, member, usedName, locator);
297298
}
299+
298300
bool AllowInvalidPartialApplication::diagnose(Expr *root, bool asNote) const {
299301
auto failure = PartialApplicationFailure(root, isWarning(),
300302
getConstraintSystem(), getLocator());

lib/Sema/CSFix.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,13 +595,17 @@ class DefineMemberBasedOnUse final : public ConstraintFix {
595595

596596
class AllowTypeOrInstanceMember final : public ConstraintFix {
597597
Type BaseType;
598-
DeclName Name;
598+
ValueDecl *Member;
599+
DeclName UsedName;
599600

600601
public:
601-
AllowTypeOrInstanceMember(ConstraintSystem &cs, Type baseType, DeclName member,
602+
AllowTypeOrInstanceMember(ConstraintSystem &cs, Type baseType,
603+
ValueDecl *member, DeclName name,
602604
ConstraintLocator *locator)
603605
: ConstraintFix(cs, FixKind::AllowTypeOrInstanceMember, locator),
604-
BaseType(baseType), Name(member) {}
606+
BaseType(baseType), Member(member), UsedName(name) {
607+
assert(member);
608+
}
605609

606610
std::string getName() const override {
607611
return "allow access to instance member on type or a type member on instance";
@@ -610,7 +614,7 @@ class AllowTypeOrInstanceMember final : public ConstraintFix {
610614
bool diagnose(Expr *root, bool asNote = false) const override;
611615

612616
static AllowTypeOrInstanceMember *create(ConstraintSystem &cs, Type baseType,
613-
DeclName member,
617+
ValueDecl *member, DeclName usedName,
614618
ConstraintLocator *locator);
615619
};
616620

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4530,8 +4530,12 @@ fixMemberRef(ConstraintSystem &cs, Type baseTy,
45304530
if (reason) {
45314531
switch (*reason) {
45324532
case MemberLookupResult::UR_InstanceMemberOnType:
4533-
case MemberLookupResult::UR_TypeMemberOnInstance:
4534-
return AllowTypeOrInstanceMember::create(cs, baseTy, memberName, locator);
4533+
case MemberLookupResult::UR_TypeMemberOnInstance: {
4534+
return choice.isDecl()
4535+
? AllowTypeOrInstanceMember::create(
4536+
cs, baseTy, choice.getDecl(), memberName, locator)
4537+
: nullptr;
4538+
}
45354539

45364540
case MemberLookupResult::UR_Inaccessible:
45374541
assert(choice.isDecl());

test/Constraints/members.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,21 @@ func rdar50679161() {
609609
}
610610
}
611611
}
612+
613+
614+
func rdar_50467583_and_50909555() {
615+
// rdar://problem/50467583
616+
let _: Set = [Int][]
617+
// expected-error@-1 {{instance member 'subscript' cannot be used on type '[Int]'}}
618+
619+
// rdar://problem/50909555
620+
struct S {
621+
static subscript(x: Int, y: Int) -> Int {
622+
return 1
623+
}
624+
}
625+
626+
func test(_ s: S) {
627+
s[1] // expected-error {{static member 'subscript' cannot be used on instance of type 'S'}} {{5-6=S}}
628+
}
629+
}

0 commit comments

Comments
 (0)