Skip to content

Commit

Permalink
Merge pull request #4330 from aschwaighofer/irgen_fix_bind_archetype_…
Browse files Browse the repository at this point in the history
…access_path

IRGen: Bind archetype access paths in emitFieldTypeAccessor
  • Loading branch information
aschwaighofer committed Aug 17, 2016
2 parents e706666 + 5369988 commit 13d24e0
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
8 changes: 8 additions & 0 deletions lib/IRGen/GenArchetype.h
Expand Up @@ -18,6 +18,7 @@
#define SWIFT_IRGEN_GENARCHETYPE_H

#include "swift/AST/Types.h"
#include "llvm/ADT/STLExtras.h"

namespace llvm {
class Value;
Expand All @@ -31,6 +32,13 @@ namespace irgen {
class Address;
class IRGenFunction;

using GetTypeParameterInContextFn =
llvm::function_ref<CanType(CanType type)>;

void bindArchetypeAccessPaths(IRGenFunction &IGF,
GenericSignature *generics,
GetTypeParameterInContextFn getInContext);

/// Emit a type metadata reference for an archetype.
llvm::Value *emitArchetypeTypeMetadataRef(IRGenFunction &IGF,
CanArchetypeType archetype);
Expand Down
12 changes: 12 additions & 0 deletions lib/IRGen/GenMeta.cpp
Expand Up @@ -2762,6 +2762,18 @@ irgen::emitFieldTypeAccessor(IRGenModule &IGM,
// use it to provide metadata for generic parameters in field types.
IGF.bindLocalTypeDataFromTypeMetadata(formalType, IsExact, metadata);

// Bind archetype access paths if the type is generic.
if (type->isGenericContext()) {
auto declCtxt = type;
if (auto generics = declCtxt->getGenericSignatureOfContext()) {
auto getInContext = [&](CanType type) -> CanType {
return ArchetypeBuilder::mapTypeIntoContext(declCtxt, type, nullptr)
->getCanonicalType();
};
bindArchetypeAccessPaths(IGF, generics, getInContext);
}
}

// Allocate storage for the field vector.
unsigned allocSize = fieldTypes.size() * IGM.getPointerSize().getValue();
auto allocSizeVal = llvm::ConstantInt::get(IGM.IntPtrTy, allocSize);
Expand Down
9 changes: 2 additions & 7 deletions lib/IRGen/GenProto.cpp
Expand Up @@ -995,10 +995,6 @@ getWitnessTableLazyAccessFunction(IRGenModule &IGM,
return accessor;
}

static void bindArchetypeAccessPaths(IRGenFunction &IGF,
GenericSignature *Generics,
GetTypeParameterInContextFn getInContext);

namespace {

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

static void bindArchetypeAccessPaths(IRGenFunction &IGF,
GenericSignature *Generics,
GetTypeParameterInContextFn getInContext) {
void irgen::bindArchetypeAccessPaths(IRGenFunction &IGF, GenericSignature *Generics,
GetTypeParameterInContextFn getInContext) {
// Remember all the extra ways we have of reaching the parameter
// archetypes due to type equality constraints.
for (auto reqt : Generics->getRequirements()) {
Expand Down
11 changes: 10 additions & 1 deletion test/IRGen/same_type_constraints.swift
Expand Up @@ -23,13 +23,22 @@ public class C2<T: Equatable, U: P where T == U.Foo>: C1<T> {}

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

public protocol DataType {}
public protocol MyHashable {}
public protocol DataType : MyHashable {}

public protocol E {
associatedtype Data: DataType
}

struct Dict<V : MyHashable, K> {}
struct Val {}

public class GenericKlazz<T: DataType, R: E> : E where R.Data == T
{
public typealias Data = T

var d: Dict<T, Val>
init() {
d = Dict()
}
}

0 comments on commit 13d24e0

Please sign in to comment.