Skip to content

Introduce GenericEnvironment refactoring and kill AllArchetypes #4524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Aug 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions include/swift/AST/ArchetypeBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,19 @@ class ArchetypeBuilder {
/// \brief Get a generic signature based on the provided complete list
/// of generic parameter types.
///
/// \returns a generic signature build based on the provided list of
/// \returns a generic signature built from the provided list of
/// generic parameter types.
GenericSignature *
getGenericSignature(ArrayRef<GenericTypeParamType *> genericParamsTypes);

/// \brief Get a generic context based on the complete list of generic
/// parameter types.
///
/// \returns a generic context built from the provided list of
/// generic parameter types.
GenericEnvironment *getGenericEnvironment(
ArrayRef<GenericTypeParamType *> genericParamsTypes);

/// Infer requirements from the given type, recursively.
///
/// This routine infers requirements from a type that occurs within the
Expand Down Expand Up @@ -315,27 +323,20 @@ class ArchetypeBuilder {
/// parameter.
ArchetypeType *getArchetype(GenericTypeParamDecl *GenericParam);

/// \brief Retrieve the array of all of the archetypes produced during
/// archetype assignment. The 'primary' archetypes will occur first in this
/// list.
ArrayRef<ArchetypeType *> getAllArchetypes();

/// Map an interface type to a contextual type.
static Type mapTypeIntoContext(const DeclContext *dc, Type type,
LazyResolver *resolver = nullptr);
static Type mapTypeIntoContext(const DeclContext *dc, Type type);

/// Map an interface type to a contextual type.
static Type mapTypeIntoContext(ModuleDecl *M,
GenericParamList *genericParams,
Type type,
LazyResolver *resolver = nullptr);
GenericEnvironment *genericEnv,
Type type);

/// Map a contextual type to an interface type.
static Type mapTypeOutOfContext(const DeclContext *dc, Type type);

/// Map a contextual type to an interface type.
static Type mapTypeOutOfContext(ModuleDecl *M,
GenericParamList *genericParams,
GenericEnvironment *genericEnv,
Type type);

using SameTypeRequirement
Expand Down
129 changes: 50 additions & 79 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace swift {
enum class AccessSemantics : unsigned char;
class ApplyExpr;
class ArchetypeBuilder;
class GenericEnvironment;
class ArchetypeType;
class ASTContext;
class ASTPrinter;
Expand Down Expand Up @@ -1059,7 +1060,6 @@ class GenericParamList final :
unsigned NumParams;
SourceLoc WhereLoc;
MutableArrayRef<RequirementRepr> Requirements;
ArrayRef<ArchetypeType *> AllArchetypes;

GenericParamList *OuterParameters;

Expand Down Expand Up @@ -1109,28 +1109,6 @@ class GenericParamList final :
MutableArrayRef<RequirementRepr> Requirements,
SourceLoc RAngleLoc);

/// Create a new generic parameter list with the same parameters and
/// requirements as this one, but parented to a different outer parameter
/// list.
GenericParamList *cloneWithOuterParameters(const ASTContext &Context,
GenericParamList *Outer) {
auto clone = create(Context,
SourceLoc(),
getParams(),
SourceLoc(),
getRequirements(),
SourceLoc());
clone->setAllArchetypes(getAllArchetypes());
clone->setOuterParameters(Outer);
return clone;
}

/// Create an empty generic parameter list.
static GenericParamList *getEmpty(ASTContext &Context) {
// TODO: Could probably unique this in the AST context.
return create(Context, SourceLoc(), {}, SourceLoc(), {}, SourceLoc());
}

MutableArrayRef<GenericTypeParamDecl *> getParams() {
return {getTrailingObjects<GenericTypeParamDecl *>(), NumParams};
}
Expand All @@ -1148,12 +1126,6 @@ class GenericParamList final :
const_iterator begin() const { return getParams().begin(); }
const_iterator end() const { return getParams().end(); }

/// Get the total number of parameters, including those from parent generic
/// parameter lists.
unsigned totalSize() const {
return NumParams + (OuterParameters ? OuterParameters->totalSize() : 0);
}

/// \brief Retrieve the location of the 'where' keyword, or an invalid
/// location if 'where' was not present.
SourceLoc getWhereLoc() const { return WhereLoc; }
Expand Down Expand Up @@ -1199,24 +1171,7 @@ class GenericParamList final :
/// main part of a declaration's signature.
void addTrailingWhereClause(ASTContext &ctx, SourceLoc trailingWhereLoc,
ArrayRef<RequirementRepr> trailingRequirements);

