Skip to content

Commit 13d24e0

Browse files
Merge pull request #4330 from aschwaighofer/irgen_fix_bind_archetype_access_path
IRGen: Bind archetype access paths in emitFieldTypeAccessor
2 parents e706666 + 5369988 commit 13d24e0

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
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: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -995,10 +995,6 @@ getWitnessTableLazyAccessFunction(IRGenModule &IGM,
995995
return accessor;
996996
}
997997

998-
static void bindArchetypeAccessPaths(IRGenFunction &IGF,
999-
GenericSignature *Generics,
1000-
GetTypeParameterInContextFn getInContext);
1001-
1002998
namespace {
1003999

10041000
/// Conformance info for a witness table that can be directly generated.
@@ -1853,9 +1849,8 @@ void addPotentialArchetypeAccessPath(IRGenFunction &IGF,
18531849
{srcBaseArchetype, association});
18541850
}
18551851

1856-
static void bindArchetypeAccessPaths(IRGenFunction &IGF,
1857-
GenericSignature *Generics,
1858-
GetTypeParameterInContextFn getInContext) {
1852+
void irgen::bindArchetypeAccessPaths(IRGenFunction &IGF, GenericSignature *Generics,
1853+
GetTypeParameterInContextFn getInContext) {
18591854
// Remember all the extra ways we have of reaching the parameter
18601855
// archetypes due to type equality constraints.
18611856
for (auto reqt : Generics->getRequirements()) {

test/IRGen/same_type_constraints.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,22 @@ public class C2<T: Equatable, U: P where T == U.Foo>: C1<T> {}
2323

2424
// CHECK: define{{( protected)?}} void @_TFC21same_type_constraints2C1D
2525

26-
public protocol DataType {}
26+
public protocol MyHashable {}
27+
public protocol DataType : MyHashable {}
2728

2829
public protocol E {
2930
associatedtype Data: DataType
3031
}
3132

33+
struct Dict<V : MyHashable, K> {}
34+
struct Val {}
35+
3236
public class GenericKlazz<T: DataType, R: E> : E where R.Data == T
3337
{
3438
public typealias Data = T
39+
40+
var d: Dict<T, Val>
41+
init() {
42+
d = Dict()
43+
}
3544
}

0 commit comments

Comments
 (0)