Skip to content

Commit c93a65b

Browse files
committed
[ConstraintSystem] Use an explicit generic argument constraint for
UnresolvedSpecializeExpr. The eager generic argument matching code in CSGen for unresolved specializations was incorrect because it didn't account for parameter packs. Fortunately, a constraint to delay explicit generic argument matching already exists for macros. Use it here. (cherry picked from commit eb858d9)
1 parent 061d92e commit c93a65b

File tree

3 files changed

+39
-44
lines changed

3 files changed

+39
-44
lines changed

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,49 +1810,11 @@ namespace {
18101810
if (AnyMetatypeType *meta = baseTy->getAs<AnyMetatypeType>()) {
18111811
if (BoundGenericType *bgt
18121812
= meta->getInstanceType()->getAs<BoundGenericType>()) {
1813-
ArrayRef<Type> typeVars = bgt->getGenericArgs();
1814-
auto specializations = expr->getUnresolvedParams();
1815-
1816-
// If we have too many generic arguments, complain.
1817-
if (specializations.size() > typeVars.size()) {
1818-
de.diagnose(expr->getSubExpr()->getLoc(),
1819-
diag::type_parameter_count_mismatch,
1820-
bgt->getDecl()->getName(), typeVars.size(),
1821-
specializations.size(),
1822-
/*too many arguments*/ false,
1823-
/*isParameterPack?*/ false)
1824-
.highlight(
1825-
SourceRange(expr->getLAngleLoc(), expr->getRAngleLoc()));
1826-
de.diagnose(bgt->getDecl(), diag::kind_declname_declared_here,
1827-
DescriptiveDeclKind::GenericType,
1828-
bgt->getDecl()->getName());
1813+
auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr());
1814+
if (addSpecializationConstraint(overloadLocator, bgt,
1815+
expr->getUnresolvedParams())) {
18291816
return Type();
18301817
}
1831-
1832-
// Bind the specified generic arguments to the type variables in the
1833-
// open type.
1834-
auto *const locator = CS.getConstraintLocator(expr);
1835-
auto options =
1836-
TypeResolutionOptions(TypeResolverContext::InExpression);
1837-
for (size_t i = 0, e = specializations.size(); i < e; ++i) {
1838-
PackExpansionExpr *elementEnv = nullptr;
1839-
if (!PackElementEnvironments.empty()) {
1840-
options |= TypeResolutionFlags::AllowPackReferences;
1841-
elementEnv = PackElementEnvironments.back();
1842-
}
1843-
1844-
const auto result = TypeResolution::resolveContextualType(
1845-
specializations[i], CS.DC, options,
1846-
// Introduce type variables for unbound generics.
1847-
OpenUnboundGenericType(CS, locator),
1848-
HandlePlaceholderType(CS, locator),
1849-
OpenPackElementType(CS, locator, elementEnv));
1850-
if (result->hasError())
1851-
return Type();
1852-
1853-
CS.addConstraint(ConstraintKind::Bind, typeVars[i], result,
1854-
locator);
1855-
}
18561818

18571819
return baseTy;
18581820
} else {

lib/Sema/CSSimplify.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13523,7 +13523,26 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1352313523
auto genericParamDepth = genericParams->getParams()[0]->getDepth();
1352413524
for (const auto &openedType : getOpenedTypes(overloadLocator)) {
1352513525
if (openedType.first->getDepth() == genericParamDepth) {
13526-
openedGenericParams.push_back(Type(openedType.second));
13526+
// A generic argument list containing pack references expects
13527+
// those packs to be wrapped in pack expansion types. If this
13528+
// opened type represents the generic argument for a parameter
13529+
// pack, wrap generate the appropriate shape constraints and
13530+
// add a pack expansion to the argument list.
13531+
if (openedType.first->isParameterPack()) {
13532+
auto patternType = openedType.second;
13533+
auto *shapeLoc = getConstraintLocator(
13534+
locator.withPathElement(ConstraintLocator::PackShape));
13535+
auto *shapeType = createTypeVariable(shapeLoc,
13536+
TVO_CanBindToPack |
13537+
TVO_CanBindToHole);
13538+
addConstraint(ConstraintKind::ShapeOf,
13539+
shapeType, patternType, shapeLoc);
13540+
13541+
auto *expansion = PackExpansionType::get(patternType, shapeType);
13542+
openedGenericParams.push_back(expansion);
13543+
} else {
13544+
openedGenericParams.push_back(Type(openedType.second));
13545+
}
1352713546
}
1352813547
}
1352913548
assert(openedGenericParams.size() == genericParams->size());

test/Macros/macro_expand_variadic.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,32 @@
22

33
// RUN: %empty-directory(%t)
44
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/variadic_macros.swift -g -no-toolchain-stdlib-rpath
5-
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
6-
// RUN: %target-build-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5
5+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
6+
// RUN: %target-build-swift -Xfrontend -disable-availability-checking -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5
77
// RUN: %target-codesign %t/main
88
// RUN: %target-run %t/main | %FileCheck %s
99

1010
@freestanding(expression) macro print<each Value>(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
1111

12+
@freestanding(expression) macro Print<each Value>(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
13+
14+
struct Print<each Value> {
15+
init() {}
16+
}
17+
18+
func testAmbiguity() {
19+
let _ = Print<Int>()
20+
}
21+
1222
func testIt() {
1323
// CHECK: hello
1424
// CHECK: [1, 2, 3, 4, 5]
1525
#print("hello", [1, 2, 3, 4, 5])
1626

27+
// CHECK: hello
28+
// CHECK: [1, 2, 3, 4, 5]
29+
#print<String, [Int]>("hello", [1, 2, 3, 4, 5])
30+
1731
// CHECK: world
1832
#print("world")
1933
}

0 commit comments

Comments
 (0)