Skip to content

Remove AllArchetypes list #4436

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

Closed
Closed
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
5 changes: 0 additions & 5 deletions include/swift/AST/ArchetypeBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,6 @@ 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);
Expand Down
34 changes: 0 additions & 34 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,6 @@ class GenericParamList final :
unsigned NumParams;
SourceLoc WhereLoc;
MutableArrayRef<RequirementRepr> Requirements;
ArrayRef<ArchetypeType *> AllArchetypes;

GenericParamList *OuterParameters;

Expand Down Expand Up @@ -1120,7 +1119,6 @@ class GenericParamList final :
SourceLoc(),
getRequirements(),
SourceLoc());
clone->setAllArchetypes(getAllArchetypes());
clone->setOuterParameters(Outer);
return clone;
}
Expand Down Expand Up @@ -1199,24 +1197,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 @@ -1280,26 +1261,11 @@ class GenericParamList final :
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
10 changes: 4 additions & 6 deletions include/swift/AST/GenericSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,6 @@ class GenericSignature final : public llvm::FoldingSetNode,
/// Return a range that iterates through first all of the generic parameters
/// of the signature, followed by all of their recursive member types exposed
/// through protocol requirements.
///
/// The member types are presented in the
/// same order as GenericParamList::getAllArchetypes would present for an
/// equivalent GenericParamList.
GenericSignatureWitnessIterator getAllDependentTypes() const {
return GenericSignatureWitnessIterator(getRequirements());
}
Expand All @@ -204,8 +200,10 @@ class GenericSignature final : public llvm::FoldingSetNode,
/// for mangling purposes.
///
/// TODO: This is what getCanonicalSignature() ought to do, but currently
/// cannot due to implementation dependencies on 'getAllDependentTypes'
/// order matching 'getAllArchetypes' order of a generic param list.
/// does not due to former implementation dependencies on
/// 'getAllDependentTypes' order matching 'getAllArchetypes' order of a
/// generic param list. Now that 'getAllArchetypes' is gone, we might
/// be able to move forward here.
CanGenericSignature getCanonicalManglingSignature(ModuleDecl &M) const;

/// Uniquing for the ASTContext.
Expand Down
5 changes: 2 additions & 3 deletions include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 261; // Last change: remove AllArchetypes indexing
const uint16_t VERSION_MINOR = 262; // Last change: remove AllArchetypes

using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
Expand Down Expand Up @@ -1082,8 +1082,7 @@ namespace decls_block {
>;

using GenericParamListLayout = BCRecordLayout<
GENERIC_PARAM_LIST,
BCArray<TypeIDField> // Archetypes
GENERIC_PARAM_LIST
// The actual parameters and requirements trail the record.
>;

Expand Down
195 changes: 0 additions & 195 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2084,195 +2084,6 @@ struct ASTNodeBase {};
verifyParsedBase(DD);
}

bool checkAllArchetypes(const GenericParamList *generics) {
ArrayRef<ArchetypeType*> storedArchetypes = generics->getAllArchetypes();

SmallVector<ArchetypeType*, 16> derivedBuffer;
ArrayRef<ArchetypeType*> derivedArchetypes =
GenericParamList::deriveAllArchetypes(generics->getParams(),
derivedBuffer);

return (storedArchetypes == derivedArchetypes);
}

