Skip to content

Commit bd5f05c

Browse files
authored
Merge pull request #6629 from rudkx/fix-iuo-collections
Fix one source of exponential behavior in the type checker.
2 parents fa01895 + 1efafbc commit bd5f05c

File tree

1 file changed

+50
-50
lines changed

1 file changed

+50
-50
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,48 @@ static bool isStringCompatiblePointerBaseType(TypeChecker &TC,
11891189
return false;
11901190
}
11911191

1192+
static Optional<ConversionRestrictionKind>
1193+
selectOptionalConversionRestriction(Type type1, Type type2,
1194+
ConstraintKind kind) {
1195+
OptionalTypeKind optionalKind1 = OTK_None;
1196+
if (auto boundGeneric1 = type1->getAs<BoundGenericType>())
1197+
optionalKind1 = boundGeneric1->getDecl()->classifyAsOptionalType();
1198+
1199+
OptionalTypeKind optionalKind2 = OTK_None;
1200+
if (auto boundGeneric2 = type2->getAs<BoundGenericType>())
1201+
optionalKind2 = boundGeneric2->getDecl()->classifyAsOptionalType();
1202+
1203+
if (optionalKind2 == OTK_None) {
1204+
if (optionalKind1 == OTK_ImplicitlyUnwrappedOptional &&
1205+
kind >= ConstraintKind::Conversion)
1206+
return ConversionRestrictionKind::ForceUnchecked;
1207+
1208+
return llvm::None;
1209+
}
1210+
1211+
if (optionalKind1 == optionalKind2)
1212+
return ConversionRestrictionKind::OptionalToOptional;
1213+
1214+
if (optionalKind1 == OTK_None)
1215+
return ConversionRestrictionKind::ValueToOptional;
1216+
1217+
if (optionalKind1 == OTK_Optional) {
1218+
if (kind >= ConstraintKind::Conversion)
1219+
return ConversionRestrictionKind::OptionalToImplicitlyUnwrappedOptional;
1220+
1221+
assert(optionalKind2 == OTK_ImplicitlyUnwrappedOptional &&
1222+
"Result has unexpected optional kind!");
1223+
1224+
return llvm::None;
1225+
}
1226+
1227+
assert(optionalKind1 == OTK_ImplicitlyUnwrappedOptional &&
1228+
"Source has unexpected optional kind!");
1229+
1230+
return ConversionRestrictionKind::ImplicitlyUnwrappedOptionalToOptional;
1231+
}
1232+
1233+
11921234
ConstraintSystem::SolutionKind
11931235
ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
11941236
TypeMatchOptions flags,
@@ -1933,57 +1975,15 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
19331975
conversionsOrFixes.push_back(ConversionRestrictionKind::Existential);
19341976
}
19351977

1936-
// A value of type T can be converted to type U? if T is convertible to U.
1937-
// A value of type T? can be converted to type U? if T is convertible to U.
1938-
// The above conversions also apply to implicitly unwrapped optional types,
1939-
// except that there is no implicit conversion from T? to T!.
1940-
{
1941-
BoundGenericType *boundGenericType2;
1942-
1943-
if (concrete && kind >= ConstraintKind::Subtype &&
1944-
(boundGenericType2 = type2->getAs<BoundGenericType>())) {
1945-
auto decl2 = boundGenericType2->getDecl();
1946-
if (auto optionalKind2 = decl2->classifyAsOptionalType()) {
1947-
assert(boundGenericType2->getGenericArgs().size() == 1);
1948-
1949-
BoundGenericType *boundGenericType1 = type1->getAs<BoundGenericType>();
1950-
if (boundGenericType1) {
1951-
auto decl1 = boundGenericType1->getDecl();
1952-
if (decl1 == decl2) {
1953-
assert(boundGenericType1->getGenericArgs().size() == 1);
1954-
conversionsOrFixes.push_back(
1955-
ConversionRestrictionKind::OptionalToOptional);
1956-
} else if (optionalKind2 == OTK_Optional &&
1957-
decl1 == TC.Context.getImplicitlyUnwrappedOptionalDecl()) {
1958-
assert(boundGenericType1->getGenericArgs().size() == 1);
1959-
conversionsOrFixes.push_back(
1960-
ConversionRestrictionKind::ImplicitlyUnwrappedOptionalToOptional);
1961-
} else if (optionalKind2 == OTK_ImplicitlyUnwrappedOptional &&
1962-
kind >= ConstraintKind::Conversion &&
1963-
decl1 == TC.Context.getOptionalDecl()) {
1964-
assert(boundGenericType1->getGenericArgs().size() == 1);
1965-
conversionsOrFixes.push_back(
1966-
ConversionRestrictionKind::OptionalToImplicitlyUnwrappedOptional);
1967-
}
1968-
}
1969-
1970-
conversionsOrFixes.push_back(
1971-
ConversionRestrictionKind::ValueToOptional);
1972-
}
1973-
}
1974-
}
1978+
// A value of type T! can be converted to type U if T is convertible
1979+
// to U by force-unwrapping the source value.
1980+
// A value of type T, T?, or T! can be converted to type U? or U! if
1981+
// T is convertible to U.
1982+
if (concrete && kind >= ConstraintKind::Subtype)
1983+
if (auto restriction =
1984+
selectOptionalConversionRestriction(type1, type2, kind))
1985+
conversionsOrFixes.push_back(restriction.getValue());
19751986

1976-
// A value of type T! can be (unsafely) forced to U if T
1977-
// is convertible to U.
1978-
{
1979-
Type objectType1;
1980-
if (concrete && kind >= ConstraintKind::Conversion &&
1981-
(objectType1 = lookThroughImplicitlyUnwrappedOptionalType(type1))) {
1982-
conversionsOrFixes.push_back(
1983-
ConversionRestrictionKind::ForceUnchecked);
1984-
}
1985-
}
1986-
19871987
// Allow '() -> T' to '() -> ()' and '() -> Never' to '() -> T' for closure
19881988
// literals.
19891989
if (auto elt = locator.last()) {

0 commit comments

Comments
 (0)