mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -49,7 +49,7 @@ thunk helpers" sometimes seen in Swift backtraces come from.)
|
|||||||
|
|
||||||
Broadly, an "access path" is a list of "accesses" which must be chained together
|
Broadly, an "access path" is a list of "accesses" which must be chained together
|
||||||
to compute some output from an input. For instance, the generics system has a
|
to compute some output from an input. For instance, the generics system has a
|
||||||
type called a `ConformanceAccessPath` which explains how to, for example,
|
type called a `ConformancePath` which explains how to, for example,
|
||||||
walk from `T: Collection` to `T: Sequence` to `T.Iterator: IteratorProtocol`.
|
walk from `T: Collection` to `T: Sequence` to `T.Iterator: IteratorProtocol`.
|
||||||
There are several different kinds of "access path" in different parts of the compiler,
|
There are several different kinds of "access path" in different parts of the compiler,
|
||||||
but they all follow this basic theme.
|
but they all follow this basic theme.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class NamedDecl;
|
|||||||
namespace swift {
|
namespace swift {
|
||||||
|
|
||||||
class AbstractClosureExpr;
|
class AbstractClosureExpr;
|
||||||
class ConformanceAccessPath;
|
class ConformancePath;
|
||||||
class RootProtocolConformance;
|
class RootProtocolConformance;
|
||||||
|
|
||||||
namespace Mangle {
|
namespace Mangle {
|
||||||
@@ -560,7 +560,7 @@ protected:
|
|||||||
void appendConcreteProtocolConformance(
|
void appendConcreteProtocolConformance(
|
||||||
const ProtocolConformance *conformance,
|
const ProtocolConformance *conformance,
|
||||||
GenericSignature sig);
|
GenericSignature sig);
|
||||||
void appendDependentProtocolConformance(const ConformanceAccessPath &path,
|
void appendDependentProtocolConformance(const ConformancePath &path,
|
||||||
GenericSignature sig);
|
GenericSignature sig);
|
||||||
void appendOpParamForLayoutConstraint(LayoutConstraint Layout);
|
void appendOpParamForLayoutConstraint(LayoutConstraint Layout);
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace rewriting {
|
|||||||
/// \c Sequence conformance of \c C (because \c Collection inherits
|
/// \c Sequence conformance of \c C (because \c Collection inherits
|
||||||
/// \c Sequence). Finally, it extracts the conformance of the associated type
|
/// \c Sequence). Finally, it extracts the conformance of the associated type
|
||||||
/// \c Iterator to \c IteratorProtocol from the \c Sequence protocol.
|
/// \c Iterator to \c IteratorProtocol from the \c Sequence protocol.
|
||||||
class ConformanceAccessPath {
|
class ConformancePath {
|
||||||
public:
|
public:
|
||||||
/// An entry in the conformance access path, which is described by the
|
/// An entry in the conformance access path, which is described by the
|
||||||
/// dependent type on which the conformance is stated as the protocol to
|
/// dependent type on which the conformance is stated as the protocol to
|
||||||
@@ -80,7 +80,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ArrayRef<Entry> path;
|
ArrayRef<Entry> path;
|
||||||
|
|
||||||
ConformanceAccessPath(ArrayRef<Entry> path) : path(path) {}
|
ConformancePath(ArrayRef<Entry> path) : path(path) {}
|
||||||
|
|
||||||
friend class GenericSignatureImpl;
|
friend class GenericSignatureImpl;
|
||||||
friend class rewriting::RequirementMachine;
|
friend class rewriting::RequirementMachine;
|
||||||
@@ -398,20 +398,20 @@ public:
|
|||||||
/// signature.
|
/// signature.
|
||||||
bool isValidTypeParameter(Type type) const;
|
bool isValidTypeParameter(Type type) const;
|
||||||
|
|
||||||
/// Retrieve the conformance access path used to extract the conformance of
|
/// Retrieve the conformance path used to extract the conformance of
|
||||||
/// interface \c type to the given \c protocol.
|
/// interface \c type to the given \c protocol.
|
||||||
///
|
///
|
||||||
/// \param type The interface type whose conformance access path is to be
|
/// \param type The type parameter whose conformance path is to be
|
||||||
/// queried.
|
/// queried.
|
||||||
/// \param protocol A protocol to which \c type conforms.
|
/// \param protocol A protocol to which \c type conforms.
|
||||||
///
|
///
|
||||||
/// \returns the conformance access path that starts at a requirement of
|
/// \returns the conformance path that starts at a requirement of
|
||||||
/// this generic signature and ends at the conformance that makes \c type
|
/// this generic signature and ends at the conformance that makes \c type
|
||||||
/// conform to \c protocol.
|
/// conform to \c protocol.
|
||||||
///
|
///
|
||||||
/// \seealso ConformanceAccessPath
|
/// \seealso ConformancePath
|
||||||
ConformanceAccessPath getConformanceAccessPath(Type type,
|
ConformancePath getConformancePath(Type type,
|
||||||
ProtocolDecl *protocol) const;
|
ProtocolDecl *protocol) const;
|
||||||
|
|
||||||
/// Lookup a nested type with the given name within this type parameter.
|
/// Lookup a nested type with the given name within this type parameter.
|
||||||
TypeDecl *lookupNestedType(Type type, Identifier name) const;
|
TypeDecl *lookupNestedType(Type type, Identifier name) const;
|
||||||
|
|||||||
@@ -230,16 +230,8 @@ FRONTEND_STATISTIC(Sema, NumRequirementMachineCompletionSteps)
|
|||||||
/// Number of new rules added by concrete term unification.
|
/// Number of new rules added by concrete term unification.
|
||||||
FRONTEND_STATISTIC(Sema, NumRequirementMachineUnifiedConcreteTerms)
|
FRONTEND_STATISTIC(Sema, NumRequirementMachineUnifiedConcreteTerms)
|
||||||
|
|
||||||
/// Number of generic signature builders constructed. Rough proxy for
|
/// Number of conformance paths we had to compute.
|
||||||
/// amount of work the GSB does analyzing type signatures.
|
FRONTEND_STATISTIC(Sema, NumConformancePathsRecorded)
|
||||||
FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
|
|
||||||
|
|
||||||
/// Number of steps in the GSB's redundant requirements algorithm, which is in
|
|
||||||
/// the worst-case exponential.
|
|
||||||
FRONTEND_STATISTIC(Sema, NumRedundantRequirementSteps)
|
|
||||||
|
|
||||||
/// Number of conformance access paths we had to compute.
|
|
||||||
FRONTEND_STATISTIC(Sema, NumConformanceAccessPathsRecorded)
|
|
||||||
|
|
||||||
/// Number of lazy requirement signatures registered.
|
/// Number of lazy requirement signatures registered.
|
||||||
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)
|
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)
|
||||||
|
|||||||
@@ -3357,9 +3357,9 @@ void ASTMangler::appendProtocolConformanceRef(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the index of the conformance requirement indicated by the
|
/// Retrieve the index of the conformance requirement indicated by the
|
||||||
/// conformance access path entry within the given set of requirements.
|
/// conformance path entry within the given set of requirements.
|
||||||
static unsigned conformanceRequirementIndex(
|
static unsigned conformanceRequirementIndex(
|
||||||
const ConformanceAccessPath::Entry &entry,
|
const ConformancePath::Entry &entry,
|
||||||
ArrayRef<Requirement> requirements) {
|
ArrayRef<Requirement> requirements) {
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
for (const auto &req : requirements) {
|
for (const auto &req : requirements) {
|
||||||
@@ -3377,7 +3377,7 @@ static unsigned conformanceRequirementIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ASTMangler::appendDependentProtocolConformance(
|
void ASTMangler::appendDependentProtocolConformance(
|
||||||
const ConformanceAccessPath &path,
|
const ConformancePath &path,
|
||||||
GenericSignature sig) {
|
GenericSignature sig) {
|
||||||
ProtocolDecl *currentProtocol = nullptr;
|
ProtocolDecl *currentProtocol = nullptr;
|
||||||
for (const auto &entry : path) {
|
for (const auto &entry : path) {
|
||||||
@@ -3441,19 +3441,19 @@ void ASTMangler::appendAnyProtocolConformance(
|
|||||||
|
|
||||||
if (conformingType->isTypeParameter()) {
|
if (conformingType->isTypeParameter()) {
|
||||||
assert(genericSig && "Need a generic signature to resolve conformance");
|
assert(genericSig && "Need a generic signature to resolve conformance");
|
||||||
auto path = genericSig->getConformanceAccessPath(conformingType,
|
auto path = genericSig->getConformancePath(conformingType,
|
||||||
conformance.getAbstract());
|
conformance.getAbstract());
|
||||||
appendDependentProtocolConformance(path, genericSig);
|
appendDependentProtocolConformance(path, genericSig);
|
||||||
} else if (auto opaqueType = conformingType->getAs<OpaqueTypeArchetypeType>()) {
|
} else if (auto opaqueType = conformingType->getAs<OpaqueTypeArchetypeType>()) {
|
||||||
GenericSignature opaqueSignature =
|
GenericSignature opaqueSignature =
|
||||||
opaqueType->getDecl()->getOpaqueInterfaceGenericSignature();
|
opaqueType->getDecl()->getOpaqueInterfaceGenericSignature();
|
||||||
ConformanceAccessPath conformanceAccessPath =
|
ConformancePath conformancePath =
|
||||||
opaqueSignature->getConformanceAccessPath(
|
opaqueSignature->getConformancePath(
|
||||||
opaqueType->getInterfaceType(),
|
opaqueType->getInterfaceType(),
|
||||||
conformance.getAbstract());
|
conformance.getAbstract());
|
||||||
|
|
||||||
// Append the conformance access path with the signature of the opaque type.
|
// Append the conformance path with the signature of the opaque type.
|
||||||
appendDependentProtocolConformance(conformanceAccessPath, opaqueSignature);
|
appendDependentProtocolConformance(conformancePath, opaqueSignature);
|
||||||
appendType(conformingType, genericSig);
|
appendType(conformingType, genericSig);
|
||||||
appendOperator("HO");
|
appendOperator("HO");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
void ConformanceAccessPath::print(raw_ostream &out) const {
|
void ConformancePath::print(raw_ostream &out) const {
|
||||||
llvm::interleave(
|
llvm::interleave(
|
||||||
begin(), end(),
|
begin(), end(),
|
||||||
[&](const Entry &entry) {
|
[&](const Entry &entry) {
|
||||||
@@ -39,7 +39,7 @@ void ConformanceAccessPath::print(raw_ostream &out) const {
|
|||||||
[&] { out << " -> "; });
|
[&] { out << " -> "; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConformanceAccessPath::dump() const {
|
void ConformancePath::dump() const {
|
||||||
print(llvm::errs());
|
print(llvm::errs());
|
||||||
llvm::errs() << "\n";
|
llvm::errs() << "\n";
|
||||||
}
|
}
|
||||||
@@ -475,10 +475,10 @@ CanGenericSignature::getGenericParams() const {
|
|||||||
return {base, params.size()};
|
return {base, params.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
ConformanceAccessPath
|
ConformancePath
|
||||||
GenericSignatureImpl::getConformanceAccessPath(Type type,
|
GenericSignatureImpl::getConformancePath(Type type,
|
||||||
ProtocolDecl *protocol) const {
|
ProtocolDecl *protocol) const {
|
||||||
return getRequirementMachine()->getConformanceAccessPath(type, protocol);
|
return getRequirementMachine()->getConformancePath(type, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDecl *
|
TypeDecl *
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
// arbitrary type, not just a type parameter, and recursively transfozms the
|
// arbitrary type, not just a type parameter, and recursively transfozms the
|
||||||
// type parameters it contains, if any.
|
// type parameters it contains, if any.
|
||||||
//
|
//
|
||||||
// Also, getConformanceAccessPath() is another one-off operation.
|
// Also, getConformancePath() is another one-off operation.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ bool RequirementMachine::isValidTypeParameter(Type type) const {
|
|||||||
return (prefix == term);
|
return (prefix == term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the conformance access path used to extract the conformance of
|
/// Retrieve the conformance path used to extract the conformance of
|
||||||
/// interface \c type to the given \c protocol.
|
/// interface \c type to the given \c protocol.
|
||||||
///
|
///
|
||||||
/// \param type The interface type whose conformance access path is to be
|
/// \param type The interface type whose conformance access path is to be
|
||||||
@@ -480,10 +480,10 @@ bool RequirementMachine::isValidTypeParameter(Type type) const {
|
|||||||
/// this generic signature and ends at the conformance that makes \c type
|
/// this generic signature and ends at the conformance that makes \c type
|
||||||
/// conform to \c protocol.
|
/// conform to \c protocol.
|
||||||
///
|
///
|
||||||
/// \seealso ConformanceAccessPath
|
/// \seealso ConformancePath
|
||||||
ConformanceAccessPath
|
ConformancePath
|
||||||
RequirementMachine::getConformanceAccessPath(Type type,
|
RequirementMachine::getConformancePath(Type type,
|
||||||
ProtocolDecl *protocol) {
|
ProtocolDecl *protocol) {
|
||||||
assert(type->isTypeParameter());
|
assert(type->isTypeParameter());
|
||||||
|
|
||||||
auto mutTerm = Context.getMutableTermForType(type->getCanonicalType(),
|
auto mutTerm = Context.getMutableTermForType(type->getCanonicalType(),
|
||||||
@@ -505,9 +505,9 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
auto term = Term::get(mutTerm, Context);
|
auto term = Term::get(mutTerm, Context);
|
||||||
|
|
||||||
// Check if we've already cached the result before doing anything else.
|
// Check if we've already cached the result before doing anything else.
|
||||||
auto found = ConformanceAccessPaths.find(
|
auto found = ConformancePaths.find(
|
||||||
std::make_pair(term, protocol));
|
std::make_pair(term, protocol));
|
||||||
if (found != ConformanceAccessPaths.end()) {
|
if (found != ConformancePaths.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,25 +516,25 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
FrontendStatsTracer tracer(Stats, "get-conformance-access-path");
|
FrontendStatsTracer tracer(Stats, "get-conformance-access-path");
|
||||||
|
|
||||||
auto recordPath = [&](Term term, ProtocolDecl *proto,
|
auto recordPath = [&](Term term, ProtocolDecl *proto,
|
||||||
ConformanceAccessPath path) {
|
ConformancePath path) {
|
||||||
// Add the path to the buffer.
|
// Add the path to the buffer.
|
||||||
CurrentConformanceAccessPaths.emplace_back(term, path);
|
CurrentConformancePaths.emplace_back(term, path);
|
||||||
|
|
||||||
// Add the path to the map.
|
// Add the path to the map.
|
||||||
auto key = std::make_pair(term, proto);
|
auto key = std::make_pair(term, proto);
|
||||||
auto inserted = ConformanceAccessPaths.insert(
|
auto inserted = ConformancePaths.insert(
|
||||||
std::make_pair(key, path));
|
std::make_pair(key, path));
|
||||||
assert(inserted.second);
|
assert(inserted.second);
|
||||||
(void) inserted;
|
(void) inserted;
|
||||||
|
|
||||||
if (Stats)
|
if (Stats)
|
||||||
++Stats->getFrontendCounters().NumConformanceAccessPathsRecorded;
|
++Stats->getFrontendCounters().NumConformancePathsRecorded;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If this is the first time we're asked to look up a conformance access path,
|
// If this is the first time we're asked to look up a conformance access path,
|
||||||
// visit all of the root conformance requirements in our generic signature and
|
// visit all of the root conformance requirements in our generic signature and
|
||||||
// add them to the buffer.
|
// add them to the buffer.
|
||||||
if (ConformanceAccessPaths.empty()) {
|
if (ConformancePaths.empty()) {
|
||||||
for (const auto &req : Sig.getRequirements()) {
|
for (const auto &req : Sig.getRequirements()) {
|
||||||
// We only care about conformance requirements.
|
// We only care about conformance requirements.
|
||||||
if (req.getKind() != RequirementKind::Conformance)
|
if (req.getKind() != RequirementKind::Conformance)
|
||||||
@@ -543,9 +543,9 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
auto rootType = CanType(req.getFirstType());
|
auto rootType = CanType(req.getFirstType());
|
||||||
auto *rootProto = req.getProtocolDecl();
|
auto *rootProto = req.getProtocolDecl();
|
||||||
|
|
||||||
ConformanceAccessPath::Entry root(rootType, rootProto);
|
ConformancePath::Entry root(rootType, rootProto);
|
||||||
ArrayRef<ConformanceAccessPath::Entry> path(root);
|
ArrayRef<ConformancePath::Entry> path(root);
|
||||||
ConformanceAccessPath result(ctx.AllocateCopy(path));
|
ConformancePath result(ctx.AllocateCopy(path));
|
||||||
|
|
||||||
auto mutTerm = Context.getMutableTermForType(rootType, nullptr);
|
auto mutTerm = Context.getMutableTermForType(rootType, nullptr);
|
||||||
System.simplify(mutTerm);
|
System.simplify(mutTerm);
|
||||||
@@ -555,17 +555,17 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We enumerate conformance access paths in shortlex order until we find the
|
// We enumerate conformance paths in shortlex order until we find the
|
||||||
// path whose corresponding type reduces to the one we are looking for.
|
// path whose corresponding type reduces to the one we are looking for.
|
||||||
while (true) {
|
while (true) {
|
||||||
auto found = ConformanceAccessPaths.find(
|
auto found = ConformancePaths.find(
|
||||||
std::make_pair(term, protocol));
|
std::make_pair(term, protocol));
|
||||||
if (found != ConformanceAccessPaths.end()) {
|
if (found != ConformancePaths.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentConformanceAccessPaths.empty()) {
|
if (CurrentConformancePaths.empty()) {
|
||||||
llvm::errs() << "Failed to find conformance access path for ";
|
llvm::errs() << "Failed to find conformance path for ";
|
||||||
llvm::errs() << type << " (" << term << ")" << " : ";
|
llvm::errs() << type << " (" << term << ")" << " : ";
|
||||||
llvm::errs() << protocol->getName() << ":\n";
|
llvm::errs() << protocol->getName() << ":\n";
|
||||||
type.dump(llvm::errs());
|
type.dump(llvm::errs());
|
||||||
@@ -574,18 +574,18 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The buffer consists of all conformance access paths of length N.
|
// The buffer consists of all conformance paths of length N.
|
||||||
// Swap it out with an empty buffer, and fill it with all paths of
|
// Swap it out with an empty buffer, and fill it with all paths of
|
||||||
// length N+1.
|
// length N+1.
|
||||||
std::vector<std::pair<Term, ConformanceAccessPath>> oldPaths;
|
std::vector<std::pair<Term, ConformancePath>> oldPaths;
|
||||||
std::swap(CurrentConformanceAccessPaths, oldPaths);
|
std::swap(CurrentConformancePaths, oldPaths);
|
||||||
|
|
||||||
for (const auto &pair : oldPaths) {
|
for (const auto &pair : oldPaths) {
|
||||||
const auto &lastElt = pair.second.back();
|
const auto &lastElt = pair.second.back();
|
||||||
auto *lastProto = lastElt.second;
|
auto *lastProto = lastElt.second;
|
||||||
|
|
||||||
// A copy of the current path, populated as needed.
|
// A copy of the current path, populated as needed.
|
||||||
SmallVector<ConformanceAccessPath::Entry, 4> entries;
|
SmallVector<ConformancePath::Entry, 4> entries;
|
||||||
|
|
||||||
auto reqs = lastProto->getRequirementSignature().getRequirements();
|
auto reqs = lastProto->getRequirementSignature().getRequirements();
|
||||||
for (const auto &req : reqs) {
|
for (const auto &req : reqs) {
|
||||||
@@ -607,7 +607,7 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
// don't add it to the buffer. Note that because we iterate over
|
// don't add it to the buffer. Note that because we iterate over
|
||||||
// conformance access paths in shortlex order, the existing
|
// conformance access paths in shortlex order, the existing
|
||||||
// conformance access path is shorter than the one we found just now.
|
// conformance access path is shorter than the one we found just now.
|
||||||
if (ConformanceAccessPaths.count(
|
if (ConformancePaths.count(
|
||||||
std::make_pair(nextTerm, nextProto)))
|
std::make_pair(nextTerm, nextProto)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -620,7 +620,7 @@ RequirementMachine::getConformanceAccessPath(Type type,
|
|||||||
|
|
||||||
// Add the next entry.
|
// Add the next entry.
|
||||||
entries.emplace_back(nextSubjectType, nextProto);
|
entries.emplace_back(nextSubjectType, nextProto);
|
||||||
ConformanceAccessPath result = ctx.AllocateCopy(entries);
|
ConformancePath result = ctx.AllocateCopy(entries);
|
||||||
entries.pop_back();
|
entries.pop_back();
|
||||||
|
|
||||||
recordPath(nextTerm, nextProto, result);
|
recordPath(nextTerm, nextProto, result);
|
||||||
|
|||||||
@@ -565,8 +565,8 @@ void RequirementMachine::dump(llvm::raw_ostream &out) const {
|
|||||||
System.dump(out);
|
System.dump(out);
|
||||||
Map.dump(out);
|
Map.dump(out);
|
||||||
|
|
||||||
out << "Conformance access paths: {\n";
|
out << "Conformance paths: {\n";
|
||||||
for (auto pair : ConformanceAccessPaths) {
|
for (auto pair : ConformancePaths) {
|
||||||
out << "- " << pair.first.first << " : ";
|
out << "- " << pair.first.first << " : ";
|
||||||
out << pair.first.second->getName() << " => ";
|
out << pair.first.second->getName() << " => ";
|
||||||
pair.second.print(out);
|
pair.second.print(out);
|
||||||
|
|||||||
@@ -71,16 +71,15 @@ class RequirementMachine final {
|
|||||||
|
|
||||||
UnifiedStatsReporter *Stats;
|
UnifiedStatsReporter *Stats;
|
||||||
|
|
||||||
/// All conformance access paths computed so far.
|
/// All conformance paths computed so far.
|
||||||
llvm::DenseMap<std::pair<Term, ProtocolDecl *>,
|
llvm::DenseMap<std::pair<Term, ProtocolDecl *>,
|
||||||
ConformanceAccessPath> ConformanceAccessPaths;
|
ConformancePath> ConformancePaths;
|
||||||
|
|
||||||
/// Conformance access paths computed during the last round. All elements
|
/// Conformance access paths computed during the last round. All elements
|
||||||
/// have the same length. If a conformance access path of greater length
|
/// have the same length. If a conformance access path of greater length
|
||||||
/// is requested, we refill CurrentConformanceAccessPaths with all paths of
|
/// is requested, we refill CurrentConformancePaths with all paths of
|
||||||
/// length N+1, and add them to the ConformanceAccessPaths map.
|
/// length N+1, and add them to the ConformancePaths map.
|
||||||
std::vector<std::pair<Term, ConformanceAccessPath>>
|
std::vector<std::pair<Term, ConformancePath>> CurrentConformancePaths;
|
||||||
CurrentConformanceAccessPaths;
|
|
||||||
|
|
||||||
explicit RequirementMachine(RewriteContext &rewriteCtx);
|
explicit RequirementMachine(RewriteContext &rewriteCtx);
|
||||||
|
|
||||||
@@ -158,8 +157,7 @@ public:
|
|||||||
Type getReducedType(Type type,
|
Type getReducedType(Type type,
|
||||||
TypeArrayView<GenericTypeParamType> genericParams) const;
|
TypeArrayView<GenericTypeParamType> genericParams) const;
|
||||||
bool isValidTypeParameter(Type type) const;
|
bool isValidTypeParameter(Type type) const;
|
||||||
ConformanceAccessPath getConformanceAccessPath(Type type,
|
ConformancePath getConformancePath(Type type, ProtocolDecl *protocol);
|
||||||
ProtocolDecl *protocol);
|
|
||||||
TypeDecl *lookupNestedType(Type depType, Identifier name) const;
|
TypeDecl *lookupNestedType(Type depType, Identifier name) const;
|
||||||
|
|
||||||
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>
|
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ RequirementMachine::computeMinimalGenericSignature(
|
|||||||
auto sig = GenericSignature::get(getGenericParams(), reqs);
|
auto sig = GenericSignature::get(getGenericParams(), reqs);
|
||||||
|
|
||||||
// Remember the signature for generic signature queries. In particular,
|
// Remember the signature for generic signature queries. In particular,
|
||||||
// getConformanceAccessPath() needs the current requirement machine's
|
// getConformancePath() needs the current requirement machine's
|
||||||
// generic signature.
|
// generic signature.
|
||||||
Sig = sig.getCanonicalSignature();
|
Sig = sig.getCanonicalSignature();
|
||||||
|
|
||||||
|
|||||||
@@ -367,11 +367,10 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
|
|||||||
return ProtocolConformanceRef::forMissingOrInvalid(substType, proto);
|
return ProtocolConformanceRef::forMissingOrInvalid(substType, proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto accessPath =
|
auto path = genericSig->getConformancePath(type, proto);
|
||||||
genericSig->getConformanceAccessPath(type, proto);
|
|
||||||
|
|
||||||
ProtocolConformanceRef conformance;
|
ProtocolConformanceRef conformance;
|
||||||
for (const auto &step : accessPath) {
|
for (const auto &step : path) {
|
||||||
// For the first step, grab the initial conformance.
|
// For the first step, grab the initial conformance.
|
||||||
if (conformance.isInvalid()) {
|
if (conformance.isInvalid()) {
|
||||||
if (auto initialConformance = getSignatureConformance(
|
if (auto initialConformance = getSignatureConformance(
|
||||||
|
|||||||
@@ -191,8 +191,7 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
|
|||||||
|
|
||||||
auto environment = archetype->getGenericEnvironment();
|
auto environment = archetype->getGenericEnvironment();
|
||||||
|
|
||||||
// Otherwise, ask the generic signature for the environment for the best
|
// Otherwise, ask the generic signature for the best path to the conformance.
|
||||||
// path to the conformance.
|
|
||||||
// TODO: this isn't necessarily optimal if the direct conformance isn't
|
// TODO: this isn't necessarily optimal if the direct conformance isn't
|
||||||
// concretely available; we really ought to be comparing the full paths
|
// concretely available; we really ought to be comparing the full paths
|
||||||
// to this conformance from concrete sources.
|
// to this conformance from concrete sources.
|
||||||
@@ -200,8 +199,7 @@ llvm::Value *irgen::emitArchetypeWitnessTableRef(IRGenFunction &IGF,
|
|||||||
auto signature = environment->getGenericSignature().getCanonicalSignature();
|
auto signature = environment->getGenericSignature().getCanonicalSignature();
|
||||||
auto archetypeDepType = archetype->getInterfaceType();
|
auto archetypeDepType = archetype->getInterfaceType();
|
||||||
|
|
||||||
auto astPath = signature->getConformanceAccessPath(archetypeDepType,
|
auto astPath = signature->getConformancePath(archetypeDepType, protocol);
|
||||||
protocol);
|
|
||||||
|
|
||||||
auto i = astPath.begin(), e = astPath.end();
|
auto i = astPath.begin(), e = astPath.end();
|
||||||
assert(i != e && "empty path!");
|
assert(i != e && "empty path!");
|
||||||
|
|||||||
Reference in New Issue
Block a user