/// \brief Retrieves the list containing all archetypes described by this
/// generic parameter clause.
///
/// In this list of archetypes, the primary archetypes come first followed by
/// any non-primary archetypes (i.e., those archetypes that encode associated
/// types of another archetype).
///
/// This does not include archetypes from the outer generic parameter list(s).
ArrayRef<ArchetypeType *> getAllArchetypes() const { return AllArchetypes; }

/// \brief Sets all archetypes *without* copying the source array.
void setAllArchetypes(ArrayRef<ArchetypeType *> AA) {
assert(AA.size() >= size()
&& "allArchetypes is smaller than number of generic params?!");
AllArchetypes = AA;
}

/// \brief Retrieve the outer generic parameter list, which provides the
/// generic parameters of the context in which this generic parameter list
/// exists.
Expand Down Expand Up @@ -1270,36 +1225,6 @@ class GenericParamList final :
return depth;
}

/// Derive a contextual type substitution map from a substitution array.
/// This is just like GenericSignature::getSubstitutionMap(), except
/// with contextual types instead of interface types.
void
getSubstitutionMap(ModuleDecl *mod,
GenericSignature *sig,
ArrayRef<Substitution> subs,
TypeSubstitutionMap &subsMap,
ArchetypeConformanceMap &conformanceMap) const;

/// Derive the all-archetypes list for the given list of generic
/// parameters.
static ArrayRef<ArchetypeType*>
deriveAllArchetypes(ArrayRef<GenericTypeParamDecl*> params,
SmallVectorImpl<ArchetypeType*> &archetypes);

void getForwardingSubstitutionMap(TypeSubstitutionMap &result) const;

ArrayRef<Substitution>
getForwardingSubstitutions(GenericSignature *sig) const;

/// Collect the nested archetypes of an archetype into the given
/// collection.
///
/// \param known - the set of archetypes already present in `all`
/// \param all - the output list of archetypes
static void addNestedArchetypes(ArchetypeType *archetype,
SmallPtrSetImpl<ArchetypeType*> &known,
SmallVectorImpl<ArchetypeType*> &all);

void print(raw_ostream &OS);
void dump();
};
Expand Down Expand Up @@ -1472,6 +1397,12 @@ class ExtensionDecl final : public Decl, public DeclContext,
/// the parsed representation, and not part of the module file.
GenericSignature *GenericSig = nullptr;

/// \brief The generic context of this extension.
///
/// This is the mapping between interface types and archetypes for the
/// generic parameters of this extension.
GenericEnvironment *GenericEnv = nullptr;

MutableArrayRef<TypeLoc> Inherited;

/// The trailing where clause.
Expand Down Expand Up @@ -1555,7 +1486,19 @@ class ExtensionDecl final : public Decl, public DeclContext,
GenericSignature *getGenericSignature() const { return GenericSig; }

/// Set the generic signature of this extension.
void setGenericSignature(GenericSignature *sig);
void setGenericSignature(GenericSignature *sig) {
assert(!GenericSig && "Already have generic signature");
GenericSig = sig;
}

/// Retrieve the generic context for this extension.
GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }

/// Set the generic context of this extension.
void setGenericEnvironment(GenericEnvironment *env) {
assert(!GenericEnv && "Already have generic context");
GenericEnv = env;
}

