Skip to content

Commit b9b21fc

Browse files
committed
[CSSimplify] Detect and diagnose attempts to specialize types with invalid number of arguments
1 parent be4df5a commit b9b21fc

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13631,6 +13631,7 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1363113631
}
1363213632

1363313633
// Map the generic parameters we have over to their opened types.
13634+
bool hasParameterPack = false;
1363413635
SmallVector<Type, 2> openedGenericParams;
1363513636
auto genericParamDepth = genericParams->getParams()[0]->getDepth();
1363613637
for (const auto &openedType : openedTypes) {
@@ -13652,6 +13653,7 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1365213653

1365313654
auto *expansion = PackExpansionType::get(patternType, shapeType);
1365413655
openedGenericParams.push_back(expansion);
13656+
hasParameterPack = true;
1365513657
} else {
1365613658
openedGenericParams.push_back(Type(openedType.second));
1365713659
}
@@ -13674,8 +13676,15 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1367413676
auto specializedArgs = type2->castTo<PackType>()->getElementTypes();
1367513677
PackMatcher matcher(openedGenericParams, specializedArgs, getASTContext(),
1367613678
isPackExpansionType);
13677-
if (matcher.match())
13678-
return SolutionKind::Error;
13679+
if (matcher.match()) {
13680+
if (!shouldAttemptFixes())
13681+
return SolutionKind::Error;
13682+
13683+
auto *fix = IgnoreGenericSpecializationArityMismatch::create(
13684+
*this, decl, openedGenericParams.size(), specializedArgs.size(),
13685+
hasParameterPack, getConstraintLocator(locator));
13686+
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
13687+
}
1367913688

1368013689
// Bind the opened generic parameters to the specialization arguments.
1368113690
for (const auto &pair : matcher.pairs) {

test/Macros/macro_and_typealias.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,21 @@
77
@freestanding(expression) public macro Print<each Value>(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
88
@freestanding(expression) public macro OtherPrint<each Value>(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
99
@freestanding(expression) public macro ConcretePrint(_ value: Any) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
10+
@freestanding(expression) public macro MultiPrint(_ value: Any) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
1011

1112
public struct Printer<Value> {
1213
init(_: (Value) -> Void) {}
1314
}
1415

16+
public struct MultiPrinter<T, U> {
17+
// expected-note@-1 {{'T' declared as parameter to type 'MultiPrinter'}}
18+
// expected-note@-2 {{'U' declared as parameter to type 'MultiPrinter'}}
19+
}
20+
1521
typealias Print = Printer
1622
typealias OtherPrint<T> = Printer<T>
1723
typealias ConcretePrint = Printer<Any>
24+
typealias MultiPrint = MultiPrinter
1825

1926
struct Test {
2027
struct Object {
@@ -26,6 +33,10 @@ struct Test {
2633
compute(root: $0, \.prop)
2734
}
2835

36+
let _ = Print<Object, Int> {
37+
// expected-error@-1 {{generic type 'Print' specialized with too many type parameters (got 2, but expected 1)}}
38+
}
39+
2940
let _ = OtherPrint<Object> { // Ok
3041
compute(root: $0, \.prop)
3142
}
@@ -34,6 +45,11 @@ struct Test {
3445
compute(root: $0, \.prop) // expected-error {{value of type 'Any' has no member 'prop'}}
3546
// expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
3647
}
48+
49+
let _ = MultiPrint<Int>()
50+
// expected-error@-1 {{generic type 'MultiPrint' specialized with too few type parameters (got 1, but expected 2)}}
51+
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
52+
// expected-error@-3 {{generic parameter 'U' could not be inferred}}
3753
}
3854

3955
func compute<R, V>(root: R, _: KeyPath<R, V>) {}

test/Macros/macros_diagnostics.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ macro genericDeclMacro<T: Numeric, U: Numeric>(_ x: T, _ y: U)
9696
// expected-note @-2 {{where 'U' = 'String'}}
9797

9898
func testDiags(a: Int, b: Int) {
99-
// FIXME: Bad diagnostic.
100-
let s = #stringify<Int, Int>(a + b) // expected-error{{type of expression is ambiguous without a type annotation}}
99+
let s = #stringify<Int, Int>(a + b) // expected-error{{generic type 'stringify' specialized with too many type parameters (got 2, but expected 1)}}
101100

102101
_ = #stringify()
103102
// expected-error@-1{{missing argument for parameter #1 in macro expansion}}

0 commit comments

Comments
 (0)