Skip to content

Commit 29188e3

Browse files
[AST] Update equality for ExtInfo to take Clang types into account.
In the future, we will remove the UseClangFunctionTypes language option, but we temporarily need the scaffolding for equality checks to be consistent in all places.
1 parent f219e58 commit 29188e3

File tree

10 files changed

+72
-35
lines changed

10 files changed

+72
-35
lines changed

include/swift/AST/ExtInfo.h

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ClangTypeInfo {
6666
constexpr ClangTypeInfo() : type(nullptr) {}
6767
constexpr ClangTypeInfo(const clang::Type *type) : type(type) {}
6868

69+
friend bool operator==(ClangTypeInfo lhs, ClangTypeInfo rhs);
6970
ClangTypeInfo getCanonical() const;
7071

7172
public:
@@ -345,7 +346,12 @@ class ASTExtInfoBuilder {
345346
clangTypeInfo);
346347
}
347348

348-
std::pair<unsigned, const void *> getFuncAttrKey() const {
349+
bool isEqualTo(ASTExtInfoBuilder other, bool useClangTypes) const {
350+
return bits == other.bits &&
351+
(useClangTypes ? (clangTypeInfo == other.clangTypeInfo) : true);
352+
}
353+
354+
constexpr std::pair<unsigned, const void *> getFuncAttrKey() const {
349355
return std::make_pair(bits, clangTypeInfo.getType());
350356
}
351357
}; // end ASTExtInfoBuilder
@@ -430,11 +436,8 @@ class ASTExtInfo {
430436
return builder.withThrows(throws).build();
431437
}
432438

433-
bool operator==(ASTExtInfo other) const {
434-
return builder.bits == other.builder.bits;
435-
}
436-
bool operator!=(ASTExtInfo other) const {
437-
return builder.bits != other.builder.bits;
439+
bool isEqualTo(ASTExtInfo other, bool useClangTypes) const {
440+
return builder.isEqualTo(other.builder, useClangTypes);
438441
}
439442

440443
constexpr std::pair<unsigned, const void *> getFuncAttrKey() const {
@@ -613,7 +616,12 @@ class SILExtInfoBuilder {
613616
clangTypeInfo);
614617
}
615618

616-
std::pair<unsigned, const void *> getFuncAttrKey() const {
619+
bool isEqualTo(SILExtInfoBuilder other, bool useClangTypes) const {
620+
return bits == other.bits &&
621+
(useClangTypes ? (clangTypeInfo == other.clangTypeInfo) : true);
622+
}
623+
624+
constexpr std::pair<unsigned, const void *> getFuncAttrKey() const {
617625
return std::make_pair(bits, clangTypeInfo.getType());
618626
}
619627
}; // end SILExtInfoBuilder
@@ -693,19 +701,24 @@ class SILExtInfo {
693701
return builder.withNoEscape(noEscape).build();
694702
}
695703

696-
bool operator==(SILExtInfo other) const {
697-
return builder.bits == other.builder.bits;
698-
}
699-
bool operator!=(SILExtInfo other) const {
700-
return builder.bits != other.builder.bits;
704+
bool isEqualTo(SILExtInfo other, bool useClangTypes) const {
705+
return builder.isEqualTo(other.builder, useClangTypes);
701706
}
702707

703-
704708
constexpr std::pair<unsigned, const void *> getFuncAttrKey() const {
705709
return builder.getFuncAttrKey();
706710
}
707711
};
708712

713+
/// Helper function to obtain the useClangTypes parameter for checking equality
714+
/// of ExtInfos.
715+
///
716+
/// Typically, the argument will be a function type which was used to obtain one
717+
/// of the ExtInfos.
718+
template <typename HasContext> bool useClangTypes(HasContext hasContext) {
719+
return hasContext->getASTContext().LangOpts.UseClangFunctionTypes;
720+
}
721+
709722
} // end namespace swift
710723

711724
#endif // SWIFT_EXTINFO_H

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
214214

215215
bool visitAnyFunctionType(CanAnyFunctionType type1,
216216
CanAnyFunctionType type2) {
217-
if (type1->getExtInfo() != type2->getExtInfo())
217+
if (!type1->hasSameExtInfoAs(type2))
218218
return asImpl().visitDifferentTypeStructure(type1, type2);
219219

220220
if (asImpl().visit(type1.getResult(), type2.getResult()))
@@ -242,10 +242,10 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
242242

243243
bool visitSILFunctionTypeStructure(CanSILFunctionType type1,
244244
CanSILFunctionType type2) {
245-
if (type1->getExtInfo() != type2->getExtInfo() ||
245+
if (!type1->hasSameExtInfoAs(type2) ||
246246
type1->getCoroutineKind() != type2->getCoroutineKind() ||
247-
type1->getInvocationGenericSignature()
248-
!= type2->getInvocationGenericSignature())
247+
type1->getInvocationGenericSignature() !=
248+
type2->getInvocationGenericSignature())
249249
return asImpl().visitDifferentTypeStructure(type1, type2);
250250
return false;
251251
}

include/swift/AST/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,6 +2932,8 @@ class AnyFunctionType : public TypeBase {
29322932
: ClangTypeInfo());
29332933
}
29342934

