mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* spelling: accessor Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: accommodates Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: argument Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: availability Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: belongs Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: bookkeeping Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: building Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: clazz Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: clonable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: closure Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: concatenated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: conformance Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: context Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: conversion Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: correspondence Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: declarations Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: declared Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: defining Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: delayed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: dependency Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: deployed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: descendants Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: diagnose Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: diagnostic Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: equitable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: evaluation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: exclusivity Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: existence Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: existential Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: explicit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expressed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: foreign Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: function Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: identifier Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: implicit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: indices Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: information Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: instance Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: interchangeable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: interface Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: introduced Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: invalid Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: kind-in Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: least Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: library Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: location Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: namespace Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: necessary Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: not Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: number Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: obtains Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurs Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: opaque Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: parameter Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: precede Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: preceding Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: property Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: protocol Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: qualified Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: recognized Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: recursively Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: references Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: relaxing Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: represented Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: request Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requirement Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requirements Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: retrieve Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: satisfied Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: satisfy Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: scanner Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: siblings Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: simplified Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: something Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: source Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: specializations Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: specially Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: statement Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: stripped Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: structure Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: substitution Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transform Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transformed Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transitively Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transparent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: typecheck Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unknown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unlabeled Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unqualified Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: with Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: scanner Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
251 lines
9.0 KiB
C++
251 lines
9.0 KiB
C++
//===--- GenericEnvironment.h - Generic Environment AST ---------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://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/SubstitutionMap.h"
|
|
#include "swift/AST/GenericParamKey.h"
|
|
#include "swift/AST/GenericParamList.h"
|
|
#include "swift/AST/GenericSignature.h"
|
|
#include "swift/Basic/Compiler.h"
|
|
#include "swift/Basic/Debug.h"
|
|
#include "swift/Basic/UUID.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/TrailingObjects.h"
|
|
#include <utility>
|
|
|
|
namespace swift {
|
|
|
|
class ArchetypeType;
|
|
class ASTContext;
|
|
class GenericTypeParamType;
|
|
class OpaqueTypeDecl;
|
|
class OpenedArchetypeType;
|
|
class SILModule;
|
|
class SILType;
|
|
|
|
/// Query function suitable for use as a \c TypeSubstitutionFn that queries
|
|
/// the mapping of interface types to archetypes.
|
|
class QueryInterfaceTypeSubstitutions {
|
|
const GenericEnvironment *self;
|
|
|
|
public:
|
|
QueryInterfaceTypeSubstitutions(const GenericEnvironment *self)
|
|
: self(self) { }
|
|
|
|
Type operator()(SubstitutableType *type) const;
|
|
};
|
|
|
|
/// Extra data in a generic environment for an opened existential.
|
|
struct OpenedGenericEnvironmentData {
|
|
Type existential;
|
|
UUID uuid;
|
|
};
|
|
|
|
/// Describes the mapping between archetypes and interface types for the
|
|
/// generic parameters of a DeclContext.
|
|
///
|
|
/// The most frequently used method here is mapTypeIntoContext(), which
|
|
/// maps an interface type to a type written in terms of the generic
|
|
/// environment's archetypes; to go in the other direction, use
|
|
/// TypeBase::mapTypeOutOfContext().
|
|
///
|
|
class alignas(1 << DeclAlignInBits) GenericEnvironment final
|
|
: private llvm::TrailingObjects<
|
|
GenericEnvironment, OpaqueTypeDecl *, SubstitutionMap,
|
|
OpenedGenericEnvironmentData, Type> {
|
|
public:
|
|
enum class Kind {
|
|
/// A normal generic environment, determined only by its generic
|
|
/// signature.
|
|
Normal,
|
|
/// A generic environment describing an opened existential archetype.
|
|
OpenedExistential,
|
|
/// A generic environment describing an opaque type archetype.
|
|
Opaque,
|
|
};
|
|
|
|
class NestedTypeStorage;
|
|
|
|
private:
|
|
mutable llvm::PointerIntPair<GenericSignature, 2, Kind> SignatureAndKind{
|
|
GenericSignature(), Kind::Normal};
|
|
NestedTypeStorage *nestedTypeStorage = nullptr;
|
|
|
|
friend TrailingObjects;
|
|
friend OpaqueTypeArchetypeType;
|
|
|
|
size_t numTrailingObjects(OverloadToken<OpaqueTypeDecl *>) const;
|
|
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
|
|
size_t numTrailingObjects(OverloadToken<Type>) const;
|
|
size_t numTrailingObjects(OverloadToken<OpenedGenericEnvironmentData>) const;
|
|
|
|
/// Retrieve the array containing the context types associated with the
|
|
/// generic parameters, stored in parallel with the generic parameters of the
|
|
/// generic signature.
|
|
MutableArrayRef<Type> getContextTypes();
|
|
|
|
/// Retrieve the array containing the context types associated with the
|
|
/// generic parameters, stored in parallel with the generic parameters of the
|
|
/// generic signature.
|
|
ArrayRef<Type> getContextTypes() const;
|
|
|
|
/// Get the nested type storage, allocating it if required.
|
|
NestedTypeStorage &getOrCreateNestedTypeStorage();
|
|
|
|
explicit GenericEnvironment(GenericSignature signature);
|
|
explicit GenericEnvironment(
|
|
GenericSignature signature, Type existential, UUID uuid);
|
|
explicit GenericEnvironment(
|
|
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs);
|
|
|
|
friend ArchetypeType;
|
|
friend QueryInterfaceTypeSubstitutions;
|
|
|
|
Type getOrCreateArchetypeFromInterfaceType(Type depType);
|
|
|
|
/// Add a mapping of a generic parameter to a specific type (which may be
|
|
/// an archetype)
|
|
void addMapping(GenericParamKey key, Type contextType);
|
|
|
|
/// Retrieve the mapping for the given generic parameter, if present.
|
|
///
|
|
/// This is only useful when lazily populating a generic environment.
|
|
Optional<Type> getMappingIfPresent(GenericParamKey key) const;
|
|
|
|
public:
|
|
GenericSignature getGenericSignature() const {
|
|
return SignatureAndKind.getPointer();
|
|
}
|
|
|
|
Kind getKind() const { return SignatureAndKind.getInt(); }
|
|
|
|
TypeArrayView<GenericTypeParamType> getGenericParams() const;
|
|
|
|
/// Retrieve the existential type for an opened existential environment.
|
|
Type getOpenedExistentialType() const;
|
|
|
|
/// Retrieve the UUID for an opened existential environment.
|
|
UUID getOpenedExistentialUUID() const;
|
|
|
|
/// Retrieve the opaque type declaration for a generic environment describing
|
|
/// opaque types.
|
|
OpaqueTypeDecl *getOpaqueTypeDecl() const;
|
|
|
|
/// Retrieve the substitutions applied to an opaque type declaration to
|
|
/// create a generic environment.
|
|
SubstitutionMap getOpaqueSubstitutions() const;
|
|
|
|
/// Create a new, "incomplete" generic environment that will be populated
|
|
/// by calls to \c addMapping().
|
|
static
|
|
GenericEnvironment *getIncomplete(GenericSignature signature);
|
|
|
|
/// Create a new generic environment for an opened existential.
|
|
///
|
|
/// This function uses the provided parent signature to construct a new
|
|
/// signature suitable for use with an opened archetype. If you have an
|
|
/// existing generic signature from e.g. deserialization use
|
|
/// \c GenericEnvironment::forOpenedArchetypeSignature instead.
|
|
///
|
|
/// \param existential The subject existential type
|
|
/// \param parentSig The signature of the context where this existential type is being opened
|
|
/// \param uuid The unique identifier for this opened existential
|
|
static GenericEnvironment *
|
|
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);
|
|
|
|
/// Create a new generic environment for an opened existential.
|
|
///
|
|
/// It is unlikely you want to use this function.
|
|
/// Call \c GenericEnvironment::forOpenedExistential instead.
|
|
///
|
|
/// \param existential The subject existential type
|
|
/// \param signature The signature of the opened archetype
|
|
/// \param uuid The unique identifier for this opened existential
|
|
static GenericEnvironment *
|
|
forOpenedArchetypeSignature(Type existential,
|
|
GenericSignature signature, UUID uuid);
|
|
|
|
/// Create a new generic environment for an opaque type with the given set of
|
|
/// outer substitutions.
|
|
static GenericEnvironment *forOpaqueType(
|
|
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena);
|
|
|
|
/// Make vanilla new/delete illegal.
|
|
void *operator new(size_t Bytes) = delete;
|
|
void operator delete(void *Data) = delete;
|
|
|
|
/// Only allow placement new.
|
|
void *operator new(size_t Bytes, void *Mem) {
|
|
assert(Mem);
|
|
return Mem;
|
|
}
|
|
|
|
/// For an opaque archetype environment, apply the substitutions.
|
|
Type maybeApplyOpaqueTypeSubstitutions(Type type) const;
|
|
|
|
/// Compute the canonical interface type within this environment.
|
|
Type getCanonicalInterfaceType(Type interfaceType);
|
|
|
|
/// Map an interface type to a contextual type.
|
|
static Type mapTypeIntoContext(GenericEnvironment *genericEnv,
|
|
Type type);
|
|
|
|
/// Map an interface type to a contextual type.
|
|
Type mapTypeIntoContext(Type type) const;
|
|
|
|
/// Map an interface type to a contextual type.
|
|
Type mapTypeIntoContext(Type type,
|
|
LookupConformanceFn lookupConformance) const;
|
|
|
|
/// Map a generic parameter type to a contextual type.
|
|
Type mapTypeIntoContext(GenericTypeParamType *type) const;
|
|
|
|
/// Map the given SIL interface type to a contextual type.
|
|
///
|
|
/// This operation will also reabstract dependent types according to the
|
|
/// abstraction level of their associated type requirements.
|
|
SILType mapTypeIntoContext(SILModule &M, SILType type) const;
|
|
|
|
/// Map an interface type's protocol conformance into the corresponding
|
|
/// conformance for the contextual type.
|
|
static std::pair<Type, ProtocolConformanceRef>
|
|
mapConformanceRefIntoContext(GenericEnvironment *genericEnv,
|
|
Type conformingType,
|
|
ProtocolConformanceRef conformance);
|
|
|
|
/// Map an interface type's protocol conformance into the corresponding
|
|
/// conformance for the contextual type.
|
|
std::pair<Type, ProtocolConformanceRef>
|
|
mapConformanceRefIntoContext(Type conformingType,
|
|
ProtocolConformanceRef conformance) const;
|
|
|
|
/// Returns a substitution map that sends every generic parameter to its
|
|
/// corresponding archetype in this generic environment.
|
|
SubstitutionMap getForwardingSubstitutionMap() const;
|
|
|
|
void dump(raw_ostream &os) const;
|
|
|
|
SWIFT_DEBUG_DUMP;
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif // SWIFT_AST_GENERIC_ENVIRONMENT_H
|
|
|