Skip to content

Commit 189cf8e

Browse files
committed
[CSSimplify] Add special handling if specialized type comes from TypeExpr
Add a special case for `TypeExpr` due to i.e. context specialization, in such cases there is nothing for the solver to "open" so we need to form opened type map manually. Resolves: rdar://111059036 (cherry picked from commit e1e933c) (cherry picked from commit 5e30445)
1 parent 89245dd commit 189cf8e

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,15 @@ class ConstraintLocatorBuilder {
12711271
return ConstraintLocatorBuilder(this, newElt, newFlags);
12721272
}
12731273

1274+
/// Determine whether this locator builder points directly to a
1275+
/// given expression.
1276+
template <typename E>
1277+
bool directlyAt() const {
1278+
if (auto *expr = getAnchor().dyn_cast<Expr *>())
1279+
return isa<E>(expr) && hasEmptyPath();
1280+
return false;
1281+
}
1282+
12741283
/// Determine whether this builder has an empty path.
12751284
bool hasEmptyPath() const {
12761285
return !element;

lib/Sema/CSSimplify.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13547,6 +13547,38 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1354713547
auto *genericParam = typeVar->getImpl().getGenericParameter();
1354813548
openedTypes.push_back({genericParam, typeVar});
1354913549
}
13550+
} else if (locator.directlyAt<TypeExpr>()) {
13551+
auto *BGT = type1->getAs<BoundGenericType>();
13552+
if (!BGT)
13553+
return SolutionKind::Error;
13554+
13555+
decl = BGT->getDecl();
13556+
13557+
auto genericParams = BGT->getDecl()->getInnermostGenericParamTypes();
13558+
if (genericParams.size() != BGT->getGenericArgs().size())
13559+
return SolutionKind::Error;
13560+
13561+
for (unsigned i = 0, n = genericParams.size(); i != n; ++i) {
13562+
auto argType = BGT->getGenericArgs()[i];
13563+
if (auto *typeVar = argType->getAs<TypeVariableType>()) {
13564+
openedTypes.push_back({genericParams[i], typeVar});
13565+
} else {
13566+
// If we have a concrete substitution then we need to create
13567+
// a new type variable to be able to add it to the list as-if
13568+
// it is opened generic parameter type.
13569+
auto *GP = genericParams[i];
13570+
13571+
unsigned options = TVO_CanBindToNoEscape;
13572+
if (GP->isParameterPack())
13573+
options |= TVO_CanBindToPack;
13574+
13575+
auto *argVar = createTypeVariable(
13576+
getConstraintLocator(locator, LocatorPathElt::GenericArgument(i)),
13577+
options);
13578+
addConstraint(ConstraintKind::Bind, argVar, argType, locator);
13579+
openedTypes.push_back({GP, argVar});
13580+
}
13581+
}
1355013582
} else {
1355113583
// If the overload hasn't been resolved, we can't simplify this constraint.
1355213584
auto overloadLocator = getCalleeLocator(getConstraintLocator(locator));

test/decl/ext/specialize.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,15 @@ func testNestedExtensions() {
7474

7575
Tree<Int>.Branch<String>.Nest<Void>.Egg.twite()
7676
}
77+
78+
// rdar://111059036 - failed to produce a diagnostic in specialized extension
79+
struct Test {
80+
struct Key<Value> {}
81+
}
82+
83+
class State {
84+
}
85+
86+
extension Test.Key<State> {
87+
static let state = Self<State>()
88+
}

0 commit comments

Comments
 (0)