Skip to content

Commit 9906db3

Browse files
committed
Fix closures capturing value generics
1 parent 8a9303b commit 9906db3

File tree

5 files changed

+70
-13
lines changed

5 files changed

+70
-13
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,8 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
12931293
struct Entry {
12941294
enum Kind {
12951295
Metadata,
1296-
Shape
1296+
Shape,
1297+
Value
12971298
};
12981299

12991300
Kind kind;
@@ -1314,6 +1315,9 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
13141315
SmallString<16> EncodeBuffer;
13151316
llvm::raw_svector_ostream OS(EncodeBuffer);
13161317
switch (Kind) {
1318+
case Entry::Kind::Value:
1319+
OS << "v";
1320+
break;
13171321
case Entry::Kind::Shape:
13181322
OS << "s";
13191323
break;
@@ -1390,10 +1394,18 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
13901394
switch (Bindings[i].getKind()) {
13911395
case GenericRequirement::Kind::Shape:
13921396
case GenericRequirement::Kind::Metadata:
1393-
case GenericRequirement::Kind::MetadataPack: {
1394-
auto Kind = (Bindings[i].getKind() == GenericRequirement::Kind::Shape
1395-
? Entry::Kind::Shape
1396-
: Entry::Kind::Metadata);
1397+
case GenericRequirement::Kind::MetadataPack:
1398+
case GenericRequirement::Kind::Value: {
1399+
auto Kind = Entry::Kind::Metadata;
1400+
1401+
if (Bindings[i].getKind() == GenericRequirement::Kind::Shape) {
1402+
Kind = Entry::Kind::Shape;
1403+
}
1404+
1405+
if (Bindings[i].getKind() == GenericRequirement::Kind::Value) {
1406+
Kind = Entry::Kind::Value;
1407+
}
1408+
13971409
auto Source = SourceBuilder.createClosureBinding(i);
13981410
auto BindingType = Bindings[i].getTypeParameter().subst(Subs);
13991411
auto InterfaceType = BindingType->mapTypeOutOfContext();
@@ -1404,9 +1416,6 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
14041416
case GenericRequirement::Kind::WitnessTablePack:
14051417
// Skip protocol requirements (FIXME: for now?)
14061418
break;
1407-
1408-
case GenericRequirement::Kind::Value:
1409-
llvm_unreachable("implement me");
14101419
}
14111420
}
14121421

@@ -1453,9 +1462,12 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
14531462
Kind = Entry::Kind::Metadata;
14541463
break;
14551464

1465+
case GenericRequirement::Kind::Value:
1466+
Kind = Entry::Kind::Value;
1467+
break;
1468+
14561469
case GenericRequirement::Kind::WitnessTable:
14571470
case GenericRequirement::Kind::WitnessTablePack:
1458-
case GenericRequirement::Kind::Value:
14591471
llvm_unreachable("Bad kind");
14601472
}
14611473

lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ static bool usesGenerics(SILFunction *F,
290290
}
291291
}
292292

293+
// Scan the parameter type of a 'type_value'.
294+
if (auto tvi = dyn_cast<TypeValueInst>(&I)) {
295+
tvi->getParamType().visit(FindArchetypesAndGenericTypes);
296+
}
297+
293298
// Scan the result type of the instruction.
294299
for (auto V : I.getResults()) {
295300
V->getType().getASTType().visit(FindArchetypesAndGenericTypes);

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,10 @@ class FindCapturedVars : public ASTWalker {
683683
}
684684
}
685685

686+
if (auto typeValue = dyn_cast<TypeValueExpr>(E)) {
687+
checkType(typeValue->getParamType(), E->getLoc());
688+
}
689+
686690
return Action::Continue(E);
687691
}
688692

test/SILGen/closures.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

2-
// RUN: %target-swift-emit-silgen -module-name closures -parse-stdlib -parse-as-library %s | %FileCheck %s
3-
// RUN: %target-swift-emit-silgen -module-name closures -parse-stdlib -parse-as-library %s | %FileCheck %s --check-prefix=GUARANTEED
2+
// RUN: %target-swift-emit-silgen -module-name closures -parse-stdlib -parse-as-library %s -enable-experimental-feature ValueGenerics | %FileCheck %s
3+
// RUN: %target-swift-emit-silgen -module-name closures -parse-stdlib -parse-as-library %s -enable-experimental-feature ValueGenerics | %FileCheck %s --check-prefix=GUARANTEED
44

