mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add a BuiltinGenericType base class.
Builtin.FixedArray was introduced as the first generic builtin type, with special case handling in all the various recursive visitors. Introduce a base class, and move the handling to that base class, so it is easier to introduce other generic builtins in the future.
This commit is contained in:
@@ -1609,6 +1609,10 @@ public:
|
||||
OutputBackend = std::move(OutBackend);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class BuiltinGenericType;
|
||||
GenericSignature &getCachedBuiltinGenericTypeSignature(TypeKind kind);
|
||||
|
||||
private:
|
||||
friend Decl;
|
||||
|
||||
|
||||
@@ -134,13 +134,28 @@ public:
|
||||
CanBuiltinUnboundGenericType type2) {
|
||||
return asImpl().visitDifferentTypeStructure(type1, type2);
|
||||
}
|
||||
|
||||
bool visitBuiltinFixedArrayType(CanBuiltinFixedArrayType type1,
|
||||
CanBuiltinFixedArrayType type2) {
|
||||
if (asImpl().visit(type1->getSize(), type2->getSize())) {
|
||||
|
||||
bool visitBuiltinGenericType(CanBuiltinGenericType type1,
|
||||
CanBuiltinGenericType type2) {
|
||||
if (type1->getBuiltinTypeKind() != type2->getBuiltinTypeKind()) {
|
||||
return true;
|
||||
}
|
||||
return asImpl().visit(type1->getElementType(), type2->getElementType());
|
||||
|
||||
auto subs1 = type1->getSubstitutions();
|
||||
auto subs2 = type2->getSubstitutions();
|
||||
|
||||
for (unsigned i : indices(subs1.getReplacementTypes())) {
|
||||
if (asImpl().visit(CanType(subs1.getReplacementTypes()[i]),
|
||||
CanType(subs2.getReplacementTypes()[i]))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (unsigned i : indices(subs1.getConformances())) {
|
||||
if (subs1.getConformances()[i] != subs2.getConformances()[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visitPackType(CanPackType type1, CanPackType type2) {
|
||||
|
||||
@@ -112,7 +112,7 @@ private:
|
||||
TRIVIAL_CASE(BuiltinFloatType)
|
||||
TRIVIAL_CASE(BuiltinVectorType)
|
||||
TRIVIAL_CASE(BuiltinUnboundGenericType)
|
||||
TRIVIAL_CASE(BuiltinFixedArrayType)
|
||||
TRIVIAL_CASE(BuiltinGenericType)
|
||||
TRIVIAL_CASE(IntegerType)
|
||||
#define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type)
|
||||
#include "swift/AST/TypeNodes.def"
|
||||
|
||||
@@ -141,7 +141,9 @@ ABSTRACT_TYPE(Builtin, Type)
|
||||
BUILTIN_CONCRETE_TYPE(BuiltinDefaultActorStorage, BuiltinType)
|
||||
BUILTIN_CONCRETE_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
|
||||
BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
|
||||
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
|
||||
ABSTRACT_TYPE(BuiltinGeneric, BuiltinType)
|
||||
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinGenericType)
|
||||
TYPE_RANGE(BuiltinGeneric, BuiltinFixedArray, BuiltinFixedArray)
|
||||
BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
|
||||
BUILTIN_CONCRETE_TYPE(BuiltinImplicitActor, BuiltinType)
|
||||
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinImplicitActor)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "swift/AST/GenericEnvironment.h"
|
||||
#include "swift/AST/SILLayout.h"
|
||||
#include "swift/AST/LifetimeDependence.h"
|
||||
#include "swift/AST/SubstitutionMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
@@ -117,29 +119,26 @@ case TypeKind::Id:
|
||||
case TypeKind::Integer:
|
||||
return t;
|
||||
|
||||
// BuiltinGenericType subclasses
|
||||
case TypeKind::BuiltinFixedArray: {
|
||||
auto bfaTy = cast<BuiltinFixedArrayType>(base);
|
||||
|
||||
Type transSize = doIt(bfaTy->getSize(),
|
||||
TypePosition::Invariant);
|
||||
if (!transSize) {
|
||||
return Type();
|
||||
auto bgaTy = cast<BuiltinGenericType>(base);
|
||||
|
||||
llvm::SmallVector<Type, 2> transReplacements;
|
||||
|
||||
for (auto t : bgaTy->getSubstitutions().getReplacementTypes()) {
|
||||
Type transTy = doIt(t, TypePosition::Invariant);
|
||||
if (!transTy) {
|
||||
return Type();
|
||||
}
|
||||
transReplacements.push_back(transTy);
|
||||
}
|
||||
|
||||
Type transElement = doIt(bfaTy->getElementType(),
|
||||
TypePosition::Invariant);
|
||||
if (!transElement) {
|
||||
return Type();
|
||||
}
|
||||
|
||||
CanType canTransSize = transSize->getCanonicalType();
|
||||
CanType canTransElement = transElement->getCanonicalType();
|
||||
if (canTransSize != bfaTy->getSize()
|
||||
|| canTransElement != bfaTy->getElementType()) {
|
||||
return BuiltinFixedArrayType::get(canTransSize, canTransElement);
|
||||
}
|
||||
|
||||
return bfaTy;
|
||||
|
||||
// TODO: translate conformances. No builtin types yet have conformance
|
||||
// requirements in their generic signatures.
|
||||
auto transSubs = SubstitutionMap::get(bgaTy->getGenericSignature(),
|
||||
transReplacements,
|
||||
ArrayRef<ProtocolConformanceRef>{});
|
||||
return bgaTy->getWithSubstitutions(transSubs);
|
||||
}
|
||||
|
||||
case TypeKind::PrimaryArchetype:
|
||||
|
||||
@@ -1780,12 +1780,45 @@ public:
|
||||
};
|
||||
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinUnboundGenericType, BuiltinType)
|
||||
|
||||
/// BuiltinGenericType - Base class for builtins that are parameterized by
|
||||
/// a generic signature.
|
||||
class BuiltinGenericType : public BuiltinType {
|
||||
protected:
|
||||
|
||||
BuiltinGenericType(TypeKind kind, ASTContext &context,
|
||||
RecursiveTypeProperties properties)
|
||||
: BuiltinType(kind, context, properties)
|
||||
{}
|
||||
|
||||
/// The substitution map is cached here once requested.
|
||||
mutable std::optional<SubstitutionMap> CachedSubstitutionMap = std::nullopt;
|
||||
|
||||
public:
|
||||
static bool classof(const TypeBase *T) {
|
||||
return T->getKind() >= TypeKind::First_BuiltinGenericType
|
||||
&& T->getKind() <= TypeKind::Last_BuiltinGenericType;
|
||||
}
|
||||
|
||||
// Get the generic signature describing the parameterization of types of
|
||||
// this class.
|
||||
GenericSignature getGenericSignature() const;
|
||||
|
||||
// Get the substitution map for this particular type.
|
||||
SubstitutionMap getSubstitutions() const;
|
||||
|
||||
// Produce another type of the same class but with different arguments.
|
||||
CanTypeWrapper<BuiltinGenericType>
|
||||
getWithSubstitutions(SubstitutionMap newSubs) const;
|
||||
};
|
||||
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinGenericType, BuiltinType)
|
||||
|
||||
/// BuiltinFixedArrayType - The builtin type representing N values stored
|
||||
/// inline contiguously.
|
||||
///
|
||||
/// All elements of a value of this type must be fully initialized any time the
|
||||
/// value may be copied, moved, or destroyed.
|
||||
class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
|
||||
class BuiltinFixedArrayType : public BuiltinGenericType,
|
||||
public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
|
||||
CanType Size;
|
||||
@@ -1793,12 +1826,17 @@ class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
|
||||
|
||||
BuiltinFixedArrayType(CanType Size, CanType ElementType,
|
||||
RecursiveTypeProperties properties)
|
||||
: BuiltinType(TypeKind::BuiltinFixedArray, ElementType->getASTContext(),
|
||||
properties),
|
||||
: BuiltinGenericType(TypeKind::BuiltinFixedArray,
|
||||
ElementType->getASTContext(),
|
||||
properties),
|
||||
Size(Size),
|
||||
ElementType(ElementType)
|
||||
{}
|
||||
|
||||
friend BuiltinGenericType;
|
||||
/// Get the generic arguments as a substitution map.
|
||||
SubstitutionMap buildSubstitutions() const;
|
||||
|
||||
public:
|
||||
/// Arrays with more elements than this are always treated as in-memory values.
|
||||
///
|
||||
@@ -1826,7 +1864,7 @@ public:
|
||||
|
||||
/// Get the element type.
|
||||
CanType getElementType() const { return ElementType; }
|
||||
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
Profile(ID, getSize(), getElementType());
|
||||
}
|
||||
@@ -1836,7 +1874,7 @@ public:
|
||||
ID.AddPointer(ElementType.getPointer());
|
||||
}
|
||||
};
|
||||
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinType)
|
||||
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinGenericType)
|
||||
|
||||
/// BuiltinRawPointerType - The builtin raw (and dangling) pointer type. This
|
||||
/// pointer is completely unmanaged and is equivalent to i8* in LLVM IR.
|
||||
|
||||
@@ -533,6 +533,13 @@ struct ASTContext::Implementation {
|
||||
/// Local and closure discriminators per context.
|
||||
llvm::DenseMap<const DeclContext *, unsigned> NextDiscriminator;
|
||||
|
||||
/// Cached generic signatures for generic builtin types.
|
||||
static const unsigned NumBuiltinGenericTypes
|
||||
= unsigned(TypeKind::Last_BuiltinGenericType)
|
||||
- unsigned(TypeKind::First_BuiltinGenericType) + 1;
|
||||
std::array<GenericSignature, NumBuiltinGenericTypes>
|
||||
BuiltinGenericTypeSignatures = {};
|
||||
|
||||
/// Structure that captures data that is segregated into different
|
||||
/// arenas.
|
||||
struct Arena {
|
||||
@@ -7309,3 +7316,13 @@ AvailabilityDomain ASTContext::getTargetAvailabilityDomain() const {
|
||||
// Fall back to the universal domain for triples without a platform.
|
||||
return AvailabilityDomain::forUniversal();
|
||||
}
|
||||
|
||||
GenericSignature &
|
||||
ASTContext::getCachedBuiltinGenericTypeSignature(TypeKind kind) {
|
||||
ASSERT(kind >= TypeKind::First_BuiltinGenericType
|
||||
&& kind <= TypeKind::Last_BuiltinGenericType
|
||||
&& "not a builtin generic type kind");
|
||||
|
||||
return getImpl().BuiltinGenericTypeSignatures
|
||||
[unsigned(kind) - unsigned(TypeKind::First_BuiltinGenericType)];
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "swift/AST/FileUnit.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/AST/ParameterList.h"
|
||||
#include "swift/AST/SubstitutionMap.h"
|
||||
#include "swift/AST/TypeCheckRequests.h"
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include <tuple>
|
||||
|
||||
@@ -3649,11 +3651,10 @@ BuiltinUnboundGenericType::getBuiltinTypeNameString() const {
|
||||
return getBuiltinTypeName();
|
||||
}
|
||||
|
||||
GenericSignature
|
||||
BuiltinUnboundGenericType::getGenericSignature() const {
|
||||
auto &C = getASTContext();
|
||||
|
||||
switch (BoundGenericTypeKind) {
|
||||
static GenericSignature
|
||||
getBuiltinGenericSignature(ASTContext &C,
|
||||
TypeKind kind) {
|
||||
switch (kind) {
|
||||
case TypeKind::BuiltinFixedArray: {
|
||||
auto Count = GenericTypeParamType::get(C.getIdentifier("Count"),
|
||||
GenericTypeParamKind::Value,
|
||||
@@ -3663,35 +3664,48 @@ BuiltinUnboundGenericType::getGenericSignature() const {
|
||||
0, 1, Type(), C);
|
||||
return GenericSignature::get({Count, Element}, {});
|
||||
}
|
||||
|
||||
|
||||
case TypeKind::BuiltinInteger: {
|
||||
auto bits = GenericTypeParamType::get(C.getIdentifier("Bits"),
|
||||
GenericTypeParamKind::Type,
|
||||
0, 0, C.getIntType(), C);
|
||||
return GenericSignature::get(bits, {});
|
||||
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("not a generic builtin");
|
||||
llvm_unreachable("not a generic builtin type");
|
||||
}
|
||||
}
|
||||
|
||||
Type
|
||||
BuiltinUnboundGenericType::getBound(SubstitutionMap subs) const {
|
||||
if (!subs.getGenericSignature()->isEqual(getGenericSignature())) {
|
||||
return ErrorType::get(const_cast<BuiltinUnboundGenericType*>(this));
|
||||
GenericSignature
|
||||
BuiltinUnboundGenericType::getGenericSignature() const {
|
||||
return getBuiltinGenericSignature(getASTContext(), BoundGenericTypeKind);
|
||||
}
|
||||
|
||||
static Type
|
||||
getBuiltinBoundGenericType(ASTContext &C,
|
||||
TypeKind kind,
|
||||
SubstitutionMap subs,
|
||||
bool validate) {
|
||||
if (!subs.getGenericSignature()->isEqual(getBuiltinGenericSignature(C, kind))) {
|
||||
return ErrorType::get(BuiltinUnboundGenericType::get(kind, C));
|
||||
}
|
||||
|
||||
switch (BoundGenericTypeKind) {
|
||||
switch (kind) {
|
||||
case TypeKind::BuiltinFixedArray: {
|
||||
auto types = subs.getReplacementTypes();
|
||||
|
||||
auto size = types[0]->getCanonicalType();
|
||||
if (size->getMatchingParamKind() != GenericTypeParamKind::Value) {
|
||||
return ErrorType::get(const_cast<BuiltinUnboundGenericType*>(this));
|
||||
if (validate
|
||||
&& size->getMatchingParamKind() != GenericTypeParamKind::Value
|
||||
&& !size->hasTypeVariableOrPlaceholder()) {
|
||||
return ErrorType::get(BuiltinUnboundGenericType::get(kind, C));
|
||||
}
|
||||
auto element = types[1]->getCanonicalType();
|
||||
if (element->getMatchingParamKind() != GenericTypeParamKind::Type) {
|
||||
return ErrorType::get(const_cast<BuiltinUnboundGenericType*>(this));
|
||||
if (validate
|
||||
&& element->getMatchingParamKind() != GenericTypeParamKind::Type
|
||||
&& !element->hasTypeVariableOrPlaceholder()) {
|
||||
return ErrorType::get(BuiltinUnboundGenericType::get(kind, C));
|
||||
}
|
||||
|
||||
return BuiltinFixedArrayType::get(size, element);
|
||||
@@ -3699,19 +3713,20 @@ BuiltinUnboundGenericType::getBound(SubstitutionMap subs) const {
|
||||
|
||||
case TypeKind::BuiltinInteger: {
|
||||
auto size = subs.getReplacementTypes()[0];
|
||||
if (size->getMatchingParamKind() != GenericTypeParamKind::Value) {
|
||||
return ErrorType::get(const_cast<BuiltinUnboundGenericType*>(this));
|
||||
if (validate
|
||||
&& size->getMatchingParamKind() != GenericTypeParamKind::Value) {
|
||||
return ErrorType::get(BuiltinUnboundGenericType::get(kind, C));
|
||||
}
|
||||
|
||||
// TODO: support actual generic parameters
|
||||
auto literalSize = size->getAs<IntegerType>();
|
||||
|
||||
if (!literalSize) {
|
||||
return ErrorType::get(const_cast<BuiltinUnboundGenericType*>(this));
|
||||
assert(validate && "can't represent an unbound generic sized integer yet");
|
||||
return ErrorType::get(BuiltinUnboundGenericType::get(kind, C));
|
||||
}
|
||||
|
||||
return BuiltinIntegerType::get(literalSize->getValue().getLimitedValue(),
|
||||
getASTContext());
|
||||
return BuiltinIntegerType::get(literalSize->getValue().getLimitedValue(),C);
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -3719,6 +3734,59 @@ BuiltinUnboundGenericType::getBound(SubstitutionMap subs) const {
|
||||
}
|
||||
}
|
||||
|
||||
Type
|
||||
BuiltinUnboundGenericType::getBound(SubstitutionMap subs) const {
|
||||
return getBuiltinBoundGenericType(getASTContext(), BoundGenericTypeKind,
|
||||
subs, /*validate*/ true);
|
||||
}
|
||||
|
||||
CanBuiltinGenericType
|
||||
BuiltinGenericType::getWithSubstitutions(SubstitutionMap subs) const {
|
||||
auto t = getBuiltinBoundGenericType(getASTContext(), getKind(), subs,
|
||||
/*validate*/ false);
|
||||
return CanBuiltinGenericType(t->castTo<BuiltinGenericType>());
|
||||
}
|
||||
|
||||
GenericSignature
|
||||
BuiltinGenericType::getGenericSignature() const {
|
||||
auto &cached = getASTContext()
|
||||
.getCachedBuiltinGenericTypeSignature(getKind());
|
||||
|
||||
if (!cached) {
|
||||
cached = getBuiltinGenericSignature(getASTContext(), getKind());
|
||||
}
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
SubstitutionMap
|
||||
BuiltinGenericType::getSubstitutions() const {
|
||||
if (auto cached = CachedSubstitutionMap) {
|
||||
return *cached;
|
||||
}
|
||||
|
||||
auto buildSubstitutions = [&]() -> SubstitutionMap {
|
||||
#define BUILTIN_GENERIC_SUBCLASS(c) \
|
||||
if (auto t = dyn_cast<c>(this)) { \
|
||||
return t->c::buildSubstitutions(); \
|
||||
}
|
||||
|
||||
BUILTIN_GENERIC_SUBCLASS(BuiltinFixedArrayType)
|
||||
llvm_unreachable("unhandled BuiltinGenericType subclass");
|
||||
};
|
||||
|
||||
auto subs = buildSubstitutions();
|
||||
CachedSubstitutionMap = subs;
|
||||
return subs;
|
||||
}
|
||||
|
||||
SubstitutionMap
|
||||
BuiltinFixedArrayType::buildSubstitutions() const {
|
||||
return SubstitutionMap::get(getGenericSignature(),
|
||||
{getSize(), getElementType()},
|
||||
ArrayRef<ProtocolConformanceRef>{});
|
||||
}
|
||||
|
||||
std::optional<uint64_t>
|
||||
BuiltinFixedArrayType::getFixedInhabitedSize() const {
|
||||
if (auto intSize = getSize()->getAs<IntegerType>()) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "swift/AST/TypeWalker.h"
|
||||
#include "swift/AST/TypeVisitor.h"
|
||||
#include "swift/AST/GenericEnvironment.h"
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
|
||||
using namespace swift;
|
||||
@@ -301,17 +302,16 @@ class Traversal : public TypeVisitor<Traversal, bool>
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visitBuiltinFixedArrayType(BuiltinFixedArrayType *ty) {
|
||||
if (ty->getSize() && doIt(ty->getSize())) {
|
||||
return true;
|
||||
}
|
||||
if (ty->getElementType() && doIt(ty->getElementType())) {
|
||||
return true;
|
||||
|
||||
bool visitBuiltinGenericType(BuiltinGenericType *ty) {
|
||||
for (auto replacement : ty->getSubstitutions().getReplacementTypes()) {
|
||||
if (replacement && doIt(replacement)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
explicit Traversal(TypeWalker &walker) : Walker(walker) {}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/AST/Types.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#define DEBUG_TYPE "libsil"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ConformanceLookup.h"
|
||||
@@ -2673,32 +2675,38 @@ public:
|
||||
// Otherwise, there are no structural type parameters to visit.
|
||||
return nom;
|
||||
}
|
||||
|
||||
CanType visitBuiltinFixedArrayType(CanBuiltinFixedArrayType bfa,
|
||||
AbstractionPattern pattern) {
|
||||
auto orig = pattern.getAs<BuiltinFixedArrayType>();
|
||||
|
||||
CanType visitBuiltinGenericType(CanBuiltinGenericType bga,
|
||||
AbstractionPattern pattern) {
|
||||
auto orig = pattern.getAs<BuiltinGenericType>();
|
||||
|
||||
// If there are no loose type parameters in the pattern here, we don't need
|
||||
// to do a recursive visit at all.
|
||||
if (!orig->hasTypeParameter()
|
||||
&& !orig->hasArchetype()
|
||||
&& !orig->hasOpaqueArchetype()) {
|
||||
return bfa;
|
||||
return bga;
|
||||
}
|
||||
|
||||
CanType newSize = visit(bfa->getSize(),
|
||||
AbstractionPattern(pattern.getGenericSubstitutions(),
|
||||
pattern.getGenericSignatureOrNull(),
|
||||
orig->getSize()));
|
||||
CanType newElement = visit(bfa->getElementType(),
|
||||
AbstractionPattern(pattern.getGenericSubstitutions(),
|
||||
pattern.getGenericSignatureOrNull(),
|
||||
orig->getElementType()));
|
||||
|
||||
return BuiltinFixedArrayType::get(newSize, newElement)
|
||||
->getCanonicalType();
|
||||
|
||||
SmallVector<Type, 2> newReplacements;
|
||||
|
||||
for (unsigned i : indices(bga->getSubstitutions().getReplacementTypes())) {
|
||||
CanType newReplacement
|
||||
= visit(CanType(bga->getSubstitutions().getReplacementTypes()[i]),
|
||||
AbstractionPattern(pattern.getGenericSubstitutions(),
|
||||
pattern.getGenericSignatureOrNull(),
|
||||
CanType(orig->getSubstitutions().getReplacementTypes()[i])));
|
||||
newReplacements.push_back(newReplacement);
|
||||
}
|
||||
|
||||
// TODO: handle conformances. no generic builtins currently have protocol
|
||||
// requirements.
|
||||
auto newSubs = SubstitutionMap::get(bga->getGenericSignature(),
|
||||
newReplacements,
|
||||
ArrayRef<ProtocolConformanceRef>{});
|
||||
return bga->getWithSubstitutions(newSubs);
|
||||
}
|
||||
|
||||
|
||||
CanType visitBoundGenericType(CanBoundGenericType bgt,
|
||||
AbstractionPattern pattern) {
|
||||
return handleGenericNominalType(pattern, bgt);
|
||||
|
||||
@@ -7471,21 +7471,28 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
|
||||
case TypeKind::Error:
|
||||
return getTypeMatchFailure(locator);
|
||||
|
||||
// BuiltinGenericType subclasses
|
||||
case TypeKind::BuiltinFixedArray: {
|
||||
auto *fixed1 = cast<BuiltinFixedArrayType>(desugar1);
|
||||
auto *fixed2 = cast<BuiltinFixedArrayType>(desugar2);
|
||||
auto *fixed1 = cast<BuiltinGenericType>(desugar1);
|
||||
auto *fixed2 = cast<BuiltinGenericType>(desugar2);
|
||||
if (fixed1->getBuiltinTypeKind() != fixed2->getBuiltinTypeKind()) {
|
||||
return getTypeMatchFailure(locator);
|
||||
}
|
||||
|
||||
auto result = matchTypes(fixed1->getSize(), fixed2->getSize(),
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
auto result = ConstraintSystem::TypeMatchResult::success();
|
||||
for (unsigned i
|
||||
: indices(fixed1->getSubstitutions().getReplacementTypes())) {
|
||||
result = matchTypes(fixed1->getSubstitutions().getReplacementTypes()[i],
|
||||
fixed2->getSubstitutions().getReplacementTypes()[i],
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::GenericArgument(i)));
|
||||
if (result.isFailure()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return matchTypes(fixed1->getElementType(), fixed2->getElementType(),
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
return result;
|
||||
}
|
||||
|
||||
case TypeKind::Placeholder: {
|
||||
|
||||
Reference in New Issue
Block a user