Skip to content

Commit 1fbf5f1

Browse files
committed
Add AllowCompatibleOpaqueTypeArchetypes as a Type.match flag
1 parent 6184bb6 commit 1fbf5f1

File tree

3 files changed

+17
-95
lines changed

3 files changed

+17
-95
lines changed

include/swift/AST/Types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ enum class TypeMatchFlags {
257257
///
258258
/// This is necessary because Objective-C allows optional function paramaters
259259
/// to be non-escaping, but Swift currently does not.
260-
IgnoreNonEscapingForOptionalFunctionParam = 1 << 4
260+
IgnoreNonEscapingForOptionalFunctionParam = 1 << 4,
261+
/// Allow compatible opaque archetypes.
262+
AllowCompatibleOpaqueTypeArchetypes = 1 << 5
261263
};
262264
using TypeMatchOptions = OptionSet<TypeMatchFlags>;
263265

lib/AST/Type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,13 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
22932293
if (isABICompatibleEvenAddingOptional(t1, t2))
22942294
return true;
22952295

2296+
if (matchMode.contains(TypeMatchFlags::AllowCompatibleOpaqueTypeArchetypes))
2297+
if (auto opaque1 = t1->getAs<OpaqueTypeArchetypeType>())
2298+
if (auto opaque2 = t2->getAs<OpaqueTypeArchetypeType>())
2299+
return opaque1->getBoundSignature() == opaque2->getBoundSignature() &&
2300+
opaque1->getInterfaceType()->getCanonicalType()->matches(
2301+
opaque2->getInterfaceType()->getCanonicalType(), matchMode);
2302+
22962303
return false;
22972304
}
22982305

lib/Sema/TypeCheckAttr.cpp

Lines changed: 7 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,94 +2093,6 @@ static Type getDynamicComparisonType(ValueDecl *value) {
20932093
return interfaceType->removeArgumentLabels(numArgumentLabels);
20942094
}
20952095

2096-
static OpaqueTypeArchetypeType *getOpaqueResulType(const AbstractFunctionDecl *func) {
2097-
auto funTy =
2098-
(func->getDeclContext()->isTypeContext() ? func->getMethodInterfaceType()
2099-
: func->getInterfaceType())
2100-
->getCanonicalType()
2101-
->getAs<AnyFunctionType>();
2102-
auto resultTy = funTy->getResult()->getCanonicalType()->getAs<OpaqueTypeArchetypeType>();
2103-
return resultTy;
2104-
}
2105-
2106-
static AnyFunctionType::CanParamArrayRef getParameters(const AbstractFunctionDecl *func) {
2107-
auto funTy =
2108-
(func->getDeclContext()->isTypeContext() ? func->getMethodInterfaceType()
2109-
: func->getInterfaceType())
2110-
->getCanonicalType()
2111-
->getAs<AnyFunctionType>();
2112-
assert(funTy);
2113-
return funTy->getParams();
2114-
}
2115-
2116-
static bool
2117-
matchFunctionWithOpaqueResultType(const AbstractFunctionDecl *replacement,
2118-
AbstractFunctionDecl *replaced) {
2119-
if (!replaced)
2120-
return false;
2121-
2122-
auto resultTy = getOpaqueResulType(replacement);
2123-
if (!resultTy)
2124-
return false;
2125-
auto replacedResultTy = getOpaqueResulType(replaced);
2126-
if (!replacedResultTy)
2127-
return false;
2128-
2129-
if (resultTy->getBoundSignature() != replacedResultTy->getBoundSignature() ||
2130-
!resultTy->getInterfaceType()->getCanonicalType()->matches(
2131-
replacedResultTy->getInterfaceType()->getCanonicalType(),
2132-
TypeMatchFlags::AllowABICompatible))
2133-
return false;
2134-
2135-
auto params = getParameters(replacement);
2136-
auto replacedParams = getParameters(replaced);
2137-
if (params.size() != replacedParams.size())
2138-
return false;
2139-
for (auto i : indices(params)) {
2140-
if (!params[i].getOldType()->matchesParameter(
2141-
replacedParams[i].getOldType(), TypeMatchFlags::AllowABICompatible))
2142-
return false;
2143-
}
2144-
2145-
return true;
2146-
}
2147-
2148-
static bool matchOpaqueResultType(Type replacement, Type replaced) {
2149-
if (replacement->isEqual(replaced))
2150-
return true;
2151-
2152-
if (auto fn1 = dyn_cast<AnyFunctionType>(replacement->getCanonicalType())) {
2153-
auto fn2 = dyn_cast<AnyFunctionType>(replaced->getCanonicalType());
2154-
if (!fn2)
2155-
return false;
2156-
auto fn2Params = fn2.getParams();
2157-
auto fn1Params = fn1.getParams();
2158-
if (fn2Params.size() != fn1Params.size()) {
2159-
return false;
2160-
}
2161-
for (auto i : indices(fn2Params)) {
2162-
if (!matchOpaqueResultType(fn2Params[i].getOldType(),
2163-
fn1Params[i].getOldType()))
2164-
return false;
2165-
}
2166-
return matchOpaqueResultType(fn1.getResult(), fn2.getResult());
2167-
}
2168-
2169-
auto resultTy = replacement->getAs<OpaqueTypeArchetypeType>();
2170-
if (!resultTy)
2171-
return false;
2172-
auto replacedResultTy = replaced->getAs<OpaqueTypeArchetypeType>();
2173-
if (!replacedResultTy)
2174-
return false;
2175-
2176-
if (resultTy->getBoundSignature() != replacedResultTy->getBoundSignature() ||
2177-
!resultTy->getInterfaceType()->getCanonicalType()->matches(
2178-
replacedResultTy->getInterfaceType()->getCanonicalType(),
2179-
TypeMatchFlags::AllowABICompatible))
2180-
return false;
2181-
return true;
2182-
}
2183-
21842096
static FuncDecl *findReplacedAccessor(DeclName replacedVarName,
21852097
AccessorDecl *replacement,
21862098
DynamicReplacementAttr *attr,
@@ -2205,7 +2117,9 @@ static FuncDecl *findReplacedAccessor(DeclName replacedVarName,
22052117
TC.validateDecl(result);
22062118
auto resultType = getDynamicComparisonType(result);
22072119
if (!resultType->isEqual(replacementStorageType) &&
2208-
!matchOpaqueResultType(resultType, replacementStorageType)) {
2120+
!resultType->matches(
2121+
replacementStorageType,
2122+
TypeMatchFlags::AllowCompatibleOpaqueTypeArchetypes)) {
22092123
return true;
22102124
}
22112125

@@ -2281,11 +2195,10 @@ findReplacedFunction(DeclName replacedFunctionName,
22812195
continue;
22822196
if (TC)
22832197
TC->validateDecl(result);
2284-
if (matchFunctionWithOpaqueResultType(
2285-
replacement, dyn_cast<AbstractFunctionDecl>(result)) ||
2286-
result->getInterfaceType()->getCanonicalType()->matches(
2287-
replacement->getInterfaceType()->getCanonicalType(),
2288-
TypeMatchFlags::AllowABICompatible)) {
2198+
TypeMatchOptions matchMode = TypeMatchFlags::AllowABICompatible;
2199+
matchMode |= TypeMatchFlags::AllowCompatibleOpaqueTypeArchetypes;
2200+
if (result->getInterfaceType()->getCanonicalType()->matches(
2201+
replacement->getInterfaceType()->getCanonicalType(), matchMode)) {
22892202
if (!result->isDynamic()) {
22902203
if (TC) {
22912204
TC->diagnose(attr->getLocation(),

0 commit comments

Comments
 (0)