Skip to content

Small generics cleanups #4758

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 8 commits into from
Sep 14, 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
4 changes: 0 additions & 4 deletions include/swift/AST/ArchetypeBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,6 @@ class ArchetypeBuilder {
GenericEnvironment *genericEnv,
Type type);

using SameTypeRequirement
= std::pair<PotentialArchetype *,
PointerUnion<Type, PotentialArchetype*>>;

/// \brief Dump all of the requirements, both specified and inferred.
LLVM_ATTRIBUTE_DEPRECATED(
void dump(),
Expand Down
38 changes: 26 additions & 12 deletions include/swift/AST/GenericSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,27 @@ class SubstitutionMap;
/// signature and their dependent members.
class GenericSignatureWitnessIterator {
ArrayRef<Requirement> p;


void checkValid() const {
assert(!p.empty() &&
p.front().getKind() == RequirementKind::WitnessMarker);
}

bool shouldSkip() const {
return (!p.empty() &&
p.front().getKind() != RequirementKind::WitnessMarker);
}

public:
GenericSignatureWitnessIterator() = default;
GenericSignatureWitnessIterator(ArrayRef<Requirement> p)
: p(p)
{
assert(p.empty() || p.front().getKind() == RequirementKind::WitnessMarker);
GenericSignatureWitnessIterator(ArrayRef<Requirement> requirements)
: p(requirements) {
while (shouldSkip()) { p = p.slice(1); }
}

GenericSignatureWitnessIterator &operator++() {
do {
p = p.slice(1);
} while (!p.empty()
&& p.front().getKind() != RequirementKind::WitnessMarker);
checkValid();
do { p = p.slice(1); } while (shouldSkip());
return *this;
}

Expand All @@ -59,12 +66,12 @@ class GenericSignatureWitnessIterator {
}

Type operator*() const {
assert(p.front().getKind() == RequirementKind::WitnessMarker);
checkValid();
return p.front().getFirstType();
}

Type operator->() const {
assert(p.front().getKind() == RequirementKind::WitnessMarker);
checkValid();
return p.front().getFirstType();
}

Expand Down Expand Up @@ -162,7 +169,14 @@ class GenericSignature final : public llvm::FoldingSetNode,
return const_cast<GenericSignature *>(this)->getRequirementsBuffer();
}

// Only allow allocation by doing a placement new.
/// Check if the generic signature makes all generic parameters
/// concrete.
bool areAllParamsConcrete() const {
auto iter = getAllDependentTypes();
return iter.begin() == iter.end();
}

/// Only allow allocation by doing a placement new.
void *operator new(size_t Bytes, void *Mem) {
assert(Mem);
return Mem;
Expand Down
9 changes: 0 additions & 9 deletions include/swift/AST/Substitution.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ class Substitution {

/// Apply a substitution to this substitution's replacement type and
/// conformances.
///
/// Our replacement type must be written in terms of the context
/// archetypes of 'env', which in turn must be derived from the
/// generic requirements of 'sig'.
Substitution subst(ModuleDecl *module,
GenericSignature *sig,
GenericEnvironment *env,
ArrayRef<Substitution> subs) const;

Substitution subst(ModuleDecl *module,
const SubstitutionMap &subMap) const;

Expand Down
11 changes: 0 additions & 11 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -3757,17 +3757,6 @@ class ArchetypeType final : public SubstitutableType,
return AssocTypeOrProto.dyn_cast<ProtocolDecl *>();
}

/// True if this is the 'Self' parameter of a protocol or an associated type
/// of 'Self'.
bool isSelfDerived() {
ArchetypeType *t = getPrimary();

if (t && t->getSelfProtocol())
return true;

return false;
}

/// getConformsTo - Retrieve the set of protocols to which this substitutable
/// type shall conform.
ArrayRef<ProtocolDecl *> getConformsTo() const { return ConformsTo; }
Expand Down
36 changes: 18 additions & 18 deletions include/swift/SIL/TypeSubstCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef SWIFT_SIL_TYPESUBSTCLONER_H
#define SWIFT_SIL_TYPESUBSTCLONER_H

#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Type.h"
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/DynamicCasts.h"
Expand All @@ -38,6 +39,13 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
llvm_unreachable("Clients need to explicitly call a base class impl!");
}

void computeSubsMap() {
if (auto *env = Original.getGenericEnvironment()) {
auto sig = Original.getLoweredFunctionType()->getGenericSignature();
SubsMap = env->getSubstitutionMap(SwiftMod, sig, ApplySubs);
}
}

public:
using SILClonerWithScopes<ImplClass>::asImpl;
using SILClonerWithScopes<ImplClass>::getBuilder;
Expand All @@ -55,28 +63,28 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {

TypeSubstCloner(SILFunction &To,
SILFunction &From,
const SubstitutionMap &ContextSubs,
ArrayRef<Substitution> ApplySubs,
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
bool Inlining = false)
: SILClonerWithScopes<ImplClass>(To, OpenedArchetypesTracker, Inlining),
SwiftMod(From.getModule().getSwiftModule()),
SubsMap(ContextSubs),
Original(From),
ApplySubs(ApplySubs),
Inlining(Inlining) { }
Inlining(Inlining) {
computeSubsMap();
}

TypeSubstCloner(SILFunction &To,
SILFunction &From,
const SubstitutionMap &ContextSubs,
ArrayRef<Substitution> ApplySubs,
bool Inlining = false)
: SILClonerWithScopes<ImplClass>(To, Inlining),
SwiftMod(From.getModule().getSwiftModule()),
SubsMap(ContextSubs),
Original(From),
ApplySubs(ApplySubs),
Inlining(Inlining) { }
Inlining(Inlining) {
computeSubsMap();
}


protected:
Expand All @@ -90,11 +98,8 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
}

Substitution remapSubstitution(Substitution sub) {
if (!ApplySubs.empty()) {
auto sig = Original.getLoweredFunctionType()->getGenericSignature();
auto *env = Original.getGenericEnvironment();
sub = sub.subst(SwiftMod, sig, env, ApplySubs);
}
sub = sub.subst(SwiftMod, SubsMap);

// Remap opened archetypes into the cloned context.
return Substitution(getASTTypeInClonedContext(sub.getReplacement()
->getCanonicalType()),
Expand Down Expand Up @@ -208,12 +213,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
void visitWitnessMethodInst(WitnessMethodInst *Inst) {
// Specialize the Self substitution of the witness_method.
auto sub = Inst->getSelfSubstitution();
if (!ApplySubs.empty()) {
auto sig = Original.getLoweredFunctionType()->getGenericSignature();
auto *env = Original.getGenericEnvironment();
sub = sub.subst(Inst->getModule().getSwiftModule(),
sig, env, ApplySubs);
}
sub = sub.subst(Inst->getModule().getSwiftModule(), SubsMap);

assert(sub.getConformances().size() == 1 &&
"didn't get conformance from substitution?!");
Expand Down Expand Up @@ -289,7 +289,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
/// The Swift module that the cloned function belongs to.
Module *SwiftMod;
/// The substitutions list for the specialization.
const SubstitutionMap &SubsMap;
SubstitutionMap SubsMap;
/// The original function to specialize.
SILFunction &Original;
/// The substitutions used at the call site.
Expand Down
6 changes: 2 additions & 4 deletions include/swift/SILOptimizer/Utils/GenericCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ class GenericCloner : public TypeSubstCloner<GenericCloner> {
GenericCloner(SILFunction *F,
IsFragile_t Fragile,
const ReabstractionInfo &ReInfo,
SubstitutionMap &ContextSubs,
ArrayRef<Substitution> ParamSubs,
StringRef NewName,
CloneCollector::CallbackType Callback)
: TypeSubstCloner(*initCloned(F, Fragile, ReInfo, NewName), *F, ContextSubs,
: TypeSubstCloner(*initCloned(F, Fragile, ReInfo, NewName), *F,
ParamSubs), ReInfo(ReInfo), Callback(Callback) {
assert(F->getDebugScope()->Parent != getCloned()->getDebugScope()->Parent);
}
Expand All @@ -56,12 +55,11 @@ class GenericCloner : public TypeSubstCloner<GenericCloner> {
cloneFunction(SILFunction *F,
IsFragile_t Fragile,
const ReabstractionInfo &ReInfo,
SubstitutionMap &ContextSubs,
ArrayRef<Substitution> ParamSubs,
StringRef NewName,
CloneCollector::CallbackType Callback =nullptr) {
// Clone and specialize the function.
GenericCloner SC(F, Fragile, ReInfo, ContextSubs, ParamSubs,
GenericCloner SC(F, Fragile, ReInfo, ParamSubs,
NewName, Callback);
SC.populateCloned();
SC.cleanUp(SC.getCloned());
Expand Down
4 changes: 2 additions & 2 deletions include/swift/SILOptimizer/Utils/SILInliner.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ class SILInliner : public TypeSubstCloner<SILInliner> {
};

SILInliner(SILFunction &To, SILFunction &From, InlineKind IKind,
SubstitutionMap &ContextSubs, ArrayRef<Substitution> ApplySubs,
ArrayRef<Substitution> ApplySubs,
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
CloneCollector::CallbackType Callback = nullptr)
: TypeSubstCloner<SILInliner>(To, From, ContextSubs, ApplySubs,
: TypeSubstCloner<SILInliner>(To, From, ApplySubs,
OpenedArchetypesTracker, true),
IKind(IKind), CalleeEntryBB(nullptr), CallSiteScope(nullptr),
Callback(Callback) {
Expand Down
7 changes: 7 additions & 0 deletions lib/AST/ASTScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,13 @@ SourceRange ASTScope::getSourceRangeImpl() const {
return cast<NominalTypeDecl>(iterableDeclContext)->getBraces();

case ASTScopeKind::GenericParams:
// A protocol's generic parameter list is not written in source, and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, thanks!

// is visible from the start of the body.
if (auto *protoDecl = dyn_cast<ProtocolDecl>(genericParams.decl)) {
return SourceRange(protoDecl->getBraces().Start,
protoDecl->getEndLoc());
}

// Explicitly-written generic parameters are in scope following their
// definition.
return SourceRange(genericParams.params->getParams()[genericParams.index]
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2185,7 +2185,7 @@ GenericTypeDecl::GenericTypeDecl(DeclKind K, DeclContext *DC,


void GenericTypeDecl::setGenericParams(GenericParamList *params) {
// Set the specified generic parameters onto this type alias, setting
// Set the specified generic parameters onto this type declaration, setting
// the parameters' context along the way.
GenericParams = params;
if (params)
Expand Down
9 changes: 0 additions & 9 deletions lib/AST/Substitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@ Substitution::Substitution(Type Replacement,
&& "cannot substitute with a non-materializable type");
}

Substitution Substitution::subst(Module *module,
GenericSignature *sig,
GenericEnvironment *env,
ArrayRef<Substitution> subs) const {
assert(sig && env);
auto subMap = env->getSubstitutionMap(module, sig, subs);
return subst(module, subMap);
}

Substitution Substitution::subst(Module *module,
const SubstitutionMap &subMap) const {
// Substitute the replacement.
Expand Down
11 changes: 1 addition & 10 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,19 +2816,10 @@ static Type getMemberForBaseType(ConformanceSource conformances,
if (archetypeParent->hasNestedType(name))
return archetypeParent->getNestedTypeValue(name);

if (auto parent = archetypeParent->getParent()) {
// If the archetype doesn't have the requested type and the parent is not
// self derived, error out
return parent->isSelfDerived() ? parent->getNestedTypeValue(name)
: ErrorType::get(substBase->getASTContext());
}

// If looking for an associated type and the archetype is constrained to a
// class, continue to the default associated type lookup
if (!assocType || !archetypeParent->getSuperclass()) {
// else just error out
if (!assocType || !archetypeParent->getSuperclass())
return ErrorType::get(substBase->getASTContext());
}
}

// If the parent is a type variable, retrieve its member type
Expand Down
Loading