@@ -458,6 +458,24 @@ static Type getResultType(TypeChecker &TC, FuncDecl *fn, Type resultType) {
458458 return resultType;
459459}
460460
461+ // / Determine whether the given type is \c Self, an associated type of \c Self,
462+ // / or a concrete type.
463+ static bool isSelfDerivedOrConcrete (Type type) {
464+ // Check for a concrete type.
465+ if (!type->hasTypeParameter ())
466+ return true ;
467+
468+ // Unwrap dependent member types.
469+ while (auto depMem = type->getAs <DependentMemberType>()) {
470+ type = depMem->getBase ();
471+ }
472+
473+ if (auto gp = type->getAs <GenericTypeParamType>())
474+ return gp->getDepth () == 0 && gp->getIndex () == 0 ;
475+
476+ return false ;
477+ }
478+
461479GenericSignature *
462480TypeChecker::validateGenericFuncSignature (AbstractFunctionDecl *func) {
463481 bool invalid = false ;
@@ -493,6 +511,34 @@ TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
493511 // the type of the generic function.
494512 auto sig = builder.getGenericSignature ();
495513
514+ // For a generic requirement in a protocol, make sure that the requirement
515+ // set didn't add any requirements to Self or its associated types.
516+ if (!invalid && func->getGenericParams () &&
517+ isa<ProtocolDecl>(func->getDeclContext ())) {
518+ auto proto = cast<ProtocolDecl>(func->getDeclContext ());
519+ for (auto req : sig->getRequirements ()) {
520+ // If one of the types in the requirement is dependent on a non-Self
521+ // type parameter, this requirement is okay.
522+ if (!isSelfDerivedOrConcrete (req.getFirstType ()) ||
523+ !isSelfDerivedOrConcrete (req.getSecondType ()))
524+ continue ;
525+
526+ // The conformance of 'Self' to the protocol is okay.
527+ if (req.getKind () == RequirementKind::Conformance &&
528+ req.getSecondType ()->getAs <ProtocolType>()->getDecl () == proto &&
529+ req.getFirstType ()->is <GenericTypeParamType>())
530+ continue ;
531+
532+ diagnose (func, diag::requirement_restricts_self,
533+ func->getDescriptiveKind (), func->getFullName (),
534+ req.getFirstType ().getString (),
535+ static_cast <unsigned >(req.getKind ()),
536+ req.getSecondType ().getString ());
537+
538+ invalid = true ;
539+ }
540+ }
541+
496542 // Debugging of the archetype builder and generic signature generation.
497543 if (Context.LangOpts .DebugGenericSignatures ) {
498544 func->dumpRef (llvm::errs ());
0 commit comments