Skip to content

Commit 1c34375

Browse files
authored
Merge pull request #10565 from DougGregor/gsb-concrete-types-recursion
[4.0] [GSB] Improve handling of concrete types, type aliases, recursion
2 parents 59ed33d + 19f4ee7 commit 1c34375

21 files changed

+3465
-277
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,16 +1682,16 @@ ERROR(requires_generic_param_same_type_does_not_conform,none,
16821682
(Type, Identifier))
16831683
ERROR(requires_same_concrete_type,none,
16841684
"generic signature requires types %0 and %1 to be the same", (Type, Type))
1685-
ERROR(protocol_typealias_conflict, none,
1686-
"type alias %0 requires types %1 and %2 to be the same",
1687-
(Identifier, Type, Type))
16881685
WARNING(redundant_conformance_constraint,none,
16891686
"redundant conformance constraint %0: %1", (Type, ProtocolDecl *))
16901687
NOTE(redundant_conformance_here,none,
16911688
"conformance constraint %1: %2 %select{written here|implied here|"
16921689
"inferred from type here}0",
16931690
(unsigned, Type, ProtocolDecl *))
16941691

1692+
ERROR(same_type_conflict,none,
1693+
"%select{generic parameter |protocol |}0%1 cannot be equal to both "
1694+
"%2 and %3", (unsigned, Type, Type, Type))
16951695
WARNING(redundant_same_type_to_concrete,none,
16961696
"redundant same-type constraint %0 == %1", (Type, Type))
16971697
NOTE(same_type_redundancy_here,none,
@@ -1732,6 +1732,9 @@ WARNING(inherited_associated_type_redecl,none,
17321732
WARNING(typealias_override_associated_type,none,
17331733
"typealias overriding associated type %0 from protocol %1 is better "
17341734
"expressed as same-type constraint on the protocol", (DeclName, Type))
1735+
WARNING(associated_type_override_typealias,none,
1736+
"associated type %0 is redundant with type %0 declared in inherited "
1737+
"%1 %2", (DeclName, DescriptiveDeclKind, Type))
17351738

17361739
ERROR(generic_param_access,none,
17371740
"%0 %select{must be declared %select{"

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/Decl.h"
2424
#include "swift/AST/DiagnosticEngine.h"
2525
#include "swift/AST/Identifier.h"
26+
#include "swift/AST/ProtocolConformanceRef.h"
2627
#include "swift/AST/Types.h"
2728
#include "swift/AST/TypeLoc.h"
2829
#include "swift/AST/TypeRepr.h"
@@ -74,6 +75,11 @@ enum class ArchetypeResolutionKind {
7475
/// Only create a new potential archetype to describe this dependent type
7576
/// if it is already known.
7677
AlreadyKnown,
78+
79+
/// Only create a potential archetype when it is well-formed (i.e., we know
80+
/// that there is a nested type with that name), but (unlike \c AlreadyKnown)
81+
/// allow the creation of a new potential archetype.
82+
WellFormed,
7783
};
7884

7985
/// \brief Collects a set of requirements of generic parameters, both explicitly
@@ -176,6 +182,9 @@ class GenericSignatureBuilder {
176182
/// the concrete type.
177183
unsigned recursiveConcreteType : 1;
178184

185+
/// Whether we have an invalid concrete type.
186+
unsigned invalidConcreteType : 1;
187+
179188
/// Whether we have detected recursion during the substitution of
180189
/// the superclass type.
181190
unsigned recursiveSuperclassType : 1;
@@ -281,16 +290,24 @@ class GenericSignatureBuilder {
281290
FloatingRequirementSource source,
282291
UnresolvedHandlingKind unresolvedHandling);
283292

293+
/// Resolve the conformance of the given potential archetype to
294+
/// the given protocol when the potential archetype is known to be equivalent
295+
/// to a concrete type.
296+
///
297+
/// \returns the requirement source for the resolved conformance, or nullptr
298+
/// if the conformance could not be resolved.
299+
const RequirementSource *resolveConcreteConformance(PotentialArchetype *pa,
300+
ProtocolDecl *proto);
301+
284302
/// Retrieve the constraint source conformance for the superclass constraint
285303
/// of the given potential archetype (if present) to the given protocol.
286304
///
287305
/// \param pa The potential archetype whose superclass constraint is being
288306
/// queried.
289307
///
290308
/// \param proto The protocol to which we are establishing conformance.
291-
const RequirementSource *resolveSuperConformance(
292-
GenericSignatureBuilder::PotentialArchetype *pa,
293-
ProtocolDecl *proto);
309+
const RequirementSource *resolveSuperConformance(PotentialArchetype *pa,
310+
ProtocolDecl *proto);
294311

295312
/// \brief Add a new conformance requirement specifying that the given
296313
/// potential archetype conforms to the given protocol.
@@ -316,15 +333,6 @@ class GenericSignatureBuilder {
316333
FloatingRequirementSource Source,
317334
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
318335

319-
/// \brief Add a new same-type requirement between two fully resolved types
320-
/// (output of GenericSignatureBuilder::resolve).
321-
///
322-
/// The two types must not be incompatible concrete types.
323-
ConstraintResult addSameTypeRequirementDirect(
324-
ResolvedType paOrT1,
325-
ResolvedType paOrT2,
326-
FloatingRequirementSource Source);
327-
328336
/// \brief Add a new same-type requirement between two unresolved types.
329337
///
330338
/// The types are resolved with \c GenericSignatureBuilder::resolve, and must
@@ -770,7 +778,7 @@ class GenericSignatureBuilder::RequirementSource final
770778

771779
/// A requirement that was resolved via a superclass requirement.
772780
///
773-
/// This stores the \c ProtocolConformance* used to resolve the
781+
/// This stores the \c ProtocolConformanceRef used to resolve the
774782
/// requirement.
775783
Superclass,
776784

@@ -784,6 +792,10 @@ class GenericSignatureBuilder::RequirementSource final
784792
/// This stores the \c ProtocolConformance* used to resolve the
785793
/// requirement.
786794
Concrete,
795+
796+
/// A requirement that was resolved based on structural derivation from
797+
/// another requirement.
798+
Derived,
787799
};
788800

789801
/// The kind of requirement source.
@@ -792,6 +804,7 @@ class GenericSignatureBuilder::RequirementSource final
792804
private:
793805
/// The kind of storage we have.
794806
enum class StorageKind : uint8_t {
807+
None,
795808
RootArchetype,
796809
StoredType,
797810
ProtocolConformance,
@@ -816,7 +829,7 @@ class GenericSignatureBuilder::RequirementSource final
816829
TypeBase *type;
817830

818831
/// A protocol conformance used to satisfy the requirement.
819-
ProtocolConformance *conformance;
832+
void *conformance;
820833

821834
/// An associated type to which a requirement is being applied.
822835
AssociatedTypeDecl *assocType;
@@ -839,6 +852,7 @@ class GenericSignatureBuilder::RequirementSource final
839852
case Superclass:
840853
case Parent:
841854
case Concrete:
855+
case Derived:
842856
return 0;
843857
}
844858

@@ -882,6 +896,7 @@ class GenericSignatureBuilder::RequirementSource final
882896
case Superclass:
883897
case Parent:
884898
case Concrete:
899+
case Derived:
885900
return false;
886901
}
887902

@@ -931,7 +946,7 @@ class GenericSignatureBuilder::RequirementSource final
931946
}
932947

933948
RequirementSource(Kind kind, const RequirementSource *parent,
934-
ProtocolConformance *conformance)
949+
ProtocolConformanceRef conformance)
935950
: kind(kind), storageKind(StorageKind::ProtocolConformance),
936951
hasTrailingWrittenRequirementLoc(false),
937952
usesRequirementSignature(false), parent(parent) {
@@ -940,7 +955,7 @@ class GenericSignatureBuilder::RequirementSource final
940955
assert(isAcceptableStorageKind(kind, storageKind) &&
941956
"RequirementSource kind/storageKind mismatch");
942957

943-
storage.conformance = conformance;
958+
storage.conformance = conformance.getOpaqueValue();
944959
}
945960

946961
RequirementSource(Kind kind, const RequirementSource *parent,
@@ -956,6 +971,16 @@ class GenericSignatureBuilder::RequirementSource final
956971
storage.assocType = assocType;
957972
}
958973

974+
RequirementSource(Kind kind, const RequirementSource *parent)
975+
: kind(kind), storageKind(StorageKind::None),
976+
hasTrailingWrittenRequirementLoc(false),
977+
usesRequirementSignature(false), parent(parent) {
978+
assert((static_cast<bool>(parent) != isRootKind(kind)) &&
979+
"Root RequirementSource should not have parent (or vice versa)");
980+
assert(isAcceptableStorageKind(kind, storageKind) &&
981+
"RequirementSource kind/storageKind mismatch");
982+
}
983+
959984
public:
960985
/// Retrieve an abstract requirement source.
961986
static const RequirementSource *forAbstract(PotentialArchetype *root);
@@ -997,13 +1022,14 @@ class GenericSignatureBuilder::RequirementSource final
9971022
/// A requirement source that describes that a requirement that is resolved
9981023
/// via a superclass requirement.
9991024
const RequirementSource *viaSuperclass(
1000-
GenericSignatureBuilder &builder,
1001-
ProtocolConformance *conformance) const;
1025+
GenericSignatureBuilder &builder,
1026+
ProtocolConformanceRef conformance) const;
10021027

