@@ -776,15 +776,15 @@ InferredGenericSignatureRequest::evaluate(
776776 WhereClauseOwner whereClause,
777777 SmallVector<Requirement, 2 > addedRequirements,
778778 SmallVector<TypeBase *, 2 > inferenceSources,
779- SourceLoc loc, bool isExtension , bool allowInverses) const {
779+ SourceLoc loc, ExtensionDecl *forExtension , bool allowInverses) const {
780780 GenericSignature parentSig (parentSigImpl);
781781
782782 SmallVector<GenericTypeParamType *, 4 > genericParams (
783783 parentSig.getGenericParams ().begin (),
784784 parentSig.getGenericParams ().end ());
785785
786786 unsigned numOuterParams = genericParams.size ();
787- if (isExtension ) {
787+ if (forExtension ) {
788788 numOuterParams = 0 ;
789789 }
790790
@@ -889,6 +889,68 @@ InferredGenericSignatureRequest::evaluate(
889889 SmallVector<StructuralRequirement, 2 > defaults;
890890 InverseRequirement::expandDefaults (ctx, paramTypes, defaults);
891891 applyInverses (ctx, paramTypes, inverses, defaults, errors);
892+
893+ // Any remaining implicit defaults in a conditional inverse requirement
894+ // extension must be made explicit.
895+ if (forExtension) {
896+ auto invertibleProtocol = forExtension->isAddingConformanceToInvertible ();
897+ // FIXME: to workaround a reverse condfail, always infer the requirements if
898+ // the extension is in a swiftinterface file. This is temporary and should
899+ // be removed soon. (rdar://130424971)
900+ if (auto *sf = forExtension->getOutermostParentSourceFile ()) {
901+ if (sf->Kind == SourceFileKind::Interface
902+ && !ctx.LangOpts .hasFeature (Feature::SE427NoInferenceOnExtension)) {
903+ invertibleProtocol = std::nullopt ;
904+ }
905+ }
906+ if (invertibleProtocol) {
907+ for (auto &def : defaults) {
908+ // Check whether a corresponding explicit requirement was provided.
909+ for (auto &req : requirements) {
910+ // An explicit requirement can match the default exactly.
911+ if (req.req .getCanonical () == def.req .getCanonical ()) {
912+ goto next;
913+ }
914+
915+ // Disregard requirements on other parameters.
916+ if (!req.req .getFirstType ()->isEqual (def.req .getFirstType ())) {
917+ continue ;
918+ }
919+
920+ // Or it can be implied by a requirement on something that's inherently
921+ // copyable.
922+ if (req.req .getKind () == RequirementKind::Superclass) {
923+ // classes are currently always escapable and copyable
924+ goto next;
925+ }
926+ if (req.req .getKind () == RequirementKind::Layout) {
927+ // layout constraints currently always imply escapable and copyable
928+ goto next;
929+ }
930+ if (req.req .getKind () == RequirementKind::Conformance
931+ && req.req .getProtocolDecl ()
932+ ->inheritsFrom (def.req .getProtocolDecl ())) {
933+ goto next;
934+ }
935+
936+ // A same-type constraint removes the ability for the copyability
937+ // to vary independently at all.
938+ if (req.req .getKind () == RequirementKind::SameType) {
939+ goto next;
940+ }
941+ }
942+ ctx.Diags .diagnose (loc,diag::inverse_conditional_must_be_fully_explicit,
943+ ctx.getProtocol (getKnownProtocolKind (*invertibleProtocol)),
944+ def.req .getFirstType (),
945+ def.req .getProtocolDecl ());
946+ next:;
947+ }
948+ // Don't actually apply the inferred requirements since they should be
949+ // stated explicitly.
950+ defaults.clear ();
951+ }
952+ }
953+
892954 requirements.append (defaults);
893955
894956 auto &rewriteCtx = ctx.getRewriteContext ();
@@ -954,7 +1016,7 @@ InferredGenericSignatureRequest::evaluate(
9541016 if (attempt == 0 ) {
9551017 machine->computeRequirementDiagnostics (errors, inverses, loc);
9561018 diagnoseRequirementErrors (ctx, errors,
957- (isExtension || !genericParamList)
1019+ (forExtension || !genericParamList)
9581020 ? AllowConcreteTypePolicy::All
9591021 : AllowConcreteTypePolicy::AssocTypes);
9601022 }
@@ -985,7 +1047,7 @@ InferredGenericSignatureRequest::evaluate(
9851047 std::move (machine));
9861048 }
9871049
988- if (genericParamList && !isExtension ) {
1050+ if (genericParamList && !forExtension ) {
9891051 for (auto genericParam : result.getInnermostGenericParams ()) {
9901052 auto reduced = result.getReducedType (genericParam);
9911053
0 commit comments