Skip to content

Commit d2cb83b

Browse files
committed
[Constraint solver] Make checked cast constraint generation lazy.
Fixes rdar://problem/27148148.
1 parent af4d44e commit d2cb83b

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,8 +2144,7 @@ ConstraintSystem::simplifyConstructionConstraint(
21442144
Type valueType, FunctionType *fnType, TypeMatchOptions flags,
21452145
FunctionRefKind functionRefKind, ConstraintLocator *locator) {
21462146
// Desugar the value type.
2147-
auto desugarValueType = getFixedTypeRecursive(valueType, true)
2148-
->getDesugaredType();
2147+
auto desugarValueType = valueType->getDesugaredType();
21492148

21502149
Type argType = fnType->getInput();
21512150
Type resultType = fnType->getResult();
@@ -2370,23 +2369,39 @@ static CheckedCastKind getCheckedCastKind(ConstraintSystem *cs,
23702369
ConstraintSystem::SolutionKind
23712370
ConstraintSystem::simplifyCheckedCastConstraint(
23722371
Type fromType, Type toType,
2372+
TypeMatchOptions flags,
23732373
ConstraintLocatorBuilder locator) {
2374+
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
2375+
2376+
/// Form an unresolved result.
2377+
auto formUnsolved = [&] {
2378+
if (flags.contains(TMF_GenerateConstraints)) {
2379+
addUnsolvedConstraint(
2380+
Constraint::create(*this, ConstraintKind::CheckedCast, fromType,
2381+
toType, DeclName(), FunctionRefKind::Compound,
2382+
getConstraintLocator(locator)));
2383+
return SolutionKind::Solved;
2384+
}
2385+
2386+
return SolutionKind::Unsolved;
2387+
};
2388+
23742389
do {
23752390
// Dig out the fixed type to which this type refers.
23762391
fromType = getFixedTypeRecursive(fromType, /*wantRValue=*/true);
23772392

23782393
// If we hit a type variable without a fixed type, we can't
23792394
// solve this yet.
23802395
if (fromType->isTypeVariableOrMember())
2381-
return SolutionKind::Unsolved;
2396+
return formUnsolved();
23822397

23832398
// Dig out the fixed type to which this type refers.
23842399
toType = getFixedTypeRecursive(toType, /*wantRValue=*/true);
23852400

23862401
// If we hit a type variable without a fixed type, we can't
23872402
// solve this yet.
23882403
if (toType->isTypeVariableOrMember())
2389-
return SolutionKind::Unsolved;
2404+
return formUnsolved();
23902405

23912406
Type origFromType = fromType;
23922407
Type origToType = toType;
@@ -2414,6 +2429,9 @@ ConstraintSystem::simplifyCheckedCastConstraint(
24142429
}
24152430
}
24162431

2432+
// We've decomposed the types further, so adopt the subflags.
2433+
flags = subflags;
2434+
24172435
// If nothing changed, we're done.
24182436
if (fromType.getPointer() == origFromType.getPointer() &&
24192437
toType.getPointer() == origToType.getPointer())
@@ -2435,14 +2453,12 @@ ConstraintSystem::simplifyCheckedCastConstraint(
24352453
toBaseType)) {
24362454
// The class we're bridging through must be a subtype of the type we're
24372455
// coming from.
2438-
addConstraint(ConstraintKind::Subtype, classType, fromBaseType,
2439-
getConstraintLocator(locator));
2440-
return SolutionKind::Solved;
2456+
return matchTypes(classType, fromBaseType, TypeMatchKind::Subtype,
2457+
subflags, locator);
24412458
}
24422459

2443-
addConstraint(ConstraintKind::Subtype, toBaseType, fromBaseType,
2444-
getConstraintLocator(locator));
2445-
return SolutionKind::Solved;
2460+
return matchTypes(toBaseType, fromBaseType, TypeMatchKind::Subtype,
2461+
subflags, locator);
24462462
}
24472463
case CheckedCastKind::DictionaryDowncast: {
24482464
Type fromKeyType, fromValueType;
@@ -2462,8 +2478,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
24622478
}
24632479

24642480
// Perform subtype check on the possibly-bridged-through key type.
2465-
TypeMatchOptions subflags = TMF_GenerateConstraints;
2466-
auto result = matchTypes(toKeyType, fromKeyType, TypeMatchKind::Subtype,
2481+
auto result = matchTypes(toKeyType, fromKeyType, TypeMatchKind::Subtype,
24672482
subflags, locator);
24682483
if (result == SolutionKind::Error)
24692484
return result;
@@ -2482,7 +2497,7 @@ ConstraintSystem::simplifyCheckedCastConstraint(
24822497
return result;
24832498

24842499
case SolutionKind::Unsolved:
2485-
return SolutionKind::Unsolved;
2500+
return SolutionKind::Solved;
24862501

24872502
case SolutionKind::Error:
24882503
return SolutionKind::Error;
@@ -2501,13 +2516,13 @@ ConstraintSystem::simplifyCheckedCastConstraint(
25012516
toBaseType)) {
25022517
// The class we're bridging through must be a subtype of the type we're
25032518
// coming from.
2504-
addConstraint(ConstraintKind::Subtype, classType, fromBaseType,
2505-
getConstraintLocator(locator));
2519+
addConstraint(ConstraintKind::Subtype, classType,
2520+
fromBaseType, locator);
25062521
return SolutionKind::Solved;
25072522
}
25082523

2509-
addConstraint(ConstraintKind::Subtype, toBaseType, fromBaseType,
2510-
getConstraintLocator(locator));
2524+
addConstraint(ConstraintKind::Subtype, toBaseType,
2525+
fromBaseType, locator);
25112526
return SolutionKind::Solved;
25122527
}
25132528

@@ -4144,6 +4159,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
41444159
return simplifyConformsToConstraint(first, second, kind, locator,
41454160
subflags);
41464161

4162+
case ConstraintKind::CheckedCast:
4163+
return simplifyCheckedCastConstraint(first, second, subflags, locator);
4164+
41474165
case ConstraintKind::Bind: // FIXME: This should go through matchTypes() above
41484166

41494167
default: {
@@ -4254,6 +4272,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
42544272
case ConstraintKind::CheckedCast: {
42554273
auto result = simplifyCheckedCastConstraint(constraint.getFirstType(),
42564274
constraint.getSecondType(),
4275+
None,
42574276
constraint.getLocator());
42584277
// NOTE: simplifyCheckedCastConstraint() may return Unsolved, e.g. if the
42594278
// subexpression's type is unresolved. Don't record the fix until we

lib/Sema/ConstraintSystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,7 @@ class ConstraintSystem {
20242024

20252025
/// Attempt to simplify a checked-cast constraint.
20262026
SolutionKind simplifyCheckedCastConstraint(Type fromType, Type toType,
2027+
TypeMatchOptions flags,
20272028
ConstraintLocatorBuilder locator);
20282029

20292030
/// \brief Attempt to simplify the given member constraint.

validation-test/Sema/type_checker_crashers/rdar27148148.swift renamed to validation-test/Sema/type_checker_crashers_fixed/rdar27148148.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: not --crash %target-swift-frontend %s -parse
1+
// RUN: not %target-swift-frontend %s -parse
22
// REQUIRES: asserts
33

44
public protocol I {

0 commit comments

Comments
 (0)