[CS] Distinguish locators for generic args in addSpecializationConstraint

Make sure we give each argument a different locator to ensure we
can correctly record any opened types.

rdar://153674889
This commit is contained in:
Hamish Knight
2025-06-14 15:25:26 +01:00
parent 0409102619
commit 4d654b271f
4 changed files with 33 additions and 4 deletions

View File

@@ -1933,7 +1933,11 @@ namespace {
SmallVector<Type, 2> specializationArgTypes;
auto options =
TypeResolutionOptions(TypeResolverContext::InExpression);
for (auto specializationArg : specializationArgs) {
ConstraintLocatorBuilder locBuilder(locator);
for (auto idx : indices(specializationArgs)) {
auto specializationArg = specializationArgs[idx];
auto argLocator =
locBuilder.withPathElement(LocatorPathElt::GenericArgument(idx));
PackExpansionExpr *elementEnv = nullptr;
if (!OuterExpansions.empty()) {
options |= TypeResolutionFlags::AllowPackReferences;
@@ -1942,9 +1946,9 @@ namespace {
auto result = TypeResolution::resolveContextualType(
specializationArg, CurDC, options,
// Introduce type variables for unbound generics.
OpenUnboundGenericType(CS, locator),
HandlePlaceholderType(CS, locator),
OpenPackElementType(CS, locator, elementEnv));
OpenUnboundGenericType(CS, argLocator),
HandlePlaceholderType(CS, argLocator),
OpenPackElementType(CS, argLocator, elementEnv));
if (result->hasError()) {
auto &ctxt = CS.getASTContext();
result = PlaceholderType::get(ctxt, specializationArg);

View File

@@ -22,3 +22,16 @@ func test(i: Int) {
// expected-error@-1{{external macro implementation type 'A.B' could not be found for macro 'resolve'; plugin for module 'A' not found}}
}
@freestanding(expression)
macro OverloadedMacro<T, U>(_ x: T, _ y: U) // expected-error {{requires a definition}} expected-note {{declared here}}
@freestanding(expression)
macro OverloadedMacro<T, U>(_ x: T, _ y: U, z: Int = 0) // expected-error {{requires a definition}}
// Make sure we don't crash.
func testOverloadedMacro() {
struct S<T> {} // expected-note 2{{'T' declared as parameter to type 'S'}}
_ = #OverloadedMacro<S, S>
// expected-error@-1 2{{generic parameter 'T' could not be inferred}}
// expected-error@-2 {{missing arguments for parameters #1, #2 in macro expansion}}
}

View File

@@ -76,3 +76,12 @@ do {
// expected-error@+1:13 {{cannot specialize non-generic type 'module<Swift>'}}{{none}}
func f(_: Swift<Int>) {}
}
func overloadedGenericFn<T, U>(_ x: T, _ y: U) {} // expected-note {{found this candidate}}
func overloadedGenericFn<T, U>(_ x: T, _ y: U, z: Int = 0) {} // expected-note {{found this candidate}}
// Make sure we don't crash.
func testSpecializedOverloaded() {
struct S<T> {}
_ = overloadedGenericFn<S, S> // expected-error {{no exact matches}}
}

View File

@@ -0,0 +1,3 @@
// {"signature":"swift::constraints::ConstraintSystem::recordOpenedTypes(swift::constraints::ConstraintLocatorBuilder, llvm::SmallVectorImpl<std::__1::pair<swift::GenericTypeParamType*, swift::TypeVariableType*>>&, bool)"}
// RUN: not %target-swift-frontend -typecheck %s
a<b> class a func a < c class b < d