Skip to content

Commit c7e1c5e

Browse files
authored
Merge pull request #14055 from rudkx/refactor-type-match
Refactor type matching to split function type matching out.
2 parents d471f2a + 36a49a6 commit c7e1c5e

File tree

1 file changed

+45
-32
lines changed

1 file changed

+45
-32
lines changed

lib/AST/Type.cpp

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,6 +2178,41 @@ namespace {
21782178
};
21792179
} // end anonymous namespace
21802180

2181+
static bool matchFunctionTypes(CanAnyFunctionType fn1, CanAnyFunctionType fn2,
2182+
TypeMatchOptions matchMode,
2183+
OptionalUnwrapping insideOptional,
2184+
std::function<bool()> paramsAndResultMatch) {
2185+
// FIXME: Handle generic functions in non-ABI matches.
2186+
if (!matchMode.contains(TypeMatchFlags::AllowABICompatible)) {
2187+
if (!isa<FunctionType>(fn1) || !isa<FunctionType>(fn2))
2188+
return false;
2189+
}
2190+
2191+
// When checking overrides, allow the base type to be throwing even if the
2192+
// overriding type isn't.
2193+
auto ext1 = fn1->getExtInfo();
2194+
auto ext2 = fn2->getExtInfo();
2195+
if (matchMode.contains(TypeMatchFlags::AllowOverride)) {
2196+
if (ext2.throws()) {
2197+
ext1 = ext1.withThrows(true);
2198+
}
2199+
}
2200+
// If specified, allow an escaping function parameter to override a
2201+
// non-escaping function parameter when the parameter is optional.
2202+
// Note that this is checking 'ext2' rather than 'ext1' because parameters
2203+
// must be contravariant for the containing function to be covariant.
2204+
if (matchMode.contains(
2205+
TypeMatchFlags::IgnoreNonEscapingForOptionalFunctionParam) &&
2206+
insideOptional == OptionalUnwrapping::OptionalToOptional) {
2207+
if (!ext2.isNoEscape())
2208+
ext1 = ext1.withNoEscape(false);
2209+
}
2210+
if (ext1 != ext2)
2211+
return false;
2212+
2213+
return paramsAndResultMatch();
2214+
}
2215+
21812216
static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
21822217
ParameterPosition paramPosition,
21832218
OptionalUnwrapping insideOptional) {
@@ -2255,39 +2290,17 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
22552290
if (!fn1)
22562291
return false;
22572292

2258-
// FIXME: Handle generic functions in non-ABI matches.
2259-
if (!matchMode.contains(TypeMatchFlags::AllowABICompatible)) {
2260-
if (!isa<FunctionType>(t1) || !isa<FunctionType>(t2))
2261-
return false;
2262-
}
2263-
2264-
// When checking overrides, allow the base type to be throwing even if the
2265-
// overriding type isn't.
2266-
auto ext1 = fn1->getExtInfo();
2267-
auto ext2 = fn2->getExtInfo();
2268-
if (matchMode.contains(TypeMatchFlags::AllowOverride)) {
2269-
if (ext2.throws()) {
2270-
ext1 = ext1.withThrows(true);
2271-
}
2272-
}
2273-
// If specified, allow an escaping function parameter to override a
2274-
// non-escaping function parameter when the parameter is optional.
2275-
// Note that this is checking 'ext2' rather than 'ext1' because parameters
2276-
// must be contravariant for the containing function to be covariant.
2277-
if (matchMode.contains(
2278-
TypeMatchFlags::IgnoreNonEscapingForOptionalFunctionParam) &&
2279-
insideOptional == OptionalUnwrapping::OptionalToOptional) {
2280-
if (!ext2.isNoEscape())
2281-
ext1 = ext1.withNoEscape(false);
2282-
}
2283-
if (ext1 != ext2)
2284-
return false;
2293+
std::function<bool()> paramsAndResultMatch = [=]() {
2294+
// Inputs are contravariant, results are covariant.
2295+
return (matches(fn2.getInput(), fn1.getInput(), matchMode,
2296+
ParameterPosition::Parameter, OptionalUnwrapping::None) &&
2297+
matches(fn1.getResult(), fn2.getResult(), matchMode,
2298+
ParameterPosition::NotParameter,
2299+
OptionalUnwrapping::None));
2300+
};
22852301

2286-
// Inputs are contravariant, results are covariant.
2287-
return (matches(fn2.getInput(), fn1.getInput(), matchMode,
2288-
ParameterPosition::Parameter, OptionalUnwrapping::None) &&
2289-
matches(fn1.getResult(), fn2.getResult(), matchMode,
2290-
ParameterPosition::NotParameter, OptionalUnwrapping::None));
2302+
return matchFunctionTypes(fn1, fn2, matchMode, insideOptional,
2303+
paramsAndResultMatch);
22912304
}
22922305

22932306
if (matchMode.contains(TypeMatchFlags::AllowNonOptionalForIUOParam) &&

0 commit comments

Comments
 (0)