Skip to content

[GSB] Centralize, clean up, and cache nested type name lookup #12097

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 9 commits into from
Sep 25, 2017
49 changes: 35 additions & 14 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ class GenericSignatureBuilder {
/// a superclass requirement.
bool isConformanceSatisfiedBySuperclass(ProtocolDecl *proto) const;

/// Lookup a nested type with the given name within this equivalence
/// class.
///
/// \param otherConcreteTypes If non-null, will be filled in the all of the
/// concrete types we found (other than the result) with the same name.
TypeDecl *lookupNestedType(
Identifier name,
SmallVectorImpl<TypeDecl *> *otherConcreteTypes = nullptr);

/// Dump a debugging representation of this equivalence class.
void dump(llvm::raw_ostream &out) const;

Expand All @@ -232,6 +241,17 @@ class GenericSignatureBuilder {
/// anchor was cached.
unsigned numMembers;
} archetypeAnchorCache;

/// Describes a cached nested type.
struct CachedNestedType {
unsigned numConformancesPresent;
CanType superclassPresent;
llvm::TinyPtrVector<TypeDecl *> types;
};

/// Cached nested-type information, which contains the best declaration
/// for a given name.
llvm::SmallDenseMap<Identifier, CachedNestedType> nestedTypeNameCache;
};

friend class RequirementSource;
Expand Down Expand Up @@ -522,9 +542,6 @@ class GenericSignatureBuilder {
/// \brief Add all of a generic signature's parameters and requirements.
void addGenericSignature(GenericSignature *sig);

/// \brief Build the generic signature.
GenericSignature *getGenericSignature();

/// Infer requirements from the given type, recursively.
///
/// This routine infers requirements from a type that occurs within the
Expand Down Expand Up @@ -558,11 +575,13 @@ class GenericSignatureBuilder {
/// \brief Finalize the set of requirements and compute the generic
/// signature.
///
/// After this point, one cannot introduce new requirements.
/// After this point, one cannot introduce new requirements, and the
/// generic signature builder no longer has valid state.
GenericSignature *computeGenericSignature(
SourceLoc loc,
bool allowConcreteGenericParams = false);
bool allowConcreteGenericParams = false) &&;

private:
/// Finalize the set of requirements, performing any remaining checking
/// required before generating archetypes.
///
Expand All @@ -572,6 +591,7 @@ class GenericSignatureBuilder {
ArrayRef<GenericTypeParamType *> genericParams,
bool allowConcreteGenericParams=false);

public:
/// Process any delayed requirements that can be handled now.
void processDelayedRequirements();

Expand Down Expand Up @@ -1490,6 +1510,12 @@ class GenericSignatureBuilder::PotentialArchetype {
return parentOrBuilder.dyn_cast<PotentialArchetype *>();
}

/// Retrieve the type declaration to which this nested type was resolved.
TypeDecl *getResolvedType() const {
assert(getParent() && "Not an associated type");
return identifier.assocTypeOrConcrete;
}

/// Retrieve the associated type to which this potential archetype
/// has been resolved.
AssociatedTypeDecl *getResolvedAssociatedType() const {
Expand Down Expand Up @@ -1632,13 +1658,8 @@ class GenericSignatureBuilder::PotentialArchetype {
ArchetypeResolutionKind kind,
GenericSignatureBuilder &builder);

/// \brief Retrieve (or create) a nested type with a known associated type.
PotentialArchetype *getNestedType(AssociatedTypeDecl *assocType,
GenericSignatureBuilder &builder);

/// \brief Retrieve (or create) a nested type with a known concrete type
/// declaration.
PotentialArchetype *getNestedType(TypeDecl *concreteDecl,
/// \brief Retrieve (or create) a nested type with a known type.
PotentialArchetype *getNestedType(TypeDecl *type,
GenericSignatureBuilder &builder);

/// \brief Retrieve (or create) a nested type that is the current best
Expand All @@ -1658,8 +1679,8 @@ class GenericSignatureBuilder::PotentialArchetype {
/// type or typealias of the given protocol, unless the \c kind implies that
/// a potential archetype should not be created if it's missing.
PotentialArchetype *updateNestedTypeForConformance(
PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
ArchetypeResolutionKind kind);
TypeDecl *type,
ArchetypeResolutionKind kind);

/// Update the named nested type when we know this type conforms to the given
/// protocol.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4591,7 +4591,7 @@ CanGenericSignature ASTContext::getExistentialSignature(CanType existential,
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
builder.addRequirement(requirement, source, nullptr);

CanGenericSignature genericSig(builder.computeGenericSignature(SourceLoc()));
CanGenericSignature genericSig(std::move(builder).computeGenericSignature(SourceLoc()));

auto result = Impl.ExistentialSignatures.insert(
std::make_pair(existential, genericSig));
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ namespace {
Builder.addGenericParameter(gp);
}

auto GenericSig = Builder.computeGenericSignature(SourceLoc());
auto GenericSig =
std::move(Builder).computeGenericSignature(SourceLoc());
GenericEnv = GenericSig->createGenericEnvironment(*ctx.TheBuiltinModule);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3419,7 +3419,8 @@ void ProtocolDecl::computeRequirementSignature() {
nullptr);

// Compute and record the signature.
auto requirementSig = builder.computeGenericSignature(SourceLoc());
auto requirementSig =
std::move(builder).computeGenericSignature(SourceLoc());
RequirementSignature = requirementSig->getRequirements().data();
assert(RequirementSignature != nullptr);
NumRequirementsInSignature = requirementSig->getRequirements().size();
Expand Down
Loading