Skip to content

Commit ad3fec4

Browse files
authored
Merge pull request #64299 from xedin/variadic-generics-crash-in-resolveOverload
[ConstraintSystem] Handle pack expansion materialization on l-value base
2 parents 1ead872 + a7e49ee commit ad3fec4

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

lib/Sema/CSApply.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,14 @@ namespace {
34153415
}
34163416

34173417
case OverloadChoiceKind::MaterializePack: {
3418+
auto baseTy = solution.getResolvedType(base);
3419+
3420+
// Load the base tuple if necessary, materialization
3421+
// operates on r-value types only.
3422+
if (baseTy->is<LValueType>())
3423+
base = coerceToType(base, baseTy->getRValueType(),
3424+
cs.getConstraintLocator(base));
3425+
34183426
auto packType = solution.getResolvedType(expr);
34193427
return cs.cacheType(
34203428
MaterializePackExpr::create(cs.getASTContext(),

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3506,7 +3506,13 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
35063506
break;
35073507

35083508
case OverloadChoiceKind::MaterializePack: {
3509-
auto *tuple = choice.getBaseType()->castTo<TupleType>();
3509+
// Since `.element` is only applicable to single element tuples at the
3510+
// moment we can just look through l-value base to load it.
3511+
//
3512+
// In the future, _if_ the syntax allows for multiple expansions
3513+
// this code would have to be adjusted to project l-value from the
3514+
// base type just like TupleIndex does.
3515+
auto tuple = choice.getBaseType()->getRValueType()->castTo<TupleType>();
35103516
auto *expansion = tuple->getElementType(0)->castTo<PackExpansionType>();
35113517
adjustedRefType = expansion->getPatternType();
35123518
refType = adjustedRefType;

test/Constraints/pack-expansion-expressions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,21 @@ do {
178178
test[data: repeat each args, "", 42] = 0
179179
}
180180
}
181+
182+
func test_pack_expansion_materialization_from_lvalue_base() {
183+
struct Data<Value> {}
184+
185+
struct Test<each T> {
186+
var data: (repeat Data<each T>)
187+
188+
init() {
189+
self.data = (repeat Data<each T>())
190+
_ = (repeat each data.element) // Ok
191+
192+
var tmp = (repeat Data<each T>()) // expected-warning {{never mutated}}
193+
_ = (repeat each tmp.element) // Ok
194+
195+
// TODO: Add subscript test-case when syntax is supported.
196+
}
197+
}
198+
}

0 commit comments

Comments
 (0)