/// Retrieve the generic requirements.
ArrayRef<Requirement> getGenericRequirements() const;
Expand Down Expand Up @@ -2306,6 +2249,12 @@ class GenericTypeDecl : public TypeDecl, public DeclContext {
/// the parsed representation, and not part of the module file.
GenericSignature *GenericSig = nullptr;

/// \brief The generic context of this type.
///
/// This is the mapping between interface types and archetypes for the
/// generic parameters of this type.
GenericEnvironment *GenericEnv = nullptr;

/// \brief Whether or not the generic signature of the type declaration is
/// currently being validated.
// TODO: Merge into GenericSig bits.
Expand All @@ -2324,7 +2273,10 @@ class GenericTypeDecl : public TypeDecl, public DeclContext {
void setGenericParams(GenericParamList *params);

/// Set the generic signature of this type.
void setGenericSignature(GenericSignature *sig);
void setGenericSignature(GenericSignature *sig) {
assert(!GenericSig && "Already have generic signature");
GenericSig = sig;
}

/// Retrieve the innermost generic parameter types.
ArrayRef<GenericTypeParamType *> getInnermostGenericParamTypes() const {
Expand Down Expand Up @@ -2355,6 +2307,15 @@ class GenericTypeDecl : public TypeDecl, public DeclContext {
return ValidatingGenericSignature;
}

/// Retrieve the generic context for this type.
GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }

/// Set the generic context of this type.
void setGenericEnvironment(GenericEnvironment *env) {
assert(!this->GenericEnv && "already have generic context?");
this->GenericEnv = env;
}

// Resolve ambiguity due to multiple base classes.
using TypeDecl::getASTContext;
using DeclContext::operator new;
Expand Down Expand Up @@ -4573,6 +4534,7 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {

GenericParamList *GenericParams;
GenericSignature *GenericSig;
GenericEnvironment *GenericEnv;

CaptureInfo Captures;

Expand All @@ -4589,7 +4551,7 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
: ValueDecl(Kind, Parent, Name, NameLoc),
DeclContext(DeclContextKind::AbstractFunctionDecl, Parent),
Body(nullptr), GenericParams(nullptr), GenericSig(nullptr),
ThrowsLoc(ThrowsLoc) {
GenericEnv(nullptr), ThrowsLoc(ThrowsLoc) {
setBodyKind(BodyKind::None);
setGenericParams(GenericParams);
AbstractFunctionDeclBits.NumParameterLists = NumParameterLists;
Expand All @@ -4616,6 +4578,15 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
return GenericSig;
}

/// Retrieve the generic context for this function.
GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }

/// Set the generic context of this function.
void setGenericEnvironment(GenericEnvironment *GenericEnv) {
assert(!this->GenericEnv && "already have generic context?");
this->GenericEnv = GenericEnv;
}

// Expose our import as member status
bool isImportAsMember() const { return IAMStatus.isImportAsMember(); }
bool isImportAsInstanceMember() const { return IAMStatus.isInstance(); }
Expand Down
16 changes: 11 additions & 5 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace llvm {

namespace swift {
class AbstractFunctionDecl;
class GenericEnvironment;
class ASTContext;
class ASTWalker;
class CanType;
Expand Down Expand Up @@ -284,14 +285,19 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
/// type for non-type contexts.
Type getDeclaredInterfaceType() const;

/// \brief Retrieve the innermost generic parameters introduced by this
/// context or one of its parent contexts, or null if this context is not
/// directly dependent on any generic parameters.
/// \brief Retrieve the innermost generic parameters of this context or any
/// of its parents.
///
/// FIXME: Remove this
GenericParamList *getGenericParamsOfContext() const;

/// \brief Retrieve the interface generic type parameters and requirements
/// exposed by this context.
/// \brief Retrieve the innermost generic signature of this context or any
/// of its parents.
GenericSignature *getGenericSignatureOfContext() const;

/// \brief Retrieve the innermost archetypes of this context or any
/// of its parents.
GenericEnvironment *getGenericEnvironmentOfContext() const;

/// Returns this or the first local parent context, or nullptr if it is not
/// contained in one.
Expand Down
77 changes: 77 additions & 0 deletions include/swift/AST/GenericEnvironment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//===--- GenericEnvironment.h - Generic Environment AST ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the GenericEnvironment class.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_GENERIC_ENVIRONMENT_H
#define SWIFT_AST_GENERIC_ENVIRONMENT_H

#include "swift/AST/ProtocolConformance.h"

namespace swift {

class ASTContext;

/// Describes the mapping between archetypes and interface types for the
/// generic parameters of a DeclContext.
class GenericEnvironment final {
TypeSubstitutionMap ArchetypeToInterfaceMap;
TypeSubstitutionMap InterfaceToArchetypeMap;

public:
const TypeSubstitutionMap &getArchetypeToInterfaceMap() const {
return ArchetypeToInterfaceMap;
}

const TypeSubstitutionMap &getInterfaceToArchetypeMap() const {
return InterfaceToArchetypeMap;
}

explicit GenericEnvironment(TypeSubstitutionMap interfaceToArchetypeMap);

static GenericEnvironment *get(ASTContext &ctx,
TypeSubstitutionMap interfaceToArchetypeMap);

/// Make vanilla new/delete illegal.
void *operator new(size_t Bytes) = delete;
void operator delete(void *Data) = delete;

/// Only allow allocation of GenericEnvironments using the allocator
/// in ASTContext.
void *operator new(size_t bytes, const ASTContext &ctx);

/// Map a contextual type to an interface type.
Type mapTypeOutOfContext(ModuleDecl *M, Type type) const;

/// Map an interface type to a contextual type.
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;

/// Derive a contextual type substitution map from a substitution array.
/// This is just like GenericSignature::getSubstitutionMap(), except
/// with contextual types instead of interface types.
void
getSubstitutionMap(ModuleDecl *mod,
GenericSignature *sig,
ArrayRef<Substitution> subs,
TypeSubstitutionMap &subsMap,
ArchetypeConformanceMap &conformanceMap) const;

ArrayRef<Substitution>
getForwardingSubstitutions(ModuleDecl *M, GenericSignature *sig) const;
};

} // end namespace swift

#endif // SWIFT_AST_GENERIC_ENVIRONMENT_H

Loading