@@ -2425,6 +2425,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
2425
2425
case ConstraintKind::SyntacticElement:
2426
2426
case ConstraintKind::BindTupleOfFunctionParams:
2427
2427
case ConstraintKind::PackElementOf:
2428
+ case ConstraintKind::ShapeOf:
2428
2429
llvm_unreachable("Bad constraint kind in matchTupleTypes()");
2429
2430
}
2430
2431
@@ -2597,6 +2598,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
2597
2598
case ConstraintKind::SyntacticElement:
2598
2599
case ConstraintKind::BindTupleOfFunctionParams:
2599
2600
case ConstraintKind::PackElementOf:
2601
+ case ConstraintKind::ShapeOf:
2600
2602
return true;
2601
2603
}
2602
2604
@@ -3013,6 +3015,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3013
3015
case ConstraintKind::SyntacticElement:
3014
3016
case ConstraintKind::BindTupleOfFunctionParams:
3015
3017
case ConstraintKind::PackElementOf:
3018
+ case ConstraintKind::ShapeOf:
3016
3019
llvm_unreachable("Not a relational constraint");
3017
3020
}
3018
3021
@@ -6366,6 +6369,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
6366
6369
case ConstraintKind::SyntacticElement:
6367
6370
case ConstraintKind::BindTupleOfFunctionParams:
6368
6371
case ConstraintKind::PackElementOf:
6372
+ case ConstraintKind::ShapeOf:
6369
6373
llvm_unreachable("Not a relational constraint");
6370
6374
}
6371
6375
}
@@ -7442,17 +7446,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifySubclassOfConstraint(
7442
7446
return SolutionKind::Solved;
7443
7447
}
7444
7448
7445
- auto formUnsolved = [&](bool activate = false ) {
7449
+ auto formUnsolved = [&]() {
7446
7450
// If we're supposed to generate constraints, do so.
7447
7451
if (flags.contains(TMF_GenerateConstraints)) {
7448
- auto *conformance = Constraint::create(
7452
+ auto *subclassOf = Constraint::create(
7449
7453
*this, ConstraintKind::SubclassOf, type, classType,
7450
7454
getConstraintLocator(locator));
7451
7455
7452
- addUnsolvedConstraint(conformance);
7453
- if (activate)
7454
- activateConstraint(conformance);
7455
-
7456
+ addUnsolvedConstraint(subclassOf);
7456
7457
return SolutionKind::Solved;
7457
7458
}
7458
7459
@@ -12510,6 +12511,74 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
12510
12511
return SolutionKind::Solved;
12511
12512
}
12512
12513
12514
+ static Type getReducedShape(Type type) {
12515
+ // Pack archetypes know their reduced shape
12516
+ if (auto *packArchetype = type->getAs<PackArchetypeType>())
12517
+ return packArchetype->getShape();
12518
+
12519
+ // Reduced shape of pack is computed recursively
12520
+ if (auto *packType = type->getAs<PackType>()) {
12521
+ auto &ctx = type->getASTContext();
12522
+ SmallVector<Type, 2> elts;
12523
+
12524
+ for (auto elt : packType->getElementTypes()) {
12525
+ // T... => shape(T)...
12526
+ if (auto *packExpansionType = elt->getAs<PackExpansionType>()) {
12527
+ auto shapeType = getReducedShape(packExpansionType->getCountType());
12528
+ assert(shapeType && "Should not end up here if pack type's shape "
12529
+ "is still potentially unknown");
12530
+ elts.push_back(PackExpansionType::get(shapeType, shapeType));
12531
+ }
12532
+
12533
+ // Use () as a placeholder for scalar shape
12534
+ elts.push_back(ctx.TheEmptyTupleType);
12535
+ }
12536
+
12537
+ return PackType::get(ctx, elts);
12538
+ }
12539
+
12540
+ // Getting the shape of any other type is an error.
12541
+ return Type();
12542
+ }
12543
+
12544
+ ConstraintSystem::SolutionKind ConstraintSystem::simplifyShapeOfConstraint(
12545
+ Type type1, Type type2, TypeMatchOptions flags,
12546
+ ConstraintLocatorBuilder locator) {
12547
+ // Recursively replace all type variables with fixed bindings if
12548
+ // possible.
12549
+ type1 = simplifyType(type1, flags);
12550
+
12551
+ auto formUnsolved = [&]() {
12552
+ // If we're supposed to generate constraints, do so.
12553
+ if (flags.contains(TMF_GenerateConstraints)) {
12554
+ auto *shapeOf = Constraint::create(
12555
+ *this, ConstraintKind::ShapeOf, type1, type2,
12556
+ getConstraintLocator(locator));
12557
+
12558
+ addUnsolvedConstraint(shapeOf);
12559
+ return SolutionKind::Solved;
12560
+ }
12561
+
12562
+ return SolutionKind::Unsolved;
12563
+ };
12564
+
12565
+ // We can't compute a reduced shape if the input type still
12566
+ // contains type variables that might bind to pack archetypes.
12567
+ SmallPtrSet<TypeVariableType *, 2> typeVars;
12568
+ type1->getTypeVariables(typeVars);
12569
+ for (auto *typeVar : typeVars) {
12570
+ if (typeVar->getImpl().canBindToPack())
12571
+ return formUnsolved();
12572
+ }
12573
+
12574
+ if (Type shape = getReducedShape(type1)) {
12575
+ addConstraint(ConstraintKind::Bind, shape, type2, locator);
12576
+ return SolutionKind::Solved;
12577
+ }
12578
+
12579
+ return SolutionKind::Error;
12580
+ }
12581
+
12513
12582
static llvm::PointerIntPair<Type, 3, unsigned>
12514
12583
getBaseTypeForPointer(TypeBase *type) {
12515
12584
unsigned unwrapCount = 0;
@@ -13847,6 +13916,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
13847
13916
case ConstraintKind::PackElementOf:
13848
13917
return simplifyPackElementOfConstraint(first, second, subflags, locator);
13849
13918
13919
+ case ConstraintKind::ShapeOf:
13920
+ return simplifyShapeOfConstraint(first, second, subflags, locator);
13921
+
13850
13922
case ConstraintKind::ValueMember:
13851
13923
case ConstraintKind::UnresolvedValueMember:
13852
13924
case ConstraintKind::ValueWitness:
@@ -14010,8 +14082,18 @@ void ConstraintSystem::addConstraint(Requirement req,
14010
14082
bool conformsToAnyObject = false;
14011
14083
Optional<ConstraintKind> kind;
14012
14084
switch (req.getKind()) {
14013
- case RequirementKind::SameShape:
14014
- llvm_unreachable("Same-shape requirement not supported here");
14085
+ case RequirementKind::SameShape: {
14086
+ auto type1 = req.getFirstType();
14087
+ auto type2 = req.getSecondType();
14088
+
14089
+ // FIXME: Locator for diagnostics
14090
+ auto typeVar = createTypeVariable(getConstraintLocator(locator),
14091
+ TVO_CanBindToPack);
14092
+
14093
+ addConstraint(ConstraintKind::ShapeOf, type1, typeVar, locator);
14094
+ addConstraint(ConstraintKind::ShapeOf, type2, typeVar, locator);
14095
+ return;
14096
+ }
14015
14097
14016
14098
case RequirementKind::Conformance:
14017
14099
kind = ConstraintKind::ConformsTo;
@@ -14421,6 +14503,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
14421
14503
return simplifyPackElementOfConstraint(
14422
14504
constraint.getFirstType(), constraint.getSecondType(), /*flags*/None,
14423
14505
constraint.getLocator());
14506
+
14507
+ case ConstraintKind::ShapeOf:
14508
+ return simplifyShapeOfConstraint(
14509
+ constraint.getFirstType(), constraint.getSecondType(), /*flags*/ None,
14510
+ constraint.getLocator());
14424
14511
}
14425
14512
14426
14513
llvm_unreachable("Unhandled ConstraintKind in switch.");
0 commit comments