Skip to content

Commit d357315

Browse files
committed
[ConstraintSystem] Handle typealiases in ExplicitGenericArguments
constraint simplification.
1 parent eb858d9 commit d357315

File tree

3 files changed

+43
-51
lines changed

3 files changed

+43
-51
lines changed

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,22 +1808,14 @@ namespace {
18081808
}
18091809

18101810
if (AnyMetatypeType *meta = baseTy->getAs<AnyMetatypeType>()) {
1811-
if (BoundGenericType *bgt
1812-
= meta->getInstanceType()->getAs<BoundGenericType>()) {
1813-
auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr());
1814-
if (addSpecializationConstraint(overloadLocator, bgt,
1815-
expr->getUnresolvedParams())) {
1816-
return Type();
1817-
}
1818-
1819-
return baseTy;
1820-
} else {
1821-
de.diagnose(expr->getSubExpr()->getLoc(), diag::not_a_generic_type,
1822-
meta->getInstanceType());
1823-
de.diagnose(expr->getLAngleLoc(),
1824-
diag::while_parsing_as_left_angle_bracket);
1811+
auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr());
1812+
if (addSpecializationConstraint(overloadLocator,
1813+
meta->getInstanceType(),
1814+
expr->getUnresolvedParams())) {
18251815
return Type();
18261816
}
1817+
1818+
return baseTy;
18271819
}
18281820

18291821
// FIXME: If the base type is a type variable, constrain it to a metatype

lib/Sema/CSSimplify.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13493,18 +13493,32 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1349313493
if (simplifiedBoundType->isTypeVariableOrMember())
1349413494
return formUnsolved();
1349513495

