@@ -776,15 +776,15 @@ InferredGenericSignatureRequest::evaluate(
776
776
WhereClauseOwner whereClause,
777
777
SmallVector<Requirement, 2 > addedRequirements,
778
778
SmallVector<TypeBase *, 2 > inferenceSources,
779
- SourceLoc loc, bool isExtension , bool allowInverses) const {
779
+ SourceLoc loc, ExtensionDecl *forExtension , bool allowInverses) const {
780
780
GenericSignature parentSig (parentSigImpl);
781
781
782
782
SmallVector<GenericTypeParamType *, 4 > genericParams (
783
783
parentSig.getGenericParams ().begin (),
784
784
parentSig.getGenericParams ().end ());
785
785
786
786
unsigned numOuterParams = genericParams.size ();
787
- if (isExtension ) {
787
+ if (forExtension ) {
788
788
numOuterParams = 0 ;
789
789
}
790
790
@@ -889,6 +889,68 @@ InferredGenericSignatureRequest::evaluate(
889
889
SmallVector<StructuralRequirement, 2 > defaults;
890
890
InverseRequirement::expandDefaults (ctx, paramTypes, defaults);
891
891
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
+
892
954
requirements.append (defaults);
893
955
894
956
auto &rewriteCtx = ctx.getRewriteContext ();
@@ -954,7 +1016,7 @@ InferredGenericSignatureRequest::evaluate(
954
1016
if (attempt == 0 ) {
955
1017
machine->computeRequirementDiagnostics (errors, inverses, loc);
956
1018
diagnoseRequirementErrors (ctx, errors,
957
- (isExtension || !genericParamList)
1019
+ (forExtension || !genericParamList)
958
1020
? AllowConcreteTypePolicy::All
959
1021
: AllowConcreteTypePolicy::AssocTypes);
960
1022
}
@@ -985,7 +1047,7 @@ InferredGenericSignatureRequest::evaluate(
985
1047
std::move (machine));
986
1048
}
987
1049
988
- if (genericParamList && !isExtension ) {
1050
+ if (genericParamList && !forExtension ) {
989
1051
for (auto genericParam : result.getInnermostGenericParams ()) {
990
1052
auto reduced = result.getReducedType (genericParam);
991
1053
0 commit comments