Move protocol-conformance computation into Module::lookupConformance().

Introduce an AST operation that, given a type and a protocol, determines
whether the type conforms to the protocol and produces the protocol
conformance structure. Previously, this operation was only available
on the type checker, requiring many callbacks from the AST to the type
checker during AST substitution operations (for example).

Now, we only call back into the type checker when we hit a case where
we see an explicit conformance in the AST, but the actual
ProtocolConformance object has not yet been built due to lazy type
checking.

Note that we still require a resolver (i.e., a TypeChecker) in a few
places, although we shouldn't need it outside of lazy type
checking. I'll loosen up the restrictions next.

There's a minor diagnostics regression here that will be cleaned up in
a future commit.


Swift SVN r8129
This commit is contained in:
Doug Gregor
2013-09-12 00:23:19 +00:00
parent 3aeb4814ad
commit e6076d1caf
9 changed files with 455 additions and 340 deletions

View File

@@ -44,10 +44,13 @@ namespace swift {
class LookupCache;
class ModuleLoader;
class NameAliasType;
class NominalTypeDecl;
class UnionElementDecl;
class OperatorDecl;
class PostfixOperatorDecl;
class PrefixOperatorDecl;
class ProtocolConformance;
class ProtocolDecl;
struct PrintOptions;
class TupleType;
class Type;
@@ -102,6 +105,22 @@ enum NameLookupOptions {
NL_Constructor = NL_RemoveNonVisible
};
/// Describes the result of looking for the conformance of a given type
/// to a specific protocol.
enum class ConformanceKind {
/// The type does not conform to the protocol.
DoesNotConform,
/// The type conforms to the protocol, with the given conformance.
Conforms,
/// The type is specified to conform to the protocol, but that conformance
/// has not yet been checked.
UncheckedConforms
};
/// The result of looking for a specific conformance.
typedef llvm::PointerIntPair<ProtocolConformance *, 2, ConformanceKind>
LookupConformanceResult;
/// Module - A unit of modularity. The current translation unit is a
/// module, as is an imported module.
class Module : public DeclContext {
@@ -225,6 +244,29 @@ public:
Identifier name,
SmallVectorImpl<ValueDecl*> &results) const;
/// Look for the conformance of the given type to the given protocol.
///
/// This routine determines whether the given \c type conforms to the given
/// \c protocol. It only looks for explicit conformances (which are
/// required by the language), and will return a \c ProtocolConformance*
/// describing the conformance.
///
/// During type-checking, it is possible that this routine will find an
/// explicit declaration of conformance that has not yet been type-checked,
/// in which case it will return note the presence of an unchecked
/// conformance.
///
/// \param type The type for which we are computing conformance.
///
/// \param protocol The protocol to which we are computing conformance.
///
/// \param resolver The lazy resolver.
///
/// \returns The result of the conformance search, with a conformance
/// structure when possible.
LookupConformanceResult
lookupConformance(Type type, ProtocolDecl *protocol, LazyResolver *resolver);
/// Looks up which modules are re-exported by this module.
void getImportedModules(SmallVectorImpl<ImportedModule> &modules,
bool includePrivate = false) const;