Skip to content

Commit 75207cb

Browse files
committed
Allow Deriving Type Witnesses Across Files
A recent change to witness matching in #32578 suddenly made the following construction illegal: // File1.swift enum MyEnumInAnotherFile { /**/ } // File2.swift extension MyEnumInAnotherFile { static var allCases: [MyEnumInAnotherFile] { /**/ } } Because it was no longer possible to derive the type witness for `AllCases`. This is because, when inference ran before synthesis, we would use the value witness to pick out the type witness and thus had no need for synthesis. Now that we run synthesis first, we ought to just allow deriving type witnesses across files, but still ban deriving value witnesses. In general, if you can utter a type in a different file to extend it, you should be able to see the requirements necessary to derive a default type witness. rdar://66279278, rdar://66279375, rdar://66279384, rdar://66279415, rdar://66279503
1 parent a8f3634 commit 75207cb

8 files changed

+18
-19
lines changed

lib/Sema/DerivedConformanceCaseIterable.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,6 @@ ValueDecl *DerivedConformance::deriveCaseIterable(ValueDecl *requirement) {
113113
}
114114

115115
Type DerivedConformance::deriveCaseIterable(AssociatedTypeDecl *assocType) {
116-
if (checkAndDiagnoseDisallowedContext(assocType))
117-
return nullptr;
118-
119116
// Check that we can actually derive CaseIterable for this type.
120117
if (!canDeriveConformance(Nominal))
121118
return nullptr;

lib/Sema/DerivedConformanceDifferentiable.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -895,9 +895,6 @@ DerivedConformance::deriveDifferentiable(AssociatedTypeDecl *requirement) {
895895
diag::broken_differentiable_requirement);
896896
return std::make_pair(nullptr, nullptr);
897897
}
898-
// Diagnose conformances in disallowed contexts.
899-
if (checkAndDiagnoseDisallowedContext(requirement))
900-
return std::make_pair(nullptr, nullptr);
901898

902899
// Start an error diagnostic before attempting derivation.
903900
// If derivation succeeds, cancel the diagnostic.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import _Differentiation
22

3-
// expected-note @+1 {{type declared here}}
3+
// expected-note @+1 2 {{type declared here}}
44
class OtherFileNonconforming {}
55

6-
// expected-note @+1 {{type declared here}}
6+
// expected-note @+1 2 {{type declared here}}
77
class GenericOtherFileNonconforming<T: Differentiable> {
88
var x: T
99
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import _Differentiation
22

3-
// expected-note @+1 {{type declared here}}
3+
// expected-note @+1 2 {{type declared here}}
44
struct OtherFileNonconforming {}
55

6-
// expected-note @+1 {{type declared here}}
6+
// expected-note @+1 2 {{type declared here}}
77
struct GenericOtherFileNonconforming<T: Differentiable> {
88
var x: T
99
}

test/AutoDiff/Sema/DerivedConformances/class_differentiable.swift

+2-4
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,8 @@ class WrappedProperties: Differentiable {
570570

571571
// Test derived conformances in disallowed contexts.
572572

573-
// expected-error @+2 {{type 'OtherFileNonconforming' does not conform to protocol 'Differentiable'}}
574-
// expected-error @+1 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
573+
// expected-error @+1 2 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
575574
extension OtherFileNonconforming: Differentiable {}
576575

577-
// expected-error @+2 {{type 'GenericOtherFileNonconforming<T>' does not conform to protocol 'Differentiable'}}
578-
// expected-error @+1 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
576+
// expected-error @+1 2 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
579577
extension GenericOtherFileNonconforming: Differentiable {}

test/AutoDiff/Sema/DerivedConformances/struct_differentiable.swift

+2-4
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,8 @@ struct WrappedProperties: Differentiable {
383383

384384
// Verify that cross-file derived conformances are disallowed.
385385

386-
// expected-error @+2 {{type 'OtherFileNonconforming' does not conform to protocol 'Differentiable'}}
387-
// expected-error @+1 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
386+
// expected-error @+1 2 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
388387
extension OtherFileNonconforming: Differentiable {}
389388

390-
// expected-error @+2 {{type 'GenericOtherFileNonconforming<T>' does not conform to protocol 'Differentiable'}}
391-
// expected-error @+1 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
389+
// expected-error @+1 2 {{implementation of 'Differentiable' cannot be automatically synthesized in an extension in a different file to the type}}
392390
extension GenericOtherFileNonconforming: Differentiable {}

test/Sema/Inputs/enum_conformance_synthesis_other.swift

+4
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ extension ImpliedMain: ImplierMain {}
2929
enum ImpliedOther: ImplierOther {
3030
case a(Int)
3131
}
32+
33+
enum CaseIterableAcrossFiles {
34+
case A
35+
}

test/Sema/enum_conformance_synthesis.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,12 @@ enum Complex2 {
224224
}
225225
extension Complex2 : Hashable {}
226226
extension Complex2 : CaseIterable {} // expected-error {{type 'Complex2' does not conform to protocol 'CaseIterable'}}
227-
extension FromOtherFile: CaseIterable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}} expected-error {{does not conform to protocol 'CaseIterable'}}
227+
extension FromOtherFile: CaseIterable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}}
228+
extension CaseIterableAcrossFiles: CaseIterable {
229+
public static var allCases: [CaseIterableAcrossFiles] {
230+
return [ .A ]
231+
}
232+
}
228233

229234
// No explicit conformance and it cannot be derived.
230235
enum NotExplicitlyHashableAndCannotDerive {

0 commit comments

Comments
 (0)