13496-
// If the overload hasn't been resolved, we can't simplify this constraint.
13497-
auto overloadLocator = getCalleeLocator(getConstraintLocator(locator));
13498-
auto selectedOverload = findSelectedOverloadFor(overloadLocator);
13499-
if (!selectedOverload)
13500-
return formUnsolved();
13496+
ValueDecl *decl;
13497+
SmallVector<OpenedType, 2> openedTypes;
13498+
if (auto *bound = dyn_cast<TypeAliasType>(type1.getPointer())) {
13499+
decl = bound->getDecl();
13500+
for (auto argType : bound->getDirectGenericArgs()) {
13501+
auto *typeVar = argType->getAs<TypeVariableType>();
13502+
auto *genericParam = typeVar->getImpl().getGenericParameter();
13503+
openedTypes.push_back({genericParam, typeVar});
13504+
}
13505+
} else {
13506+
// If the overload hasn't been resolved, we can't simplify this constraint.
13507+
auto overloadLocator = getCalleeLocator(getConstraintLocator(locator));
13508+
auto selectedOverload = findSelectedOverloadFor(overloadLocator);
13509+
if (!selectedOverload)
13510+
return formUnsolved();
1350113511

13502-
auto overloadChoice = selectedOverload->choice;
13503-
if (!overloadChoice.isDecl()) {
13504-
return SolutionKind::Error;
13512+
auto overloadChoice = selectedOverload->choice;
13513+
if (!overloadChoice.isDecl()) {
13514+
return SolutionKind::Error;
13515+
}
13516+
13517+
decl = overloadChoice.getDecl();
13518+
auto openedOverloadTypes = getOpenedTypes(overloadLocator);
13519+
openedTypes.append(openedOverloadTypes.begin(), openedOverloadTypes.end());
1350513520
}
1350613521

13507-
auto decl = overloadChoice.getDecl();
1350813522
auto genericContext = decl->getAsGenericContext();
1350913523
if (!genericContext)
1351013524
return SolutionKind::Error;
@@ -13518,7 +13532,7 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1351813532
// Map the generic parameters we have over to their opened types.
1351913533
SmallVector<Type, 2> openedGenericParams;
1352013534
auto genericParamDepth = genericParams->getParams()[0]->getDepth();
13521-
for (const auto &openedType : getOpenedTypes(overloadLocator)) {
13535+
for (const auto &openedType : openedTypes) {
1352213536
if (openedType.first->getDepth() == genericParamDepth) {
1352313537
// A generic argument list containing pack references expects
1352413538
// those packs to be wrapped in pack expansion types. If this

test/decl/typealias/generic.swift

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
struct MyType<TyA, TyB> { // expected-note {{generic type 'MyType' declared here}}
44
// expected-note @-1 {{arguments to generic parameter 'TyB' ('S' and 'Int') are expected to be equal}}
5-
// expected-note @-2 6 {{arguments to generic parameter 'TyA' ('Float' and 'Int') are expected to be equal}}
6-
// expected-note @-3 2 {{arguments to generic parameter 'TyA' ('Float' and 'Double') are expected to be equal}}
7-
// expected-note @-4 2 {{arguments to generic parameter 'TyB' ('Int' and 'Float') are expected to be equal}}
8-
// expected-note @-5 2 {{arguments to generic parameter 'TyB' ('Double' and 'Float') are expected to be equal}}
5+
96
var a : TyA, b : TyB
107
}
118

@@ -255,23 +252,13 @@ let _: ConcreteStruct.O<Int> = ConcreteStruct.O(123)
255252
let _: ConcreteStruct.O<Int> = ConcreteStruct.O<Int>(123)
256253

257254
// Qualified lookup of generic typealiases nested inside generic contexts
258-
//
259-
// FIXME marks cases which still don't work correctly, and either produce a
260-
// spurious diagnostic, or are actually invalid and do not diagnose.
261-
//
262-
// This occurs because the constraint solver does the wrong thing with an
263-
// UnresolvedSpecializeExpr applied to a generic typealias.
264-
//
265-
// In the other cases, we manage to fold the UnresolvedSpecializeExpr in the
266-
// precheckExpression() phase, which handles generic typealiases correctly.
267255

268256
do {
269-
let x1 = GenericClass.TA<Float>(a: 4.0, b: 1) // FIXME
270-
let x2 = GenericClass.TA<Float>(a: 1, b: 4.0) // FIXME
257+
let x1 = GenericClass.TA<Float>(a: 4.0, b: 1)
258+
let x2 = GenericClass.TA<Float>(a: 1, b: 4.0)
271259

272-
// FIXME: Should not diagnose
273-
let _: MyType<Double, Float> = x1 // expected-error {{cannot assign value of type 'MyType<Float, Int>' to type 'MyType<Double, Float>'}}
274-
let _: MyType<Int, Float> = x2 // expected-error {{cannot assign value of type 'MyType<Float, Double>' to type 'MyType<Int, Float>'}}
260+
let _: MyType<Double, Float> = x1
261+
let _: MyType<Int, Float> = x2
275262
}
276263

277264
let _ = GenericClass<Int>.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
@@ -284,12 +271,11 @@ let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1)
284271
let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0)
285272

286273
do {
287-
let x1: GenericClass.TA = GenericClass.TA<Float>(a: 4.0, b: 1) // FIXME
288-
let x2: GenericClass.TA = GenericClass.TA<Float>(a: 1, b: 4.0) // FIXME
274+
let x1: GenericClass.TA = GenericClass.TA<Float>(a: 4.0, b: 1)
275+
let x2: GenericClass.TA = GenericClass.TA<Float>(a: 1, b: 4.0)
289276

290-
// FIXME: Should not diagnose
291-
let _: MyType<Double, Float> = x1 // expected-error {{cannot assign value of type 'MyType<Float, Int>' to type 'MyType<Double, Float>'}}
292-
let _: MyType<Int, Float> = x2 // expected-error {{cannot assign value of type 'MyType<Float, Double>' to type 'MyType<Int, Float>'}}
277+
let _: MyType<Double, Float> = x1
278+
let _: MyType<Int, Float> = x2
293279
}
294280

295281
let _: GenericClass.TA = GenericClass<Int>.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
@@ -301,8 +287,8 @@ let _: GenericClass.TA = GenericClass<Int>.TA<Float>(a: 1, b: 4.0)
301287
let _: GenericClass<Int>.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
302288
let _: GenericClass<Int>.TA = GenericClass.TA(a: 1, b: 4.0)
303289

304-
let _: GenericClass<Int>.TA = GenericClass.TA<Float>(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType<Float, Int>' to type 'MyType<Int, Int>'}}
305-
let _: GenericClass<Int>.TA = GenericClass.TA<Float>(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType<Float, Double>' to type 'MyType<Int, Double>'}}
290+
let _: GenericClass<Int>.TA = GenericClass.TA<Float>(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
291+
let _: GenericClass<Int>.TA = GenericClass.TA<Float>(a: 1, b: 4.0)
306292

307293
let _: GenericClass<Int>.TA = GenericClass<Int>.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
308294
let _: GenericClass<Int>.TA = GenericClass<Int>.TA(a: 1, b: 4.0)
@@ -313,8 +299,8 @@ let _: GenericClass<Int>.TA = GenericClass<Int>.TA<Float>(a: 1, b: 4.0)
313299
let _: GenericClass<Int>.TA<Float> = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
314300
let _: GenericClass<Int>.TA<Float> = GenericClass.TA(a: 1, b: 4.0)
315301

316-
let _: GenericClass<Int>.TA<Float> = GenericClass.TA<Float>(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType<Float, Float>' to type 'GenericClass<Int>.TA<Float>' (aka 'MyType<Int, Float>')}}
317-
let _: GenericClass<Int>.TA<Float> = GenericClass.TA<Float>(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType<Float, Float>' to type 'GenericClass<Int>.TA<Float>' (aka 'MyType<Int, Float>')}}
302+
let _: GenericClass<Int>.TA<Float> = GenericClass.TA<Float>(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
303+
let _: GenericClass<Int>.TA<Float> = GenericClass.TA<Float>(a: 1, b: 4.0)
318304

319305
let _: GenericClass<Int>.TA<Float> = GenericClass<Int>.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
320306
let _: GenericClass<Int>.TA<Float> = GenericClass<Int>.TA(a: 1, b: 4.0)

0 commit comments

Comments
 (0)