Skip to content

Commit 34971b9

Browse files
committed
[Features] Gate same-element requirements behind an experimental feature flag.
1 parent 897fc89 commit 34971b9

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ EXPERIMENTAL_FEATURE(NamedOpaqueTypes, false)
123123
EXPERIMENTAL_FEATURE(FlowSensitiveConcurrencyCaptures, false)
124124
EXPERIMENTAL_FEATURE(CodeItemMacros, false)
125125
EXPERIMENTAL_FEATURE(TupleConformances, false)
126+
EXPERIMENTAL_FEATURE(SameElementRequirements, false)
126127

127128
SUPPRESSIBLE_LANGUAGE_FEATURE(ExtensionMacroAttr, 0, "@attached(extension)", true)
128129

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,6 +3259,10 @@ static bool usesFeatureTupleConformances(Decl *decl) {
32593259
return false;
32603260
}
32613261

3262+
static bool usesFeatureSameElementRequirements(Decl *decl) {
3263+
return false;
3264+
}
3265+
32623266
static bool usesFeatureSymbolLinkageMarkers(Decl *decl) {
32633267
auto &attrs = decl->getAttrs();
32643268
return std::any_of(attrs.begin(), attrs.end(), [](auto *attr) {

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,18 @@ static void desugarSameTypeRequirement(Requirement req, SourceLoc loc,
218218
break;
219219
}
220220

221+
auto &ctx = firstType->getASTContext();
222+
if (!ctx.LangOpts.hasFeature(Feature::SameElementRequirements)) {
223+
// If one side is a parameter pack, this is a same-element requirement, which
224+
// is not yet supported.
225+
if (firstType->isParameterPack() != secondType->isParameterPack()) {
226+
errors.push_back(RequirementError::forSameElement(
227+
{kind, sugaredFirstType, secondType}, loc));
228+
recordedErrors = true;
229+
return true;
230+
}
231+
}
232+
221233
if (firstType->isTypeParameter() && secondType->isTypeParameter()) {
222234
result.emplace_back(kind, sugaredFirstType, secondType);
223235
return true;

test/Constraints/pack-expansion-expressions.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,16 @@ func outerArchetype<each T, U>(t: repeat each T, u: U) where repeat each T: P {
6363
}
6464

6565
func sameElement<each T, U>(t: repeat each T, u: U) where repeat each T: P, repeat each T == U {
66-
let _ = (repeat (each t).f(u))
66+
// expected-error@-1{{same-element requirements are not yet supported}}
67+
let _: (repeat each T) = (repeat (each t).f(u))
68+
// expected-error@-1 {{cannot convert value of type 'U' to expected argument type 'each T'}}
6769
}
6870

6971
func forEachEach<each C, U>(c: repeat each C, function: (U) -> Void)
7072
where repeat each C: Collection, repeat (each C).Element == U {
71-
repeat (each c).forEach(function)
73+
// expected-error@-1{{same-element requirements are not yet supported}}
74+
_ = (repeat (each c).forEach(function))
75+
// expected-error@-1 {{cannot convert value of type '(U) -> Void' to expected argument type '(each C.Element) throws -> Void'}}
7276
}
7377

7478
func typeReprPacks<each T: ExpressibleByIntegerLiteral>(_ t: repeat each T) {

test/Generics/parameter-pack-requirements.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -disable-availability-checking 2>&1 | %FileCheck %s
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -disable-availability-checking -enable-experimental-feature SameElementRequirements 2>&1 | %FileCheck %s
2+
3+
// REQUIRES: asserts
24

35
protocol P {
46
associatedtype A: P
57
associatedtype B
8+
9+
func f(_ self: Self) -> Self
610
}
711

812
// CHECK-LABEL: inferSameShape(ts:us:)
@@ -158,3 +162,24 @@ func dependentSameElementConcrete<each C: Collection>(
158162
func dependentSameElementGeneric<each C: Collection, Element>(
159163
_: repeat each C
160164
) where repeat (each C).Element == Element {}
165+
166+
// FIXME: Either 'repeat each T: P' or 'U: P' should be redundant.
167+
// CHECK-LABEL: sameElementRedundantConformance
168+
// CHECK-NEXT: Generic signature: <each T, U where repeat each T : P, U : P, repeat U == each T>
169+
func sameElementRedundantConformance<each T, U>(
170+
t: repeat each T,
171+
u: U
172+
) where repeat each T: P,
173+
repeat each T == U {
174+
let _ = (repeat (each t).f(u))
175+
}
176+
177+
// CHECK-LABEL: forEachEach
178+
// CHECK-NEXT: Generic signature: <each C, U where repeat each C : Collection, repeat U == (each C).[Sequence]Element>
179+
func forEachEach<each C, U>(
180+
c: repeat each C,
181+
function: (U) -> Void
182+
) where repeat each C: Collection,
183+
repeat (each C).Element == U {
184+
repeat (each c).forEach(function)
185+
}

0 commit comments

Comments
 (0)