Skip to content

Commit db63c21

Browse files
authored
Merge pull request #41729 from DougGregor/opened-existential-cleanups
Opened existential cleanups
2 parents d5f63ee + 08e417c commit db63c21

File tree

4 files changed

+34
-36
lines changed

4 files changed

+34
-36
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,12 +3939,6 @@ class ConstraintSystem {
39393939
/// due to a change.
39403940
ConstraintList &getActiveConstraints() { return ActiveConstraints; }
39413941

3942-
void findConstraints(SmallVectorImpl<Constraint *> &found,
3943-
llvm::function_ref<bool(const Constraint &)> pred) {
3944-
filterConstraints(ActiveConstraints, pred, found);
3945-
filterConstraints(InactiveConstraints, pred, found);
3946-
}
3947-
39483942
/// Retrieve the representative of the equivalence class containing
39493943
/// this type variable.
39503944
TypeVariableType *getRepresentative(TypeVariableType *typeVar) const {
@@ -4117,16 +4111,6 @@ class ConstraintSystem {
41174111
/// into the worklist.
41184112
void addTypeVariableConstraintsToWorkList(TypeVariableType *typeVar);
41194113

4120-
static void
4121-
filterConstraints(ConstraintList &constraints,
4122-
llvm::function_ref<bool(const Constraint &)> pred,
4123-
SmallVectorImpl<Constraint *> &found) {
4124-
for (auto &constraint : constraints) {
4125-
if (pred(constraint))
4126-
found.push_back(&constraint);
4127-
}
4128-
}
4129-
41304114
public:
41314115

41324116
/// Coerce the given expression to an rvalue, if it isn't already.

lib/Sema/CSGen.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,11 +3733,9 @@ static bool generateInitPatternConstraints(
37333733
return cs.generateWrappedPropertyTypeConstraints(
37343734
wrappedVar, cs.getType(target.getAsExpr()), patternType);
37353735

3736-
if (!patternType->is<OpaqueTypeArchetypeType>()) {
3737-
// Add a conversion constraint between the types.
3738-
cs.addConstraint(ConstraintKind::Conversion, cs.getType(target.getAsExpr()),
3739-
patternType, locator, /*isFavored*/true);
3740-
}
3736+
// Add a conversion constraint between the types.
3737+
cs.addConstraint(ConstraintKind::Conversion, cs.getType(target.getAsExpr()),
3738+
patternType, locator, /*isFavored*/true);
37413739

37423740
return false;
37433741
}

lib/Sema/CSSimplify.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,8 @@ namespace {
13481348
static Optional<
13491349
std::tuple<TypeVariableType *, Type, OpenedExistentialAdjustments>>
13501350
shouldOpenExistentialCallArgument(
1351-
ValueDecl *callee, unsigned paramIdx, Type paramTy, Type argTy) {
1351+
ValueDecl *callee, unsigned paramIdx, Type paramTy, Type argTy,
1352+
Expr *argExpr, ConstraintSystem &cs) {
13521353
if (!callee)
13531354
return None;
13541355

@@ -1382,6 +1383,20 @@ shouldOpenExistentialCallArgument(
13821383
if (!paramTy->hasTypeVariable())
13831384
return None;
13841385

1386+
// An argument expression that explicitly coerces to an existential
1387+
// disables the implicit opening of the existential.
1388+
if (argExpr) {
1389+
if (auto argCoercion = dyn_cast<CoerceExpr>(
1390+
argExpr->getSemanticsProvidingExpr())) {
1391+
if (auto typeRepr = argCoercion->getCastTypeRepr()) {
1392+
if (auto toType = cs.getType(typeRepr)) {
1393+
if (toType->isAnyExistentialType())
1394+
return None;
1395+
}
1396+
}
1397+
}
1398+
}
1399+
13851400
OpenedExistentialAdjustments adjustments;
13861401

13871402
// If the argument is inout, strip it off and we can add it back.
@@ -1670,10 +1685,10 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
16701685
auto argTy = argument.getOldType();
16711686

16721687
bool matchingAutoClosureResult = param.isAutoClosure();
1688+
auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx);
16731689
if (param.isAutoClosure() && !isSynthesizedArgument(argument)) {
16741690
auto &ctx = cs.getASTContext();
16751691
auto *fnType = paramTy->castTo<FunctionType>();
1676-
auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx);
16771692

16781693
// If this is a call to a function with a closure argument and the
16791694
// parameter is an autoclosure, let's just increment the score here
@@ -1715,7 +1730,7 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
17151730
// If the argument is an existential type and the parameter is generic,
17161731
// consider opening the existential type.
17171732
if (auto existentialArg = shouldOpenExistentialCallArgument(
1718-
callee, paramIdx, paramTy, argTy)) {
1733+
callee, paramIdx, paramTy, argTy, argExpr, cs)) {
17191734
// My kingdom for a decent "if let" in C++.
17201735
TypeVariableType *openedTypeVar;
17211736
Type existentialType;
@@ -10113,18 +10128,8 @@ ConstraintSystem::simplifyOpenedExistentialOfConstraint(
1011310128
if (type2->isAnyExistentialType()) {
1011410129
// We have the existential side. Produce an opened archetype and bind
1011510130
// type1 to it.
10116-
bool isMetatype = false;
10117-
auto instanceTy = type2;
10118-
if (auto metaTy = type2->getAs<ExistentialMetatypeType>()) {
10119-
isMetatype = true;
10120-
instanceTy = metaTy->getExistentialInstanceType();
10121-
}
10122-
assert(instanceTy->isExistentialType());
10123-
Type openedTy =
10124-
OpenedArchetypeType::get(instanceTy->getCanonicalType(),
10125-
DC->getGenericSignatureOfContext());
10126-
if (isMetatype)
10127-
openedTy = MetatypeType::get(openedTy, getASTContext());
10131+
Type openedTy = openExistentialType(type2, getConstraintLocator(locator))
10132+
.first;
1012810133
return matchTypes(type1, openedTy, ConstraintKind::Bind, subflags, locator);
1012910134
}
1013010135
if (!type2->isTypeVariableOrMember())
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-frontend -enable-experimental-opened-existential-types -typecheck -dump-ast -parse-as-library %s | %FileCheck %s
2+
3+
protocol P { }
4+
5+
func acceptsBox<T>(_ value: T) { }
6+
7+
// CHECK: passBox
8+
// CHECK-NOT: open_existential_expr
9+
func passBox(p: P) {
10+
acceptsBox(p as P)
11+
}

0 commit comments

Comments
 (0)