Skip to content

Commit 151e1c5

Browse files
authored
Merge pull request #64337 from slavapestov/misc-variadic-generic-fixes
Miscellaneous variadic generics fixes
2 parents 58e42b3 + c3a6bfb commit 151e1c5

12 files changed

+133
-13
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3166,9 +3166,13 @@ void ASTMangler::appendGenericSignatureParts(
31663166

31673167
/// Determine whether an associated type reference into the given set of
31683168
/// protocols is unambiguous.
3169-
static bool associatedTypeRefIsUnambiguous(ArrayRef<ProtocolDecl *> protocols) {
3169+
static bool associatedTypeRefIsUnambiguous(GenericSignature sig, Type t) {
3170+
// FIXME: This should be an assertion.
3171+
if (!sig->isValidTypeParameter(t))
3172+
return false;
3173+
31703174
unsigned numProtocols = 0;
3171-
for (auto proto : protocols) {
3175+
for (auto proto : sig->getRequiredProtocols(t)) {
31723176
// Skip marker protocols, which cannot have associated types.
31733177
if (proto->isMarkerProtocol())
31743178
continue;
@@ -3188,7 +3192,7 @@ ASTMangler::dropProtocolFromAssociatedType(DependentMemberType *dmt,
31883192
auto baseTy = dmt->getBase();
31893193
bool unambiguous =
31903194
(!dmt->getAssocType() ||
3191-
associatedTypeRefIsUnambiguous(sig->getRequiredProtocols(baseTy)));
3195+
associatedTypeRefIsUnambiguous(sig, baseTy));
31923196

31933197
if (auto *baseDMT = baseTy->getAs<DependentMemberType>())
31943198
baseTy = dropProtocolFromAssociatedType(baseDMT, sig);
@@ -3225,7 +3229,7 @@ void ASTMangler::appendAssociatedTypeName(DependentMemberType *dmt,
32253229
// associated type name by protocol.
32263230
if (!OptimizeProtocolNames || !sig ||
32273231
!associatedTypeRefIsUnambiguous(
3228-
sig->getRequiredProtocols(dmt->getBase()))) {
3232+
sig, dmt->getBase())) {
32293233
appendAnyGenericType(assocTy->getProtocol());
32303234
}
32313235
return;

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,19 @@ RequirementMachine::getLongestValidPrefix(const MutableTerm &term) const {
244244
"Protocol symbol can only appear at the start of a type term");
245245
break;
246246

247-
case Symbol::Kind::GenericParam:
247+
case Symbol::Kind::GenericParam: {
248248
assert(prefix.empty() &&
249249
"Generic parameter symbol can only appear at the start of a type term");
250+
251+
if (std::find_if(Params.begin(), Params.end(),
252+
[&](Type otherParam) -> bool {
253+
return otherParam->isEqual(symbol.getGenericParam());
254+
}) == Params.end()) {
255+
return prefix;
256+
}
257+
250258
break;
259+
}
251260

252261
case Symbol::Kind::AssociatedType: {
253262
const auto *props = Map.lookUpProperties(prefix);

lib/Demangling/Demangler.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2396,7 +2396,6 @@ NodePointer Demangler::demangleArchetype() {
23962396
NodePointer PatternTy = popTypeAndGetChild();
23972397
NodePointer PackExpansionTy = createType(
23982398
createWithChildren(Node::Kind::PackExpansion, PatternTy, CountTy));
2399-
addSubstitution(PackExpansionTy);
24002399
return PackExpansionTy;
24012400
}
24022401
case 'P':

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
7979
auto sig = var->getDeclContext()
8080
->getGenericSignatureOfContext()
8181
.getCanonicalSignature();
82-
auto swiftType = sig.getReducedType(var->getInterfaceType());
82+
83+
auto interfaceType = var->getInterfaceType();
84+
if (auto *packExpansionType = interfaceType->getAs<PackExpansionType>())
85+
interfaceType = packExpansionType->getPatternType();
86+
87+
auto swiftType = sig.getReducedType(interfaceType);
8388

8489
if (isNonObjC)
8590
return AbstractionPattern(sig, swiftType);
@@ -1988,9 +1993,21 @@ class SubstFunctionTypePatternVisitor
19881993
return CanType(pack);
19891994
}
19901995

1996+
auto substPatternType = visit(pack->getPatternType(),
1997+
pattern.getPackExpansionPatternType());
1998+
auto substCountType = visit(pack->getCountType(),
1999+
pattern.getPackExpansionCountType());
2000+
2001+
SmallVector<Type> rootParameterPacks;
2002+
substPatternType->getTypeParameterPacks(rootParameterPacks);
2003+
2004+
for (auto parameterPack : rootParameterPacks) {
2005+
substRequirements.emplace_back(RequirementKind::SameShape,
2006+
parameterPack, substCountType);
2007+
}
2008+
19912009
return CanType(PackExpansionType::get(
1992-
visit(pack->getPatternType(), pattern.getPackExpansionPatternType()),
1993-
visit(pack->getCountType(), pattern.getPackExpansionCountType())));
2010+
substPatternType, substCountType));
19942011
}
19952012

19962013
CanType visitExistentialType(ExistentialType *exist,

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4650,8 +4650,14 @@ class SILTypeSubstituter :
46504650
}
46514651

46524652
bool hasSameShape(CanType lhs, CanType rhs) {
4653-
// FIXME
4654-
return lhs == rhs;
4653+
if (lhs->isTypeParameter() && rhs->isTypeParameter()) {
4654+
assert(Sig);
4655+
return Sig->haveSameShape(lhs, rhs);
4656+
}
4657+
4658+
auto lhsArchetype = cast<PackArchetypeType>(lhs);
4659+
auto rhsArchetype = cast<PackArchetypeType>(rhs);
4660+
return lhsArchetype->getReducedShape() == rhsArchetype->getReducedShape();
46554661
}
46564662
};
46574663

test/AutoDiff/compiler_crashers_fixed/58660-conflicting-debug-info-inlining.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: %target-swift-frontend -emit-sil -O -g %s | %FileCheck %s
33

44
// REQUIRES: swift_in_compiler
5+
// XFAIL: OS=linux
56

67
// Issue #58660: Specifically-shaped differentiable functions yield "conflicting debug info for argument" assertion failure
78
// Ensure that proper location is preserved after sil-mem2reg location-less stores (created during inlining)

test/SILGen/pack_expansion_type.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public struct VariadicType<each T> {
1414
// CHECK: bb0(%0 : $*Pack{repeat (each T, each U)}, %1 : $*Pack{repeat each T}, %2 : $*Pack{repeat each U}, %3 : $VariadicType<repeat each T>):
1515
public func variadicMethod<each U>(t: repeat each T, u: repeat each U) -> (repeat (each T, each U)) {}
1616

17-
// CHECK-LABEL: sil [ossa] @$s19pack_expansion_type12VariadicTypeV13takesFunction1tyqd__qd__Qp_txxQpXE_tRvd__lF : $@convention(method) <each T><each U> (@guaranteed @noescape @callee_guaranteed @substituted <each τ_0_0, each τ_0_1, each τ_0_2, each τ_0_3> (@pack_guaranteed Pack{repeat each τ_0_0}) -> @pack_out Pack{repeat each τ_0_2} for <Pack{repeat each T}, Pack{repeat each T}, Pack{repeat each U}, Pack{repeat each U}>, VariadicType<repeat each T>) -> () {
18-
// CHECK: bb0(%0 : @guaranteed $@noescape @callee_guaranteed @substituted <each τ_0_0, each τ_0_1, each τ_0_2, each τ_0_3> (@pack_guaranteed Pack{repeat each τ_0_0}) -> @pack_out Pack{repeat each τ_0_2} for <Pack{repeat each T}, Pack{repeat each T}, Pack{repeat each U}, Pack{repeat each U}>, %1 : $VariadicType<repeat each T>):
17+
// CHECK-LABEL: sil [ossa] @$s19pack_expansion_type12VariadicTypeV13takesFunction1tyqd__qd__Qp_txxQpXE_tRvd__lF : $@convention(method) <each T><each U> (@guaranteed @noescape @callee_guaranteed @substituted <each τ_0_0, each τ_0_1, each τ_0_2, each τ_0_3 where (repeat (each τ_0_0, each τ_0_1)) : Any, (repeat (each τ_0_2, each τ_0_3)) : Any> (@pack_guaranteed Pack{repeat each τ_0_0}) -> @pack_out Pack{repeat each τ_0_2} for <Pack{repeat each T}, Pack{repeat each T}, Pack{repeat each U}, Pack{repeat each U}>, VariadicType<repeat each T>) -> () {
18+
// CHECK: bb0(%0 : @guaranteed $@noescape @callee_guaranteed @substituted <each τ_0_0, each τ_0_1, each τ_0_2, each τ_0_3 where (repeat (each τ_0_0, each τ_0_1)) : Any, (repeat (each τ_0_2, each τ_0_3)) : Any> (@pack_guaranteed Pack{repeat each τ_0_0}) -> @pack_out Pack{repeat each τ_0_2} for <Pack{repeat each T}, Pack{repeat each T}, Pack{repeat each U}, Pack{repeat each U}>, %1 : $VariadicType<repeat each T>):
1919
public func takesFunction<each U>(t: (repeat each T) -> (repeat each U)) {}
2020
}
2121

@@ -43,3 +43,9 @@ func variadicMetatypes<each T>(_: repeat each T) {
4343
_ = ((repeat each T) -> ()).self
4444
_ = ((Int, repeat Array<each T>) -> ()).self
4545
}
46+
47+
// Mangling bugs with substitutions
48+
49+
// CHECK-LABEL: sil [ossa] @$s19pack_expansion_type18sameExpansionTwice2us05more_G02vsyxxQp_xxQpq_q_QptRvzRv_r0_lF : $@convention(thin) <each U, each V> (@pack_guaranteed Pack{repeat each U}, @pack_guaranteed Pack{repeat each U}, @pack_guaranteed Pack{repeat each V}) -> () {
50+
public func sameExpansionTwice<each U, each V>(us: repeat each U, more_us: repeat each U, vs: repeat each V) {}
51+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-swift-emit-silgen -module-name parameterized -disable-availability-checking %s -enable-experimental-feature VariadicGenerics | %FileCheck %s
2+
3+
protocol P<A> {
4+
associatedtype A
5+
}
6+
7+
// The mangling for generalized existentials is buggy; we decide whether to
8+
// qualify the primary associated type requirement with a protocol or not
9+
// by looking at the first generic parameter of the outer generic context.
10+
11+
struct S1 {
12+
// CHECK-LABEL: sil hidden [ossa] @$s13parameterized2S1V1fAA1P_pSi1AAaEPRts_XPyF : $@convention(method) (S1) -> @out any P<Int> {
13+
func f() -> any P<Int> {}
14+
}
15+
16+
struct S2<T> {
17+
// CHECK-LABEL: sil hidden [ossa] @$s13parameterized2S2V1fAA1P_pSi1ARts_XPyF : $@convention(method) <T> (S2<T>) -> @out any P<Int> {
18+
func f() -> any P<Int> {}
19+
}
20+
21+
struct S3<each T> {
22+
// CHECK-LABEL: sil hidden [ossa] @$s13parameterized2S3V1fAA1P_pSi1AAaEPRts_XPyF : $@convention(method) <each T> (S3<repeat each T>) -> @out any P<Int> {
23+
func f() -> any P<Int> {}
24+
}

test/SILGen/variadic-generic-arguments.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %target-swift-emit-silgen -enable-experimental-feature VariadicGenerics %s | %FileCheck %s
2+
3+
// Because of -enable-experimental-feature VariadicGenerics
24
// REQUIRES: asserts
35

46
// CHECK-LABEL: @$s4main14receive_simpleyyxxQpRvzlF : $@convention(thin) <each T> (@pack_guaranteed Pack{repeat each T}) -> () {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-emit-silgen -enable-experimental-feature VariadicGenerics %s | %FileCheck %s
2+
3+
// Because of -enable-experimental-feature VariadicGenerics
4+
// REQUIRES: asserts
5+
6+
public struct G<T> {}
7+
8+
// CHECK-LABEL: sil [ossa] @$s4main6caller2fnyyAA1GVyxGxQpXE_tRvzlF : $@convention(thin) <each T> (@guaranteed @noescape @callee_guaranteed @substituted <each τ_0_0, each τ_0_1 where (repeat (each τ_0_0, each τ_0_1)) : Any> (@pack_guaranteed Pack{repeat G<each τ_0_0>}) -> () for <Pack{repeat each T}, Pack{repeat each T}>) -> () {
9+
public func caller<each T>(fn: (repeat G<each T>) -> ()) {
10+
fn(repeat G<each T>())
11+
}

test/SILGen/variadic-generic-results.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %target-swift-emit-silgen -enable-experimental-feature VariadicGenerics %s | %FileCheck %s
2+
3+
// Because of -enable-experimental-feature VariadicGenerics
24
// REQUIRES: asserts
35

46
func sequence() {}

test/SILGen/variadic-generic-tuples.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %target-swift-emit-silgen -enable-experimental-feature VariadicGenerics %s | %FileCheck %s
2+
3+
// Because of -enable-experimental-feature VariadicGenerics
24
// REQUIRES: asserts
35

46
func takeAny(_ arg: Any) {}
@@ -165,3 +167,40 @@ func wrapTupleElements<each T>(_ value: repeat each T) -> (repeat Wrapper<each T
165167
// CHECK-NEXT: [[RET:%.*]] = tuple ()
166168
// CHECK-NEXT: return [[RET]] : $()
167169
}
170+
171+
// CHECK-LABEL: sil hidden [ossa] @$s4main20projectTupleElementsyyAA7WrapperVyxGxQpRvzlF : $@convention(thin) <each T> (@pack_guaranteed Pack{repeat Wrapper<each T>}) -> () {
172+
func projectTupleElements<each T>(_ value: repeat Wrapper<each T>) {
173+
// CHECK: [[VAR:%.*]] = alloc_stack [lexical] $(repeat each T)
174+
175+
// CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Word, 0
176+
// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Word, 1
177+
// CHECK-NEXT: [[PACK_LEN:%.*]] = pack_length $Pack{repeat each T}
178+
179+
// CHECK-NEXT: br bb1([[ZERO]] : $Builtin.Word)
180+
181+
// CHECK: bb1([[INDEX:%.*]] : $Builtin.Word):
182+
// CHECK-NEXT: [[INDEX_EQ_LEN:%.*]] = builtin "cmp_eq_Word"([[INDEX]] : $Builtin.Word, [[PACK_LEN]] : $Builtin.Word)
183+
// CHECK-NEXT: cond_br [[INDEX_EQ_LEN]], bb3, bb2
184+
185+
// CHECK: bb2:
186+
// CHECK-NEXT: [[CUR_INDEX:%.*]] = dynamic_pack_index [[INDEX]] of $Pack{repeat each T}
187+
// CHECK-NEXT: open_pack_element [[CUR_INDEX]] of <each T> at <Pack{repeat each T}>, shape $T, uuid "[[UUID:[0-9A-F-]*]]"
188+
// CHECK-NEXT: [[TUPLE_ELT_ADDR:%.*]] = tuple_pack_element_addr [[CUR_INDEX]] of [[VAR]] : $*(repeat each T) as $*@pack_element("[[UUID]]") T
189+
// CHECK-NEXT: [[VAL_ELT_ADDR:%.*]] = pack_element_get [[CUR_INDEX]] of %0 : $*Pack{repeat Wrapper<each T>} as $*Wrapper<@pack_element("[[UUID]]") T>
190+
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Wrapper<@pack_element("[[UUID]]") T>
191+
// CHECK-NEXT: copy_addr [[VAL_ELT_ADDR]] to [init] [[TEMP]] : $*Wrapper<@pack_element("[[UUID]]") T>
192+
// CHECK-NEXT: [[MEMBER:%.*]] = struct_element_addr [[TEMP]] : $*Wrapper<@pack_element("[[UUID]]") T>, #Wrapper.value
193+
// CHECK-NEXT: copy_addr [[MEMBER]] to [init] [[TUPLE_ELT_ADDR]] : $*@pack_element("[[UUID]]") T
194+
// CHECK-NEXT: destroy_addr [[TEMP]] : $*Wrapper<@pack_element("[[UUID]]") T>
195+
// CHECK-NEXT: dealloc_stack [[TEMP]] : $*Wrapper<@pack_element("[[UUID]]") T>
196+
// CHECK-NEXT: [[NEXT_INDEX:%.*]] = builtin "add_Word"([[INDEX]] : $Builtin.Word, [[ONE]] : $Builtin.Word) : $Builtin.Word
197+
// CHECK-NEXT: br bb1([[NEXT_INDEX]] : $Builtin.Word)
198+
199+
// CHECK: bb3:
200+
// CHECK-NEXT: destroy_addr [[VAR]] : $*(repeat each T)
201+
// CHECK-NEXT: dealloc_stack [[VAR]] : $*(repeat each T)
202+
// CHECK-NEXT: [[RET:%.*]] = tuple ()
203+
// CHECK-NEXT: return [[RET]] : $()
204+
205+
let tuple = (repeat (each value).value)
206+
}

0 commit comments

Comments
 (0)