2935+
bool hasSameExtInfoAs(const AnyFunctionType *otherFn);
2936+
29352937
/// Get the representation of the function type.
29362938
Representation getRepresentation() const {
29372939
return getExtInfo().getRepresentation();
@@ -4295,6 +4297,8 @@ class SILFunctionType final
42954297

42964298
ClangTypeInfo getClangTypeInfo() const;
42974299

4300+
bool hasSameExtInfoAs(const SILFunctionType *otherFn);
4301+
42984302
/// Given that `this` is a `@differentiable` or `@differentiable(linear)`
42994303
/// function type, returns an `IndexSubset` corresponding to the
43004304
/// differentiability/linearity parameters (e.g. all parameters except the

lib/AST/ExtInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ namespace swift {
2323

2424
// MARK: - ClangTypeInfo
2525

26+
bool operator==(ClangTypeInfo lhs, ClangTypeInfo rhs) {
27+
if (lhs.type == rhs.type)
28+
return true;
29+
if (lhs.type && rhs.type)
30+
return lhs.type->getCanonicalTypeInternal() ==
31+
rhs.type->getCanonicalTypeInternal();
32+
return false;
33+
}
34+
2635
ClangTypeInfo ClangTypeInfo::getCanonical() const {
2736
if (!type)
2837
return ClangTypeInfo();

lib/AST/Type.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,9 +1243,7 @@ CanType TypeBase::computeCanonicalType() {
12431243
getCanonicalParams(funcTy, genericSig, canParams);
12441244
auto resultTy = funcTy->getResult()->getCanonicalType(genericSig);
12451245

1246-
bool useClangFunctionType =
1247-
resultTy->getASTContext().LangOpts.UseClangFunctionTypes;
1248-
auto extInfo = funcTy->getCanonicalExtInfo(useClangFunctionType);
1246+
auto extInfo = funcTy->getCanonicalExtInfo(useClangTypes(resultTy));
12491247
if (genericSig) {
12501248
Result = GenericFunctionType::get(genericSig, canParams, resultTy,
12511249
extInfo);
@@ -1783,7 +1781,7 @@ class IsBindableVisitor
17831781
CanType visitFunctionType(FunctionType *func, CanType subst,
17841782
ArchetypeType*, ArrayRef<ProtocolConformanceRef>) {
17851783
if (auto substFunc = dyn_cast<FunctionType>(subst)) {
1786-
if (func->getExtInfo() != substFunc->getExtInfo())
1784+
if (!func->hasSameExtInfoAs(substFunc))
17871785
return CanType();
17881786

17891787
if (func->getParams().size() != substFunc->getParams().size())
@@ -1822,7 +1820,7 @@ class IsBindableVisitor
18221820
CanType visitSILFunctionType(SILFunctionType *func, CanType subst,
18231821
ArchetypeType*, ArrayRef<ProtocolConformanceRef>) {
18241822
if (auto substFunc = dyn_cast<SILFunctionType>(subst)) {
1825-
if (func->getExtInfo() != substFunc->getExtInfo())
1823+
if (!func->hasSameExtInfoAs(substFunc))
18261824
return CanType();
18271825

18281826
if (func->getInvocationGenericSignature()
@@ -2618,7 +2616,7 @@ static bool matchesFunctionType(CanAnyFunctionType fn1, CanAnyFunctionType fn2,
26182616
if (!ext2.isNoEscape())
26192617
ext1 = ext1.withNoEscape(false);
26202618
}
2621-
if (ext1 != ext2)
2619+
if (!ext1.isEqualTo(ext2, useClangTypes(fn1)))
26222620
return false;
26232621

26242622
return paramsAndResultMatch();
@@ -3427,11 +3425,19 @@ ClangTypeInfo AnyFunctionType::getCanonicalClangTypeInfo() const {
34273425
return getClangTypeInfo().getCanonical();
34283426
}
34293427

3428+
bool AnyFunctionType::hasSameExtInfoAs(const AnyFunctionType *otherFn) {
3429+
return getExtInfo().isEqualTo(otherFn->getExtInfo(), useClangTypes(this));
3430+
}
3431+
34303432
// [TODO: Store-SIL-Clang-type]
34313433
ClangTypeInfo SILFunctionType::getClangTypeInfo() const {
34323434
return ClangTypeInfo();
34333435
}
34343436

3437+
bool SILFunctionType::hasSameExtInfoAs(const SILFunctionType *otherFn) {
3438+
return getExtInfo().isEqualTo(otherFn->getExtInfo(), useClangTypes(this));
3439+
}
3440+
34353441
FunctionType *
34363442
GenericFunctionType::substGenericArgs(SubstitutionMap subs) {
34373443
return substGenericArgs(

lib/AST/TypeJoinMeet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ CanType TypeJoin::visitFunctionType(CanType second) {
314314
auto secondExtInfo = secondFnTy->getExtInfo();
315315

316316
// FIXME: Properly handle these attributes.
317-
if (firstExtInfo != secondExtInfo)
317+
if (!firstExtInfo.isEqualTo(secondExtInfo, useClangTypes(First)))
318318
return Unimplemented;
319319

320320
if (!AnyFunctionType::equalParams(firstFnTy->getParams(),

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ static CanType getKnownType(Optional<CanType> &cacheSlot, ASTContext &C,
932932
CanAnyFunctionType
933933
Lowering::adjustFunctionType(CanAnyFunctionType t,
934934
AnyFunctionType::ExtInfo extInfo) {
935-
if (t->getExtInfo() == extInfo)
935+
if (t->getExtInfo().isEqualTo(extInfo, useClangTypes(t)))
936936
return t;
937937
return CanAnyFunctionType(t->withExtInfo(extInfo));
938938
}
@@ -943,7 +943,8 @@ Lowering::adjustFunctionType(CanSILFunctionType type,
943943
SILFunctionType::ExtInfo extInfo,
944944
ParameterConvention callee,
945945
ProtocolConformanceRef witnessMethodConformance) {
946-
if (type->getExtInfo() == extInfo && type->getCalleeConvention() == callee &&
946+
if (type->getExtInfo().isEqualTo(extInfo, useClangTypes(type)) &&
947+
type->getCalleeConvention() == callee &&
947948
type->getWitnessMethodConformanceOrInvalid() == witnessMethodConformance)
948949
return type;
949950

@@ -965,7 +966,7 @@ SILFunctionType::getWithRepresentation(Representation repr) {
965966

966967
CanSILFunctionType SILFunctionType::getWithExtInfo(ExtInfo newExt) {
967968
auto oldExt = getExtInfo();
968-
if (newExt == oldExt)
969+
if (newExt.isEqualTo(oldExt, useClangTypes(this)))
969970
return CanSILFunctionType(this);
970971

971972
auto calleeConvention =
@@ -3968,7 +3969,7 @@ TypeConverter::getBridgedFunctionType(AbstractionPattern pattern,
39683969
case SILFunctionTypeRepresentation::Closure:
39693970
case SILFunctionTypeRepresentation::WitnessMethod: {
39703971
// No bridging needed for native functions.
3971-
if (t->getExtInfo() == extInfo)
3972+
if (t->getExtInfo().isEqualTo(extInfo, useClangTypes(t)))
39723973
return t;
39733974
return CanAnyFunctionType::get(genericSig, t.getParams(), t.getResult(),
39743975
extInfo);

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,8 +3718,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
37183718
.withRepresentation(SILFunctionType::Representation::Thick)
37193719
.withNoEscape(resFTy->isNoEscape())
37203720
.build();
3721-
require(adjustedOperandExtInfo == resFTy->getExtInfo(),
3722-
"operand and result of thin_to_think_function must agree in particulars");
3721+
require(adjustedOperandExtInfo.isEqualTo(resFTy->getExtInfo(),
3722+
useClangTypes(opFTy)),
3723+
"operand and result of thin_to_think_function must agree in "
3724+
"particulars");
37233725
}
37243726

37253727
void checkThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCI) {

lib/SILGen/SILGenPoly.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,8 +3476,9 @@ static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
34763476
CanSILFunctionType &escapingType, GenericEnvironment *&genericEnv,
34773477
SubstitutionMap &interfaceSubs, CanType &dynamicSelfType) {
34783478

3479-
assert(escapingType->getExtInfo() ==
3480-
noEscapingType->getExtInfo().withNoEscape(false));
3479+
assert(escapingType->getExtInfo().isEqualTo(
3480+
noEscapingType->getExtInfo().withNoEscape(false),
3481+
useClangTypes(escapingType)));
34813482

34823483
CanType inputSubstType, outputSubstType;
34833484
auto type = SGF.buildThunkType(noEscapingType, escapingType,
@@ -3539,8 +3540,9 @@ SILGenFunction::createWithoutActuallyEscapingClosure(
35393540
auto noEscapingFnSubstTy = noEscapingFunctionValue.getType()
35403541
.castTo<SILFunctionType>();
35413542
// TODO: maybe this should use a more explicit instruction.
3542-
assert(escapingFnSubstTy->getExtInfo() == noEscapingFnSubstTy->getExtInfo()
3543-
.withNoEscape(false));
3543+
assert(escapingFnSubstTy->getExtInfo().isEqualTo(
3544+
noEscapingFnSubstTy->getExtInfo().withNoEscape(false),
3545+
useClangTypes(escapingFnSubstTy)));
35443546

35453547
// Apply function type substitutions, since the code sequence for a thunk
35463548
// doesn't vary with function representation.

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static void adjustFunctionTypeForOverride(Type &type) {
3535
auto fnType = type->castTo<AnyFunctionType>();
3636
auto extInfo = fnType->getExtInfo();
3737
extInfo = extInfo.withThrows(false);
38-
if (fnType->getExtInfo() != extInfo)
38+
if (!fnType->getExtInfo().isEqualTo(extInfo, useClangTypes(fnType)))
3939
type = fnType->withExtInfo(extInfo);
4040
}
4141

0 commit comments

Comments
 (0)