Skip to content
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

[Generic Signature Builder] Improve the handling of typealiases in protocols. #7389

Merged
merged 3 commits into from
Feb 21, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,9 @@ ERROR(requires_generic_param_same_type_does_not_conform,none,
(Type, Identifier))
ERROR(requires_same_concrete_type,none,
"generic signature requires types %0 and %1 to be the same", (Type, Type))
ERROR(protocol_typealias_conflict, none,
"typealias %0 requires types %1 and %2 to be the same",
(Identifier, Type, Type))

ERROR(mutiple_layout_constraints,none,
"multiple layout constraints cannot be used at the same time: %0 and %1",
Expand Down
69 changes: 59 additions & 10 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@ class GenericSignatureBuilder {
/// type or some type derived from it.
class PotentialArchetype;

using UnresolvedType = llvm::PointerUnion<PotentialArchetype *, Type>;
struct ResolvedType;

using RequirementRHS =
llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;

Expand Down Expand Up @@ -419,6 +422,49 @@ class GenericSignatureBuilder {
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);

public:
/// \brief Add a new same-type requirement between two fully resolved types
/// (output of \c GenericSignatureBuilder::resolve).
///
/// If the types refer to two concrete types that are fundamentally
/// incompatible (e.g. \c Foo<Bar<T>> and \c Foo<Baz>), \c diagnoseMismatch is
/// called with the two types that don't match (\c Bar<T> and \c Baz for the
/// previous example).
bool
addSameTypeRequirement(ResolvedType paOrT1, ResolvedType paOrT2,
const RequirementSource *Source,
llvm::function_ref<void(Type, Type)> diagnoseMismatch);

/// \brief Add a new same-type requirement between two fully resolved types
/// (output of GenericSignatureBuilder::resolve).
///
/// The two types must not be incompatible concrete types.
bool addSameTypeRequirement(ResolvedType paOrT1, ResolvedType paOrT2,
const RequirementSource *Source);

/// \brief Add a new same-type requirement between two unresolved types.
///
/// The types are resolved with \c GenericSignatureBuilder::resolve, and must
/// not be incompatible concrete types.
bool addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
const RequirementSource *Source);

/// \brief Add a new same-type requirement between two unresolved types.
///
/// The types are resolved with \c GenericSignatureBuilder::resolve. \c
/// diagnoseMismatch is called if the two types refer to incompatible concrete
/// types.
bool
addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
const RequirementSource *Source,
llvm::function_ref<void(Type, Type)> diagnoseMismatch);

private:
/// \brief Add a new superclass requirement specifying that the given
/// potential archetype has the given type as an ancestor.
bool addSuperclassRequirement(PotentialArchetype *T,
Type Superclass,
const RequirementSource *Source);

/// \brief Add a new conformance requirement specifying that the given
/// potential archetypes are equivalent.
bool addSameTypeRequirementBetweenArchetypes(PotentialArchetype *T1,
Expand All @@ -431,21 +477,14 @@ class GenericSignatureBuilder {
Type Concrete,
const RequirementSource *Source);

private:
/// \brief Add a new superclass requirement specifying that the given
/// potential archetype has the given type as an ancestor.
bool addSuperclassRequirement(PotentialArchetype *T,
Type Superclass,
const RequirementSource *Source);

/// \brief Add a new same-type requirement specifying that the given two
/// types should be the same.
///
/// \param diagnoseMismatch Callback invoked when the types in the same-type
/// requirement mismatch.
bool addSameTypeRequirement(
Type T1, Type T2, const RequirementSource *Source,
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
bool addSameTypeRequirementBetweenConcrete(
Type T1, Type T2, const RequirementSource *Source,
llvm::function_ref<void(Type, Type)> diagnoseMismatch);

/// Add the requirements placed on the given type parameter
/// to the given potential archetype.
Expand Down Expand Up @@ -587,6 +626,16 @@ class GenericSignatureBuilder {
/// For any type that cannot refer to an archetype, this routine returns null.
PotentialArchetype *resolveArchetype(Type type);

/// \brief Resolve the given type as far as this Builder knows how.
///
/// This returns either a non-typealias potential archetype or a Type, if \c
/// type is concrete.
// FIXME: the hackTypeFromGenericTypeAlias is just temporarily patching over
// problems with generic typealiases (see the comment on the ResolvedType
// function)
ResolvedType resolve(UnresolvedType type,
bool hackTypeFromGenericTypeAlias = false);

/// \brief Dump all of the requirements, both specified and inferred.
LLVM_ATTRIBUTE_DEPRECATED(
void dump(),
Expand Down