@@ -2034,48 +2034,59 @@ FunctionOperatorRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
20342034 return op.get ();
20352035}
20362036
2037- bool swift::isMemberOperator (FuncDecl *decl, Type type) {
2037+ // / This means two things:
2038+ // / - If selfTy is null, 'decl' is assumed to be a member of a nominal type
2039+ // / or extension. We check if its a valid member operator.
2040+ // / - Otherwise, 'decl' is a member or top-level operator. We check if it
2041+ // / is a suitable witness for the given conforming type.
2042+ bool swift::isMemberOperator (FuncDecl *decl, Type selfTy) {
20382043 // Check that member operators reference the type of 'Self'.
20392044 if (decl->isInvalid ())
20402045 return true ;
20412046
20422047 auto *DC = decl->getDeclContext ();
20432048
20442049 auto selfNominal = DC->getSelfNominalTypeDecl ();
2050+ assert (selfNominal || selfTy);
20452051
2046- // Check the parameters for a reference to 'Self'.
2052+ // Is the operator a member of a protocol or protocol extension?
20472053 bool isProtocol = isa_and_nonnull<ProtocolDecl>(selfNominal);
2054+
2055+ // Is the operator a member of a tuple extension?
20482056 bool isTuple = isa_and_nonnull<BuiltinTupleDecl>(selfNominal);
20492057
2058+ // Check the parameters for a reference to 'Self'.
20502059 for (auto param : *decl->getParameters ()) {
20512060 // Look through a metatype reference, if there is one.
20522061 auto paramType = param->getInterfaceType ()->getMetatypeInstanceType ();
20532062
2063+ if (isProtocol || isTuple) {
2064+ // For a member of a protocol or tuple extension, is it the 'Self'
2065+ // type parameter?
2066+ if (paramType->isEqual (DC->getSelfInterfaceType ()))
2067+ return true ;
2068+
2069+ continue ;
2070+ }
2071+
2072+ // We have a member operator of a concrete nominal type, or a global operator.
20542073 auto nominal = paramType->getAnyNominal ();
2055- if (type.isNull ()) {
2056- // Is it the same nominal type?
2057- if (selfNominal && nominal == selfNominal)
2074+
2075+ if (selfTy.isNull ()) {
2076+ // We're validating a member operator.
2077+
2078+ // Does the parameter have the right nominal type?
2079+ if (nominal == selfNominal)
20582080 return true ;
20592081 } else {
2060- // Is it the same nominal type? Or a generic (which may or may not match)?
2061- if (paramType->is <GenericTypeParamType>() ||
2062- nominal == type->getAnyNominal ())
2063- return true ;
2064- }
2082+ // We're checking a conformance and this operator is a candidate witness.
20652083
2066- if (isProtocol) {
2067- // FIXME: Source compatibility hack for Swift 5. The compiler
2068- // accepts member operators on protocols with existential
2069- // type arguments. We should consider banning this in Swift 6.
2070- if (auto existential = paramType->getAs <ExistentialType>()) {
2071- if (selfNominal == existential->getConstraintType ()->getAnyNominal ())
2072- return true ;
2073- }
2074- }
2084+ // Does the parameter have the right nominal type for the conformance?
2085+ if (nominal == selfTy->getAnyNominal ())
2086+ return true ;
20752087
2076- if (isProtocol || isTuple) {
2077- // For a protocol or tuple extension, is it the 'Self' type parameter?
2078- if (paramType->isEqual (DC->getSelfInterfaceType ()))
2088+ // Otherwise, we might also have a match if the top-level operator is generic.
2089+ if (paramType->is <GenericTypeParamType>())
20792090 return true ;
20802091 }
20812092 }
0 commit comments