10031028
/// A requirement source that describes that a requirement that is resolved
10041029
/// via a same-type-to-concrete requirement.
1005-
const RequirementSource *viaConcrete(GenericSignatureBuilder &builder,
1006-
ProtocolConformance *conformance) const;
1030+
const RequirementSource *viaConcrete(
1031+
GenericSignatureBuilder &builder,
1032+
ProtocolConformanceRef conformance) const;
10071033

10081034
/// A constraint source that describes that a constraint that is resolved
10091035
/// for a nested type via a constraint on its parent.
@@ -1012,6 +1038,10 @@ class GenericSignatureBuilder::RequirementSource final
10121038
const RequirementSource *viaParent(GenericSignatureBuilder &builder,
10131039
AssociatedTypeDecl *assocType) const;
10141040

1041+
/// A constraint source that describes a constraint that is structurally
1042+
/// derived from another constraint but does not require further information.
1043+
const RequirementSource *viaDerived(GenericSignatureBuilder &builder) const;
1044+
10151045
/// Retrieve the root requirement source.
10161046
const RequirementSource *getRoot() const;
10171047

@@ -1100,9 +1130,9 @@ class GenericSignatureBuilder::RequirementSource final
11001130
ProtocolDecl *getProtocolDecl() const;
11011131

11021132
/// Retrieve the protocol conformance for this requirement, if there is one.
1103-
ProtocolConformance *getProtocolConformance() const {
1104-
if (storageKind != StorageKind::ProtocolConformance) return nullptr;
1105-
return storage.conformance;
1133+
ProtocolConformanceRef getProtocolConformance() const {
1134+
assert(storageKind == StorageKind::ProtocolConformance);
1135+
return ProtocolConformanceRef::getFromOpaqueValue(storage.conformance);
11061136
}
11071137

11081138
/// Retrieve the associated type declaration for this requirement, if there
@@ -1577,18 +1607,6 @@ class GenericSignatureBuilder::PotentialArchetype {
15771607
PotentialArchetype *getNestedType(TypeDecl *concreteDecl,
15781608
GenericSignatureBuilder &builder);
15791609

1580-
/// Describes the kind of update that is performed.
1581-
enum class NestedTypeUpdate {
1582-
/// Resolve an existing potential archetype, but don't create a new
1583-
/// one if not present.
1584-
ResolveExisting,
1585-
/// If this potential archetype is missing, create it.
1586-
AddIfMissing,
1587-
/// If this potential archetype is missing and would be a better anchor,
1588-
/// create it.
1589-
AddIfBetterAnchor,
1590-
};
1591-
15921610
/// \brief Retrieve (or create) a nested type that is the current best
15931611
/// nested archetype anchor (locally) with the given name.
15941612
///
@@ -1597,7 +1615,7 @@ class GenericSignatureBuilder::PotentialArchetype {
15971615
PotentialArchetype *getNestedArchetypeAnchor(
15981616
Identifier name,
15991617
GenericSignatureBuilder &builder,
1600-
NestedTypeUpdate kind = NestedTypeUpdate::AddIfMissing);
1618+
ArchetypeResolutionKind kind);
16011619

16021620
/// Update the named nested type when we know this type conforms to the given
16031621
/// protocol.
@@ -1607,7 +1625,7 @@ class GenericSignatureBuilder::PotentialArchetype {
16071625
/// a potential archetype should not be created if it's missing.
16081626
PotentialArchetype *updateNestedTypeForConformance(
16091627
PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
1610-
NestedTypeUpdate kind);
1628+
ArchetypeResolutionKind kind);
16111629

16121630
/// Update the named nested type when we know this type conforms to the given
16131631
/// protocol.
@@ -1618,7 +1636,7 @@ class GenericSignatureBuilder::PotentialArchetype {
16181636
PotentialArchetype *updateNestedTypeForConformance(
16191637
Identifier name,
16201638
ProtocolDecl *protocol,
1621-
NestedTypeUpdate kind);
1639+
ArchetypeResolutionKind kind);
16221640

16231641
/// \brief Retrieve (or build) the type corresponding to the potential
16241642
/// archetype within the given generic environment.

lib/AST/GenericSignature.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ ConformanceAccessPath GenericSignature::getConformanceAccessPath(
872872
auto pa =
873873
reqSigBuilder.resolveArchetype(
874874
storedType,
875-
ArchetypeResolutionKind::CompleteWellFormed);
875+
ArchetypeResolutionKind::AlwaysPartial);
876876
auto equivClass = pa->getOrCreateEquivalenceClass();
877877

878878
// Find the conformance of this potential archetype to the protocol in

0 commit comments

Comments
 (0)