/// Check that the generic requirements line up with the archetypes.
void checkGenericRequirements(Decl *decl,
DeclContext *dc,
GenericFunctionType *genericTy) {

PrettyStackTraceDecl debugStack("verifying generic requirements", decl);

// We need to have generic parameters here.
auto genericParams = dc->getGenericParamsOfContext();
if (!genericParams) {
Out << "Missing generic parameters\n";
decl->dump(Out);
abort();
}

// Verify that the list of all archetypes matches what we would
// derive from the generic params.
if (!checkAllArchetypes(genericParams)) {
Out << "Archetypes list in generic parameter list doesn't "
"match what would have been derived\n";
decl->dump(Out);
abort();
}

// Step through the list of requirements in the generic type.
auto requirements = genericTy->getRequirements();

// Skip over same-type requirements.
auto skipUnrepresentedRequirements = [&]() {
for (; !requirements.empty(); requirements = requirements.slice(1)) {
bool done = false;
switch (requirements.front().getKind()) {
case RequirementKind::Conformance:
// If the second type is a protocol type, we're done.
done = true;
break;

case RequirementKind::Superclass:
break;

case RequirementKind::SameType:
// Skip the next same-type constraint.
continue;

case RequirementKind::WitnessMarker:
done = true;
break;
}

if (done)
break;
}
};
skipUnrepresentedRequirements();

// Collect all of the generic parameter lists.
SmallVector<GenericParamList *, 4> allGenericParamLists;
for (auto gpList = genericParams; gpList;
gpList = gpList->getOuterParameters()) {
allGenericParamLists.push_back(gpList);
}
std::reverse(allGenericParamLists.begin(), allGenericParamLists.end());

// Helpers that diagnose failures when generic requirements mismatch.
bool failed = false;
auto noteFailure =[&]() {
if (failed)
return;

Out << "Generic requirements don't match all archetypes\n";
decl->dump(Out);

Out << "\nGeneric type: " << genericTy->getString() << "\n";
Out << "Expected requirements: ";
bool first = true;
for (auto gpList : allGenericParamLists) {
for (auto archetype : gpList->getAllArchetypes()) {
for (auto proto : archetype->getConformsTo()) {
if (first)
first = false;
else
Out << ", ";

Out << archetype->getString() << " : "
<< proto->getDeclaredType()->getString();
}
}
}
Out << "\n";

failed = true;
};

// Walk through all of the archetypes in the generic parameter lists,
// matching up their conformance requirements with those in the
for (auto gpList : allGenericParamLists) {
for (auto archetype : gpList->getAllArchetypes()) {
// Make sure we have the value witness marker.
if (requirements.empty()) {
noteFailure();
Out << "Ran out of requirements before we ran out of archetypes\n";
break;
}

if (requirements.front().getKind()
== RequirementKind::WitnessMarker) {
auto type = ArchetypeBuilder::mapTypeIntoContext(
dc,
requirements.front().getFirstType());
if (type->isEqual(archetype)) {
requirements = requirements.slice(1);
skipUnrepresentedRequirements();
} else {
noteFailure();
Out << "Value witness marker for " << type->getString()
<< " does not match expected " << archetype->getString()
<< "\n";
}
} else {
noteFailure();
Out << "Missing value witness marker for "
<< archetype->getString() << "\n";
}

for (auto proto : archetype->getConformsTo()) {
// If there are no requirements left, we're missing requirements.
if (requirements.empty()) {
noteFailure();
Out << "No requirement for " << archetype->getString()
<< " : " << proto->getDeclaredType()->getString() << "\n";
continue;
}

auto firstReqType = ArchetypeBuilder::mapTypeIntoContext(
dc,
requirements.front().getFirstType());
auto secondReqType = ArchetypeBuilder::mapTypeIntoContext(
dc,
requirements.front().getSecondType());

// If the requirements match up, move on to the next requirement.
if (firstReqType->isEqual(archetype) &&
secondReqType->isEqual(proto->getDeclaredType())) {
requirements = requirements.slice(1);
skipUnrepresentedRequirements();
continue;
}

noteFailure();

// If the requirements don't match up, complain.
if (!firstReqType->isEqual(archetype)) {
Out << "Mapped archetype " << firstReqType->getString()
<< " does not match expected " << archetype->getString()
<< "\n";
continue;
}

Out << "Mapped conformance " << secondReqType->getString()
<< " does not match expected "
<< proto->getDeclaredType()->getString() << "\n";
}
}
}

if (!requirements.empty()) {
noteFailure();
Out << "Extra requirement "
<< requirements.front().getFirstType()->getString()
<< " : "
<< requirements.front().getSecondType()->getString()
<< "\n";
}

if (failed)
abort();
}

void verifyChecked(AbstractFunctionDecl *AFD) {
PrettyStackTraceDecl debugStack("verifying AbstractFunctionDecl", AFD);

Expand Down Expand Up @@ -2347,12 +2158,6 @@ struct ASTNodeBase {};
abort();
}

// If the interface type is generic, make sure its requirements
// line up with the archetypes.
if (auto genericTy = interfaceTy->getAs<GenericFunctionType>()) {
checkGenericRequirements(AFD, AFD, genericTy);
}

// Throwing @objc methods must have a foreign error convention.
if (AFD->isObjC() &&
static_cast<bool>(AFD->getForeignErrorConvention())
Expand Down
40 changes: 0 additions & 40 deletions lib/AST/ArchetypeBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,6 @@ struct ArchetypeBuilder::Implementation {
/// archetypes.
llvm::MapVector<GenericTypeParamKey, PotentialArchetype*> PotentialArchetypes;

/// A vector containing all of the archetypes, expanded out.
/// FIXME: This notion should go away, because it's impossible to expand
/// out "all" archetypes
SmallVector<ArchetypeType *, 4> AllArchetypes;

/// A vector containing the same-type requirements introduced into the
/// system.
SmallVector<SameTypeRequirement, 4> SameTypeRequirements;
Expand Down Expand Up @@ -1761,41 +1756,6 @@ ArchetypeBuilder::getArchetype(GenericTypeParamDecl *GenericParam) {
return known->second->getType(*this).getAsArchetype();
}

ArrayRef<ArchetypeType *> ArchetypeBuilder::getAllArchetypes() {
// This should be kept in sync with GenericParamList::deriveAllArchetypes().
if (Impl->AllArchetypes.empty()) {
// Collect the primary archetypes first.
unsigned depth = Impl->PotentialArchetypes.back().first.Depth;
llvm::SmallPtrSet<ArchetypeType *, 8> KnownArchetypes;
for (const auto &Entry : Impl->PotentialArchetypes) {
// Skip outer potential archetypes.
if (Entry.first.Depth < depth)
continue;

PotentialArchetype *PA = Entry.second;
auto Archetype = PA->getType(*this).castToArchetype();
if (KnownArchetypes.insert(Archetype).second)
Impl->AllArchetypes.push_back(Archetype);
}

// Collect all of the remaining archetypes.
for (const auto &Entry : Impl->PotentialArchetypes) {
// Skip outer potential archetypes.
if (Entry.first.Depth < depth)
continue;

PotentialArchetype *PA = Entry.second;
if (!PA->isConcreteType() && !PA->getTypeAliasDecl()) {
auto Archetype = PA->getType(*this).castToArchetype();
GenericParamList::addNestedArchetypes(Archetype, KnownArchetypes,
Impl->AllArchetypes);
}
}
}

return Impl->AllArchetypes;
}

ArrayRef<ArchetypeBuilder::SameTypeRequirement>
ArchetypeBuilder::getSameTypeRequirements() const {
return Impl->SameTypeRequirements;
Expand Down
Loading