Skip to content

Commit ec7b317

Browse files
authored
Merge pull request #5995 from DougGregor/decouple-archetype-builder
2 parents d30df45 + 589b469 commit ec7b317

17 files changed

+634
-325
lines changed

include/swift/AST/ArchetypeBuilder.h

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,9 @@ class ArchetypeBuilder::PotentialArchetype {
366366
llvm::MapVector<Identifier, llvm::TinyPtrVector<PotentialArchetype *>>
367367
NestedTypes;
368368

369-
/// \brief The actual archetype, once it has been assigned, or the concrete
370-
/// type that the parameter was same-type constrained to.
371-
ArchetypeType::NestedType ArchetypeOrConcreteType;
369+
/// The concrete type to which a this potential archetype has been
370+
/// constrained.
371+
Type ConcreteType;
372372

373373
/// \brief Recursively conforms to itself.
374374
unsigned IsRecursive : 1;
@@ -377,10 +377,6 @@ class ArchetypeBuilder::PotentialArchetype {
377377
/// be resolved.
378378
unsigned Invalid : 1;
379379

380-
/// Whether we are currently substituting into the concrete type of
381-
/// this potential archetype.
382-
unsigned SubstitutingConcreteType : 1;
383-
384380
/// Whether we have detected recursion during the substitution of
385381
/// the concrete type.
386382
unsigned RecursiveConcreteType : 1;
@@ -403,7 +399,7 @@ class ArchetypeBuilder::PotentialArchetype {
403399
/// associated type.
404400
PotentialArchetype(PotentialArchetype *Parent, Identifier Name)
405401
: ParentOrParam(Parent), NameOrAssociatedType(Name), Representative(this),
406-
IsRecursive(false), Invalid(false), SubstitutingConcreteType(false),
402+
IsRecursive(false), Invalid(false),
407403
RecursiveConcreteType(false), RecursiveSuperclassType(false),
408404
DiagnosedRename(false)
409405
{
@@ -415,7 +411,7 @@ class ArchetypeBuilder::PotentialArchetype {
415411
PotentialArchetype(PotentialArchetype *Parent, AssociatedTypeDecl *AssocType)
416412
: ParentOrParam(Parent), NameOrAssociatedType(AssocType),
417413
Representative(this), IsRecursive(false), Invalid(false),
418-
SubstitutingConcreteType(false), RecursiveConcreteType(false),
414+
RecursiveConcreteType(false),
419415
RecursiveSuperclassType(false), DiagnosedRename(false)
420416
{
421417
assert(Parent != nullptr && "Not an associated type?");
@@ -426,7 +422,7 @@ class ArchetypeBuilder::PotentialArchetype {
426422
PotentialArchetype(PotentialArchetype *Parent, TypeAliasDecl *TypeAlias)
427423
: ParentOrParam(Parent), NameOrAssociatedType(TypeAlias),
428424
Representative(this), IsRecursive(false), Invalid(false),
429-
SubstitutingConcreteType(false), RecursiveConcreteType(false),
425+
RecursiveConcreteType(false),
430426
RecursiveSuperclassType(false), DiagnosedRename(false)
431427
{
432428
assert(Parent != nullptr && "Not an associated type?");
@@ -438,7 +434,7 @@ class ArchetypeBuilder::PotentialArchetype {
438434
Identifier Name)
439435
: ParentOrParam(GenericParam),
440436
NameOrAssociatedType(Name), Representative(this), IsRecursive(false),
441-
Invalid(false), SubstitutingConcreteType(false),
437+
Invalid(false),
442438
RecursiveConcreteType(false), RecursiveSuperclassType(false),
443439
DiagnosedRename(false)
444440
{
@@ -448,6 +444,14 @@ class ArchetypeBuilder::PotentialArchetype {
448444
/// \brief Recursively build the full name.
449445
void buildFullName(bool forDebug, SmallVectorImpl<char> &result) const;
450446

447+
/// Retrieve the generic parameter at the root of this potential archetype.
448+
GenericTypeParamType *getRootParam() const {
449+
if (auto parent = getParent())
450+
return parent->getRootParam();
451+
452+
return getGenericParam();
453+
}
454+
451455
public:
452456
~PotentialArchetype();
453457

@@ -466,14 +470,6 @@ class ArchetypeBuilder::PotentialArchetype {
466470
return ParentOrParam.dyn_cast<PotentialArchetype *>();
467471
}
468472

469-
/// Retrieve the generic parameter at the root of this potential archetype.
470-
GenericTypeParamType *getRootParam() const {
471-
if (auto parent = getParent())
472-
return parent->getRootParam();
473-
474-
return getGenericParam();
475-
}
476-
477473
/// Retrieve the associated type to which this potential archetype
478474
/// has been resolved.
479475
AssociatedTypeDecl *getResolvedAssociatedType() const {
@@ -487,10 +483,31 @@ class ArchetypeBuilder::PotentialArchetype {
487483

488484
/// Retrieve the generic type parameter for this potential
489485
/// archetype, if it corresponds to a generic parameter.
486+
///
487+
/// FIXME: We should weaken this to just a depth/index key.
490488
GenericTypeParamType *getGenericParam() const {
491489
return ParentOrParam.dyn_cast<GenericTypeParamType *>();
492490
}
493-
491+
492+
/// Determine whether this is a generic parameter.
493+
bool isGenericParam() const {
494+
return ParentOrParam.is<GenericTypeParamType *>();
495+
}
496+
497+
/// Retrieve the generic parameter key for a potential archetype that
498+
/// represents this potential archetype.
499+
///
500+
/// \pre \c isGenericParam()
501+
GenericParamKey getGenericParamKey() const {
502+
return getGenericParam();
503+
}
504+
505+
/// Retrieve the generic parameter key for the generic parameter at the
506+
/// root of this potential archetype.
507+
GenericParamKey getRootGenericParamKey() const {
508+
return getRootParam();
509+
}
510+
494511
/// Retrieve the type alias.
495512
TypeAliasDecl *getTypeAliasDecl() const {
496513
return NameOrAssociatedType.dyn_cast<TypeAliasDecl *>();
@@ -550,33 +567,38 @@ class ArchetypeBuilder::PotentialArchetype {
550567
PotentialArchetype *getNestedType(Identifier Name,
551568
ArchetypeBuilder &builder);
552569

570+
553571
/// \brief Retrieve (or build) the type corresponding to the potential
554-
/// archetype.
555-
ArchetypeType::NestedType getType(ArchetypeBuilder &builder);
572+
/// archetype within the given generic environment.
573+
ArchetypeType::NestedType getTypeInContext(ArchetypeBuilder &builder,
574+
GenericEnvironment *genericEnv);
556575

557576
/// Retrieve the dependent type that describes this potential
558577
/// archetype.
559578
///
579+
/// \param genericParams The set of generic parameters to use in the resulting
580+
/// dependent type.
581+
///
560582
/// \param allowUnresolved If true, allow the result to contain
561583
/// \c DependentMemberType types with a name but no specific associated
562584
/// type.
563-
Type getDependentType(bool allowUnresolved);
585+
Type getDependentType(ArrayRef<GenericTypeParamType *> genericParams,
586+
bool allowUnresolved);
564587

565588
/// True if the potential archetype has been bound by a concrete type
566589
/// constraint.
567590
bool isConcreteType() const {
568591
if (Representative != this)
569592
return Representative->isConcreteType();
570593

571-
return ArchetypeOrConcreteType.isConcreteType();
594+
return static_cast<bool>(ConcreteType);
572595
}
573596

574597
/// Get the concrete type this potential archetype is constrained to.
575598
Type getConcreteType() const {
576-
assert(isConcreteType());
577599
if (Representative != this)
578600
return Representative->getConcreteType();
579-
return ArchetypeOrConcreteType.getAsConcreteType();
601+
return ConcreteType;
580602
}
581603

582604
void setIsRecursive() { IsRecursive = true; }

include/swift/AST/Decl.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/DefaultArgumentKind.h"
2525
#include "swift/AST/GenericEnvironment.h"
2626
#include "swift/AST/GenericSignature.h"
27+
#include "swift/AST/GenericParamKey.h"
2728
#include "swift/AST/LazyResolver.h"
2829
#include "swift/AST/TypeAlignments.h"
2930
#include "swift/AST/Witness.h"
@@ -4013,6 +4014,8 @@ class AbstractStorageDecl : public ValueDecl {
40134014
return OverriddenDecl;
40144015
}
40154016
void setOverriddenDecl(AbstractStorageDecl *over) {
4017+
// FIXME: Hack due to broken class circulatity checking.
4018+
if (over == this) return;
40164019
OverriddenDecl = over;
40174020
over->setIsOverridden();
40184021
}
@@ -5092,6 +5095,9 @@ class FuncDecl final : public AbstractFunctionDecl,
50925095
return OverriddenOrBehaviorParamDecl.dyn_cast<FuncDecl *>();
50935096
}
50945097
void setOverriddenDecl(FuncDecl *over) {
5098+
// FIXME: Hack due to broken class circulatity checking.
5099+
if (over == this) return;
5100+
50955101
// A function cannot be an override if it is also a derived global decl
50965102
// (since derived decls are at global scope).
50975103
assert((!OverriddenOrBehaviorParamDecl
@@ -5519,6 +5525,9 @@ class ConstructorDecl : public AbstractFunctionDecl {
55195525

55205526
ConstructorDecl *getOverriddenDecl() const { return OverriddenDecl; }
55215527
void setOverriddenDecl(ConstructorDecl *over) {
5528+
// FIXME: Hack due to broken class circulatity checking.
5529+
if (over == this) return;
5530+
55225531
OverriddenDecl = over;
55235532
over->setIsOverridden();
55245533
}
@@ -6001,6 +6010,9 @@ inline bool Decl::isPotentiallyOverridable() const {
60016010
}
60026011
}
60036012

6013+
inline GenericParamKey::GenericParamKey(const GenericTypeParamDecl *d)
6014+
: Depth(d->getDepth()), Index(d->getIndex()) { }
6015+
60046016
} // end namespace swift
60056017

60066018
#endif

include/swift/AST/GenericEnvironment.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,20 @@
1818
#define SWIFT_AST_GENERIC_ENVIRONMENT_H
1919

2020
#include "swift/AST/SubstitutionMap.h"
21+
#include "swift/AST/GenericParamKey.h"
2122
#include "swift/AST/GenericSignature.h"
2223

2324
namespace swift {
2425

26+
class ArchetypeBuilder;
2527
class ASTContext;
2628
class GenericTypeParamType;
2729
class SILModule;
2830
class SILType;
2931

3032
/// Describes the mapping between archetypes and interface types for the
3133
/// generic parameters of a DeclContext.
32-
class GenericEnvironment final {
34+
class alignas(1 << DeclAlignInBits) GenericEnvironment final {
3335
GenericSignature *Signature;
3436
TypeSubstitutionMap ArchetypeToInterfaceMap;
3537
TypeSubstitutionMap InterfaceToArchetypeMap;
@@ -63,7 +65,12 @@ class GenericEnvironment final {
6365

6466
/// Add a mapping of a generic parameter to a specific type (which may be
6567
/// an archetype)
66-
void addMapping(GenericTypeParamType *genericParam, Type contextType);
68+
void addMapping(GenericParamKey key, Type contextType);
69+
70+
/// Retrieve the mapping for the given generic parameter, if present.
71+
///
72+
/// This is only useful when lazily populating a generic environment.
73+
Optional<Type> getMappingIfPresent(GenericParamKey key) const;
6774

6875
/// Make vanilla new/delete illegal.
6976
void *operator new(size_t Bytes) = delete;
@@ -80,9 +87,6 @@ class GenericEnvironment final {
8087
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;
8188

8289
/// Map a generic parameter type to a contextual type.
83-
///
84-
/// This operation will also reabstract dependent types according to the
85-
/// abstraction level of their associated type requirements.
8690
Type mapTypeIntoContext(GenericTypeParamType *type) const;
8791

8892
/// \brief Map the given SIL interface type to a contextual type.

include/swift/AST/GenericParamKey.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//===--- GenericParamKey.h - Key for generic parameters ---------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_AST_GENERICPARAMKEY_H
14+
#define SWIFT_AST_GENERICPARAMKEY_H
15+
16+
#include "llvm/ADT/DenseMapInfo.h"
17+
#include "llvm/ADT/ArrayRef.h"
18+
19+
namespace swift {
20+
21+
class GenericTypeParamDecl;
22+
class GenericTypeParamType;
23+
24+
/// A fully-abstracted generic type parameter key, maintaining only the depth
25+
/// and index of the generic parameter.
26+
struct GenericParamKey {
27+
unsigned Depth : 16;
28+
unsigned Index : 16;
29+
30+
GenericParamKey(unsigned depth, unsigned index)
31+
: Depth(depth), Index(index) { }
32+
33+
GenericParamKey(const GenericTypeParamDecl *d);
34+
GenericParamKey(const GenericTypeParamType *d);
35+
36+
friend bool operator==(GenericParamKey lhs, GenericParamKey rhs) {
37+
return lhs.Depth == rhs.Depth && lhs.Index == rhs.Index;
38+
}
39+
40+
friend bool operator!=(GenericParamKey lhs, GenericParamKey rhs) {
41+
return !(lhs == rhs);
42+
}
43+
44+
friend bool operator<(GenericParamKey lhs, GenericParamKey rhs) {
45+
return lhs.Depth < rhs.Depth ||
46+
(lhs.Depth == rhs.Depth && lhs.Index < rhs.Index);
47+
}
48+
49+
friend bool operator>(GenericParamKey lhs, GenericParamKey rhs) {
50+
return rhs < lhs;
51+
}
52+
53+
friend bool operator<=(GenericParamKey lhs, GenericParamKey rhs) {
54+
return !(rhs < lhs);
55+
}
56+
57+
friend bool operator>=(GenericParamKey lhs, GenericParamKey rhs) {
58+
return !(lhs < rhs);
59+
}
60+
61+
/// Function object type that can be used to provide an ordering of
62+
/// generic type parameter keys with themselves, generic type parameter
63+
/// declarations, and generic type parameter types.
64+
struct Ordering {
65+
bool operator()(GenericParamKey lhs, GenericParamKey rhs) const {
66+
return lhs < rhs;
67+
}
68+
69+
bool operator()(GenericParamKey lhs,
70+
const GenericTypeParamDecl *rhs) const {
71+
return (*this)(lhs, GenericParamKey(rhs));
72+
}
73+
74+
bool operator()(const GenericTypeParamDecl *lhs,
75+
GenericParamKey rhs) const {
76+
return (*this)(GenericParamKey(lhs), rhs);
77+
}
78+
79+
bool operator()(GenericParamKey lhs,
80+
const GenericTypeParamType *rhs) const {
81+
return (*this)(lhs, GenericParamKey(rhs));
82+
}
83+
84+
bool operator()(const GenericTypeParamType *lhs,
85+
GenericParamKey rhs) const {
86+
return (*this)(GenericParamKey(lhs), rhs);
87+
}
88+
};
89+
90+
91+
/// Find the index that this key would have into an array of
92+
/// generic type parameters
93+
unsigned findIndexIn(
94+
llvm::ArrayRef<GenericTypeParamType *> genericParams) const;
95+
};
96+
97+
} // end namespace swift
98+
99+
namespace llvm {
100+
101+
template<>
102+
struct DenseMapInfo<swift::GenericParamKey> {
103+
static inline swift::GenericParamKey getEmptyKey() {
104+
return {0xFFFF, 0xFFFF};
105+
}
106+
static inline swift::GenericParamKey getTombstoneKey() {
107+
return {0xFFFE, 0xFFFE};
108+
}
109+
110+
static inline unsigned getHashValue(swift::GenericParamKey k) {
111+
return DenseMapInfo<unsigned>::getHashValue(k.Depth << 16 | k.Index);
112+
}
113+
static bool isEqual(swift::GenericParamKey a,
114+
swift::GenericParamKey b) {
115+
return a.Depth == b.Depth && a.Index == b.Index;
116+
}
117+
};
118+
119+
} // end namespace llvm
120+
121+
#endif // SWIFT_AST_GENERICPARAMKEY_H

include/swift/AST/TypeAlignments.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace swift {
3434
class DeclContext;
3535
class Expr;
3636
class ExtensionDecl;
37+
class GenericEnvironment;
3738
class GenericTypeParamDecl;
3839
class NormalProtocolConformance;
3940
class OperatorDecl;
@@ -97,6 +98,8 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::Expr, swift::ExprAlignInBits)
9798
LLVM_DECLARE_TYPE_ALIGNMENT(swift::ProtocolConformance, swift::DeclAlignInBits)
9899
LLVM_DECLARE_TYPE_ALIGNMENT(swift::NormalProtocolConformance,
99100
swift::DeclAlignInBits)
101+
LLVM_DECLARE_TYPE_ALIGNMENT(swift::GenericEnvironment,
102+
swift::DeclAlignInBits)
100103

101104
static_assert(llvm::AlignOf<void*>::Alignment >= 2,
102105
"pointer alignment is too small");

0 commit comments

Comments
 (0)