Skip to content

Commit 1b6ac2c

Browse files
committed
Sema: Clean up leading dot fix logic in simplifyConformsToConstraint()
Tests still pass without this code, including the tests I just added in the previous commit.
1 parent 8d24710 commit 1b6ac2c

File tree

2 files changed

+34
-38
lines changed

2 files changed

+34
-38
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8859,17 +8859,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
88598859
return SolutionKind::Solved;
88608860
}
88618861

8862-
auto formUnsolved = [&](bool activate = false) {
8862+
auto formUnsolved = [&]() {
88638863
// If we're supposed to generate constraints, do so.
88648864
if (flags.contains(TMF_GenerateConstraints)) {
88658865
auto *conformance = Constraint::create(
88668866
*this, kind, type, protocol->getDeclaredInterfaceType(),
88678867
getConstraintLocator(locator));
88688868

88698869
addUnsolvedConstraint(conformance);
8870-
if (activate)
8871-
activateConstraint(conformance);
8872-
88738870
return SolutionKind::Solved;
88748871
}
88758872

@@ -9243,46 +9240,41 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
92439240

92449241
if (isExpr<UnresolvedMemberExpr>(anchor) &&
92459242
req->is<LocatorPathElt::TypeParameterRequirement>()) {
9243+
auto *memberLoc = getConstraintLocator(anchor, path.front());
9244+
92469245
auto signature = path[path.size() - 2]
92479246
.castTo<LocatorPathElt::OpenedGeneric>()
92489247
.getSignature();
92499248
auto requirement = signature.getRequirements()[req->getIndex()];
92509249

9251-
auto *memberLoc = getConstraintLocator(anchor, path.front());
9252-
auto overload = findSelectedOverloadFor(memberLoc);
9253-
9254-
// To figure out what is going on here we need to wait until
9255-
// member overload is set in the constraint system.
9256-
if (!overload) {
9257-
// If it's not allowed to generate new constraints
9258-
// there is no way to control re-activation, so this
9259-
// check has to fail.
9260-
if (!flags.contains(TMF_GenerateConstraints))
9261-
return SolutionKind::Error;
9250+
auto attemptInvalidStaticMemberRefOnMetatypeFix = [&]() {
9251+
// If the failed requirement isn't the first generic parameter,
9252+
// it can't be a static member reference on a protocol metatype.
9253+
if (!requirement.getFirstType()->isEqual(getASTContext().TheSelfType))
9254+
return false;
92629255

9263-
return formUnsolved(/*activate=*/true);
9264-
}
9256+
// If we don't know the overload yet, conservatively assume it's
9257+
// a static member reference on a protocol metatype.
9258+
auto overload = findSelectedOverloadFor(memberLoc);
9259+
if (!overload)
9260+
return true;
92659261

9266-
auto *memberRef = overload->choice.getDeclOrNull();
9267-
if (!memberRef)
9268-
return SolutionKind::Error;
9262+
auto *decl = overload->choice.getDeclOrNull();
9263+
if (!decl)
9264+
return true;
92699265

9270-
// If this is a `Self` conformance requirement from a static member
9271-
// reference on a protocol metatype, let's produce a tailored diagnostic.
9272-
if (memberRef->isStatic()) {
9273-
if (hasFixFor(memberLoc,
9274-
FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype))
9275-
return SolutionKind::Solved;
9266+
// Otherwise, we can do a precise check.
9267+
if (!decl->isStatic())
9268+
return false;
92769269

9277-
if (auto *protocolDecl =
9278-
memberRef->getDeclContext()->getSelfProtocolDecl()) {
9279-
auto selfTy = protocolDecl->getSelfInterfaceType();
9280-
if (selfTy->isEqual(requirement.getFirstType())) {
9281-
auto *fix = AllowInvalidStaticMemberRefOnProtocolMetatype::create(
9282-
*this, memberLoc);
9283-
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
9284-
}
9285-
}
9270+
return decl->getDeclContext()->getSelfProtocolDecl() != nullptr;
9271+
};
9272+
9273+
if (attemptInvalidStaticMemberRefOnMetatypeFix()) {
9274+
auto *fix = AllowInvalidStaticMemberRefOnProtocolMetatype::create(
9275+
*this, memberLoc);
9276+
9277+
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
92869278
}
92879279
}
92889280

test/Constraints/static_members_on_protocol_in_generic_context.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ test_combo(.genericFn(42)) // expected-error {{global function 'test_combo' requ
177177

178178
extension P { // expected-note 13 {{missing same-type requirement on 'Self'}} {{12-12= where Self == <#Type#>}}
179179
static func generic<T>(_: T) -> T { fatalError() }
180-
static func genericWithReqs<T: Collection, Q>(_: T) -> Q where T.Element == Q { // expected-note {{required by static method 'genericWithReqs' where 'T' = '()'}}
180+
static func genericWithReqs<T: Collection, Q>(_: T) -> Q where T.Element == Q { // expected-note 3 {{required by static method 'genericWithReqs' where 'T' = '()'}}
181181
fatalError()
182182
}
183183
}
@@ -246,7 +246,9 @@ test(.genericWithReqs([S()])) // expected-error {{contextual member reference to
246246
test(.genericWithReqs([42]))
247247
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
248248
test(.genericWithReqs(()))
249-
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
249+
// expected-error@-1 {{type '()' cannot conform to 'Collection'}}
250+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
251+
// expected-error@-3 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
250252

251253
test_combo(.doesntExist) // expected-error {{reference to member 'doesntExist' cannot be resolved without a contextual type}}
252254
test_combo(.doesnt.exist()) // expected-error {{reference to member 'doesnt' cannot be resolved without a contextual type}}
@@ -262,7 +264,9 @@ test_combo(.genericWithReqs([S()])) // expected-error {{contextual member refere
262264
test_combo(.genericWithReqs([42]))
263265
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
264266
test_combo(.genericWithReqs(()))
265-
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
267+
// expected-error@-1 {{type '()' cannot conform to 'Collection'}}
268+
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
269+
// expected-error@-3 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
266270

267271
protocol TestWithAssoc {
268272
associatedtype U

0 commit comments

Comments
 (0)