Skip to content

Commit 3ca6467

Browse files
authored
Merge pull request #4555 from aschwaighofer/swift-3.0-branch-sr1951-fix-2
Swift 3.0 branch SR1951 Fix 2
2 parents 6fd6c13 + d8b18fc commit 3ca6467

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

lib/IRGen/GenArchetype.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define SWIFT_IRGEN_GENARCHETYPE_H
1919

2020
#include "swift/AST/Types.h"
21+
#include "llvm/ADT/STLExtras.h"
2122

2223
namespace llvm {
2324
class Value;
@@ -31,6 +32,13 @@ namespace irgen {
3132
class Address;
3233
class IRGenFunction;
3334

35+
using GetTypeParameterInContextFn =
36+
llvm::function_ref<CanType(CanType type)>;
37+
38+
void bindArchetypeAccessPaths(IRGenFunction &IGF,
39+
GenericSignature *generics,
40+
GetTypeParameterInContextFn getInContext);
41+
3442
/// Emit a type metadata reference for an archetype.
3543
llvm::Value *emitArchetypeTypeMetadataRef(IRGenFunction &IGF,
3644
CanArchetypeType archetype);

lib/IRGen/GenMeta.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2762,6 +2762,18 @@ irgen::emitFieldTypeAccessor(IRGenModule &IGM,
27622762
// use it to provide metadata for generic parameters in field types.
27632763
IGF.bindLocalTypeDataFromTypeMetadata(formalType, IsExact, metadata);
27642764

2765+
// Bind archetype access paths if the type is generic.
2766+
if (type->isGenericContext()) {
2767+
auto declCtxt = type;
2768+
if (auto generics = declCtxt->getGenericSignatureOfContext()) {
2769+
auto getInContext = [&](CanType type) -> CanType {
2770+
return ArchetypeBuilder::mapTypeIntoContext(declCtxt, type, nullptr)
2771+
->getCanonicalType();
2772+
};
2773+
bindArchetypeAccessPaths(IGF, generics, getInContext);
2774+
}
2775+
}
2776+
27652777
// Allocate storage for the field vector.
27662778
unsigned allocSize = fieldTypes.size() * IGM.getPointerSize().getValue();
27672779
auto allocSizeVal = llvm::ConstantInt::get(IGM.IntPtrTy, allocSize);

lib/IRGen/GenProto.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,17 @@ class AccessorConformanceInfo : public ConformanceInfo {
12761276
}
12771277
return *Fulfillments;
12781278
}
1279+
1280+
void bindArchetypeAccessPathsInConformance(IRGenFunction &IGF) {
1281+
auto declCtx = Conformance.getDeclContext();
1282+
if (auto generics = declCtx->getGenericSignatureOfContext()) {
1283+
auto getInContext = [&](CanType type) -> CanType {
1284+
return ArchetypeBuilder::mapTypeIntoContext(declCtx, type, nullptr)
1285+
->getCanonicalType();
1286+
};
1287+
bindArchetypeAccessPaths(IGF, generics, getInContext);
1288+
}
1289+
}
12791290
};
12801291
}
12811292

@@ -1335,6 +1346,9 @@ getAssociatedTypeMetadataAccessFunction(AssociatedTypeDecl *requirement,
13351346
// Bind local type data from the metadata argument.
13361347
IGF.bindLocalTypeDataFromTypeMetadata(ConcreteType, IsExact, self);
13371348

1349+
// Bind archetype access paths.
1350+
bindArchetypeAccessPathsInConformance(IGF);
1351+
13381352
// For now, assume that an associated type is cheap enough to access
13391353
// that it doesn't need a new cache entry.
13401354
if (auto archetype = dyn_cast<ArchetypeType>(associatedType)) {
@@ -1458,6 +1472,9 @@ getAssociatedTypeWitnessTableAccessFunction(AssociatedTypeDecl *requirement,
14581472
associatedTypeMetadata);
14591473
IGF.bindLocalTypeDataFromTypeMetadata(ConcreteType, IsExact, self);
14601474

1475+
// Bind archetype access paths.
1476+
bindArchetypeAccessPathsInConformance(IGF);
1477+
14611478
// For now, assume that finding an abstract conformance is always
14621479
// fast enough that it's not worth caching.
14631480
// TODO: provide an API to find the best metadata path to the conformance
@@ -1832,9 +1849,8 @@ void addPotentialArchetypeAccessPath(IRGenFunction &IGF,
18321849
{srcBaseArchetype, association});
18331850
}
18341851

1835-
static void bindArchetypeAccessPaths(IRGenFunction &IGF,
1836-
GenericSignature *Generics,
1837-
GetTypeParameterInContextFn getInContext) {
1852+
void irgen::bindArchetypeAccessPaths(IRGenFunction &IGF, GenericSignature *Generics,
1853+
GetTypeParameterInContextFn getInContext) {
18381854
// Remember all the extra ways we have of reaching the parameter
18391855
// archetypes due to type equality constraints.
18401856
for (auto reqt : Generics->getRequirements()) {

test/IRGen/same_type_constraints.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,23 @@ public class C1<T: Equatable> { }
2222
public class C2<T: Equatable, U: P where T == U.Foo>: C1<T> {}
2323

2424
// CHECK: define{{( protected)?}} void @_TFC21same_type_constraints2C1D
25+
26+
public protocol MyHashable {}
27+
public protocol DataType : MyHashable {}
28+
29+
public protocol E {
30+
associatedtype Data: DataType
31+
}
32+
33+
struct Dict<V : MyHashable, K> {}
34+
struct Val {}
35+
36+
public class GenericKlazz<T: DataType, R: E> : E where R.Data == T
37+
{
38+
public typealias Data = T
39+
40+
var d: Dict<T, Val>
41+
init() {
42+
d = Dict()
43+
}
44+
}

0 commit comments

Comments
 (0)