@@ -5787,20 +5787,27 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
5787
5787
return SolutionKind::Solved;
5788
5788
}
5789
5789
5790
- // If we hit a type variable without a fixed type, we can't
5791
- // solve this yet.
5792
- if (type->isTypeVariableOrMember ()) {
5790
+ auto formUnsolved = [&](bool activate = false ) {
5793
5791
// If we're supposed to generate constraints, do so.
5794
5792
if (flags.contains (TMF_GenerateConstraints)) {
5795
- addUnsolvedConstraint (
5796
- Constraint::create (*this , kind, type,
5797
- protocol->getDeclaredInterfaceType (),
5798
- getConstraintLocator (locator)));
5793
+ auto *conformance = Constraint::create (
5794
+ *this , kind, type, protocol->getDeclaredInterfaceType (),
5795
+ getConstraintLocator (locator));
5796
+
5797
+ addUnsolvedConstraint (conformance);
5798
+ if (activate)
5799
+ activateConstraint (conformance);
5800
+
5799
5801
return SolutionKind::Solved;
5800
5802
}
5801
5803
5802
5804
return SolutionKind::Unsolved;
5803
- }
5805
+ };
5806
+
5807
+ // If we hit a type variable without a fixed type, we can't
5808
+ // solve this yet.
5809
+ if (type->isTypeVariableOrMember ())
5810
+ return formUnsolved ();
5804
5811
5805
5812
auto *loc = getConstraintLocator (locator);
5806
5813
@@ -5922,7 +5929,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
5922
5929
return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
5923
5930
}
5924
5931
5925
- if (path.back ().is <LocatorPathElt::AnyRequirement>()) {
5932
+ if (auto req = path.back ().getAs <LocatorPathElt::AnyRequirement>()) {
5926
5933
// If this is a requirement associated with `Self` which is bound
5927
5934
// to `Any`, let's consider this "too incorrect" to continue.
5928
5935
//
@@ -5941,6 +5948,39 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
5941
5948
}
5942
5949
}
5943
5950
5951
+ auto anchor = locator.getAnchor ();
5952
+
5953
+ if ((isExpr<UnresolvedDotExpr>(anchor) ||
5954
+ isExpr<UnresolvedMemberExpr>(anchor)) &&
5955
+ req->is <LocatorPathElt::TypeParameterRequirement>()) {
5956
+ auto signature = path[path.size () - 2 ]
5957
+ .castTo <LocatorPathElt::OpenedGeneric>()
5958
+ .getSignature ();
5959
+ auto requirement = signature->getRequirements ()[req->getIndex ()];
5960
+
5961
+ auto *memberLoc = getConstraintLocator (anchor, path.front ());
5962
+ auto *memberRef = findResolvedMemberRef (memberLoc);
5963
+
5964
+ // To figure out what is going on here we need to wait until
5965
+ // member overload is set in the constraint system.
5966
+ if (!memberRef)
5967
+ return formUnsolved (/* activate=*/ true );
5968
+
5969
+ // If this is a `Self` conformance requirement from a static member
5970
+ // reference on a protocol metatype, let's produce a tailored diagnostic.
5971
+ if (memberRef->isStatic ()) {
5972
+ if (auto *protocolDecl =
5973
+ memberRef->getDeclContext ()->getSelfProtocolDecl ()) {
5974
+ auto selfTy = protocolDecl->getProtocolSelfType ();
5975
+ if (selfTy->isEqual (requirement.getFirstType ())) {
5976
+ auto *fix = AllowInvalidStaticMemberRefOnProtocolMetatype::create (
5977
+ *this , memberLoc);
5978
+ return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
5979
+ }
5980
+ }
5981
+ }
5982
+ }
5983
+
5944
5984
if (auto *fix =
5945
5985
fixRequirementFailure (*this , type, protocolTy, anchor, path)) {
5946
5986
auto impact = assessRequirementFailureImpact (*this , rawType, locator);
@@ -5953,27 +5993,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
5953
5993
}
5954
5994
}
5955
5995
5956
- if (path.back ().is <LocatorPathElt::MemberRefBase>()) {
5957
- path.pop_back ();
5958
-
5959
- auto *memberLoc = getConstraintLocator (anchor, path);
5960
- if (auto overload = findSelectedOverloadFor (memberLoc)) {
5961
- const auto &choice = overload->choice ;
5962
- assert (choice.isDecl ());
5963
-
5964
- auto *decl = choice.getDecl ();
5965
- auto nameRef = choice.getFunctionRefKind () == FunctionRefKind::Compound
5966
- ? decl->createNameRef ()
5967
- : DeclNameRef (decl->getBaseName ());
5968
-
5969
- auto *fix = AllowTypeOrInstanceMember::create (
5970
- *this , MetatypeType::get (protocolTy, getASTContext ()), decl,
5971
- nameRef, memberLoc);
5972
-
5973
- return recordFix (fix) ? SolutionKind::Error : SolutionKind::Solved;
5974
- }
5975
- }
5976
-
5977
5996
// If this is an implicit Hashable conformance check generated for each
5978
5997
// index argument of the keypath subscript component, we could just treat
5979
5998
// it as though it conforms.
@@ -6833,8 +6852,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
6833
6852
// referred from.
6834
6853
assert (hasStaticMembers);
6835
6854
6836
- Type resultTy;
6837
-
6838
6855
// Cannot instantiate a protocol or reference a member on
6839
6856
// protocol composition type.
6840
6857
if (isa<ConstructorDecl>(decl) ||
@@ -6844,6 +6861,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
6844
6861
return ;
6845
6862
}
6846
6863
6864
+ Type resultTy;
6865
+
6847
6866
if (isa<AbstractFunctionDecl>(decl)) {
6848
6867
auto refTy =
6849
6868
decl->getInterfaceType ()->castTo <AnyFunctionType>()->getResult ();
@@ -8017,10 +8036,11 @@ ConstraintSystem::simplifyUnresolvedMemberChainBaseConstraint(
8017
8036
auto *memberLoc =
8018
8037
getConstraintLocator (baseExpr, ConstraintLocator::UnresolvedMember);
8019
8038
8020
- auto *memberRef = findResolvedMemberRef (memberLoc);
8021
- assert (memberRef) ;
8039
+ if ( shouldAttemptFixes () && hasFixFor (memberLoc))
8040
+ return SolutionKind::Solved ;
8022
8041
8023
- if (memberRef->isStatic ()) {
8042
+ auto *memberRef = findResolvedMemberRef (memberLoc);
8043
+ if (memberRef && memberRef->isStatic ()) {
8024
8044
return simplifyConformsToConstraint (
8025
8045
resultTy, baseTy, ConstraintKind::ConformsTo,
8026
8046
getConstraintLocator (memberLoc, ConstraintLocator::MemberRefBase),
0 commit comments