Skip to content

Commit fdfe507

Browse files
committed
Merge remote-tracking branch 'slavapestov/misc-variadic-generic-fixes'
2 parents ffb8a3c + 39a220e commit fdfe507

File tree

7 files changed

+91
-7
lines changed

7 files changed

+91
-7
lines changed

lib/AST/ASTMangler.cpp

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

31653165
/// Determine whether an associated type reference into the given set of
31663166
/// protocols is unambiguous.
3167-
static bool associatedTypeRefIsUnambiguous(ArrayRef<ProtocolDecl *> protocols) {
3167+
static bool associatedTypeRefIsUnambiguous(GenericSignature sig, Type t) {
3168+
// FIXME: This should be an assertion.
3169+
if (!sig->isValidTypeParameter(t))
3170+
return false;
3171+
31683172
unsigned numProtocols = 0;
3169-
for (auto proto : protocols) {
3173+
for (auto proto : sig->getRequiredProtocols(t)) {
31703174
// Skip marker protocols, which cannot have associated types.
31713175
if (proto->isMarkerProtocol())
31723176
continue;
@@ -3186,7 +3190,7 @@ ASTMangler::dropProtocolFromAssociatedType(DependentMemberType *dmt,
31863190
auto baseTy = dmt->getBase();
31873191
bool unambiguous =
31883192
(!dmt->getAssocType() ||
3189-
associatedTypeRefIsUnambiguous(sig->getRequiredProtocols(baseTy)));
3193+
associatedTypeRefIsUnambiguous(sig, baseTy));
31903194

31913195
if (auto *baseDMT = baseTy->getAs<DependentMemberType>())
31923196
baseTy = dropProtocolFromAssociatedType(baseDMT, sig);
@@ -3223,7 +3227,7 @@ void ASTMangler::appendAssociatedTypeName(DependentMemberType *dmt,
32233227
// associated type name by protocol.
32243228
if (!OptimizeProtocolNames || !sig ||
32253229
!associatedTypeRefIsUnambiguous(
3226-
sig->getRequiredProtocols(dmt->getBase()))) {
3230+
sig, dmt->getBase())) {
32273231
appendAnyGenericType(assocTy->getProtocol());
32283232
}
32293233
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
@@ -2392,7 +2392,6 @@ NodePointer Demangler::demangleArchetype() {
23922392
NodePointer PatternTy = popTypeAndGetChild();
23932393
NodePointer PackExpansionTy = createType(
23942394
createWithChildren(Node::Kind::PackExpansion, PatternTy, CountTy));
2395-
addSubstitution(PackExpansionTy);
23962395
return PackExpansionTy;
23972396
}
23982397
case 'P':

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 6 additions & 1 deletion
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);

test/SILGen/pack_expansion_type.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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-tuples.swift

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

0 commit comments

Comments
 (0)