55
import Swift
66

@@ -875,3 +875,11 @@ func test() {
875875
assert(k.x == k2.x)
876876
}
877877

878+
struct ValueGenericType<let N: Int> {
879+
// CHECK-LABEL: @$s8closures16ValueGenericTypeV9somethingSiycyFSiycfU_ : $@convention(thin) <let N : Int> () -> Int
880+
// CHECK: type_value $Int for N
881+
// CHECK-NOT: type_value $Int for @error_type N
882+
func something() -> (() -> Int) {
883+
{ N }
884+
}
885+
}

test/SILOptimizer/functionsigopts.sil

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-sil-opt -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck %s
2-
// RUN: %target-sil-opt -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck -check-prefix=CHECK-NEGATIVE %s
1+
// RUN: %target-sil-opt -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature ValueGenerics %s | %FileCheck %s
2+
// RUN: %target-sil-opt -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature ValueGenerics %s | %FileCheck -check-prefix=CHECK-NEGATIVE %s
33

44
import Builtin
55
import Swift
@@ -68,6 +68,8 @@ indirect public enum IndirectEnum : Hashable {
6868
case B(IndirectEnum)
6969
}
7070

71+
struct ValueGenericType<let N: Int> {}
72+
7173
sil @use_Int : $@convention(thin) (Int) -> ()
7274
sil @use_Int64 : $@convention(thin) (Int64) -> ()
7375
sil @use_Generic : $@convention(thin) <T>(@in_guaranteed T) -> ()
@@ -1809,6 +1811,27 @@ bb0(%0 : $*T):
18091811
return %r : $()
18101812
}
18111813

1814+
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @value_generic_count : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int
1815+
// CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) <let τ_0_0 : Int> () -> Int
1816+
// CHECK: apply
1817+
// CHECK: } // end sil function 'value_generic_count'
1818+
sil [noinline] @value_generic_count : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int {
1819+
bb0(%0 : $ValueGenericType<N>):
1820+
%1 = type_value $Int for N
1821+
return %1 : $Int
1822+
}
1823+
1824+
// CHECK-LABEL: sil [noinline] @value_generic_count_caller : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int
1825+
// CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) <let τ_0_0 : Int> () -> Int
1826+
// CHECK: apply
1827+
// CHECK: } // end sil function 'value_generic_count_caller'
1828+
sil [noinline] @value_generic_count_caller : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int {
1829+
bb0(%0 : $ValueGenericType<N>):
1830+
%1 = function_ref @value_generic_count : $@convention(thin) <let τ_0_0 : Int> (ValueGenericType<τ_0_0>) -> Int
1831+
%2 = apply %1<N>(%0) : $@convention(thin) <let τ_0_0 : Int> (ValueGenericType<τ_0_0>) -> Int
1832+
return %2 : $Int
1833+
}
1834+
18121835
// CHECK-LABEL: sil shared @$s36exploded_release_to_guaranteed_paramTf4gX_n
18131836
// CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $Int):
18141837
// CHECK-NOT: strong_release
@@ -1909,3 +1932,8 @@ bb0(%0 : $*T):
19091932
// CHECK: apply
19101933
// CHECK: end sil function '$s31generic_in_to_guaranteed_callerTf4g_n'
19111934

1935+
// CHECK-LABEL: sil shared [noinline] @$s19value_generic_countTf4d_n : $@convention(thin) <let N : Int> () -> Int {
1936+
// CHECK: [[TYPE_VALUE:%.*]] = type_value $Int for N
1937+
// CEHCK-NOT: type_value $Int for @error_type N
1938+
// CHECK-NEXT: return [[TYPE_VALUE]] : $Int
1939+
// CHECK-LABEL: } // end sil function '$s19value_generic_countTf4d_n'

0 commit comments

Comments
 (0)