Skip to content

Commit 47049ce

Browse files
authored
Merge pull request #84299 from slavapestov/non-canonical-archetypes
AST: Allow non-canonical opaque archetypes
2 parents 11964e5 + d7726dc commit 47049ce

13 files changed

+110
-114
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ struct OpaqueEnvironmentData {
6161
};
6262

6363
/// Extra data in a generic environment for an opened existential.
64-
struct OpenedExistentialEnvironmentData {
64+
struct ExistentialEnvironmentData {
6565
Type existential;
6666
UUID uuid;
6767
};
6868

6969
/// Extra data in a generic environment for an opened pack element.
70-
struct OpenedElementEnvironmentData {
70+
struct ElementEnvironmentData {
7171
UUID uuid;
7272
CanGenericTypeParamType shapeClass;
7373
};
@@ -85,37 +85,38 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
8585
GenericEnvironment,
8686
SubstitutionMap,
8787
OpaqueEnvironmentData,
88-
OpenedExistentialEnvironmentData,
89-
OpenedElementEnvironmentData,
88+
ExistentialEnvironmentData,
89+
ElementEnvironmentData,
9090
Type> {
9191
public:
92-
enum class Kind {
92+
enum class Kind: uint8_t {
9393
/// A normal generic environment, determined only by its generic
9494
/// signature.
9595
Primary,
9696
/// A generic environment describing an opaque type archetype.
9797
Opaque,
9898
/// A generic environment describing an opened existential archetype.
99-
OpenedExistential,
99+
Existential,
100100
/// A generic environment describing an opened element type of a
101101
/// pack archetype inside a pack expansion expression.
102-
OpenedElement,
102+
Element,
103103
};
104104

105105
class NestedTypeStorage;
106106

107107
private:
108-
mutable llvm::PointerIntPair<GenericSignature, 2, Kind> SignatureAndKind{
109-
GenericSignature(), Kind::Primary};
108+
GenericSignature sig;
110109
NestedTypeStorage *nestedTypeStorage = nullptr;
110+
Kind kind;
111+
bool canonical;
111112

112113
friend TrailingObjects;
113114
friend OpaqueTypeArchetypeType;
114115

115116
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
116117
size_t numTrailingObjects(OverloadToken<OpaqueEnvironmentData>) const;
117-
size_t numTrailingObjects(OverloadToken<OpenedExistentialEnvironmentData>) const;
118-
size_t numTrailingObjects(OverloadToken<OpenedElementEnvironmentData>) const;
118+
size_t numTrailingObjects(OverloadToken<ExistentialEnvironmentData>) const;
119+
size_t numTrailingObjects(OverloadToken<ElementEnvironmentData>) const;
119120
size_t numTrailingObjects(OverloadToken<Type>) const;
120121

121122
/// Retrieve the array containing the context types associated with the
@@ -168,10 +169,13 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
168169

169170
public:
170171
GenericSignature getGenericSignature() const {
171-
return SignatureAndKind.getPointer();
172+
return sig;
172173
}
173174

174-
Kind getKind() const { return SignatureAndKind.getInt(); }
175+
Kind getKind() const { return kind; }
176+
177+
/// Returns if the archetypes from this environment are canonical types.
178+
bool isCanonical() const { return canonical; }
175179

176180
ArrayRef<GenericTypeParamType *> getGenericParams() const;
177181

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ TYPE(DynamicSelf, Type)
176176
ABSTRACT_TYPE(Substitutable, Type)
177177
ABSTRACT_TYPE(Archetype, SubstitutableType)
178178
ALWAYS_CANONICAL_TYPE(PrimaryArchetype, ArchetypeType)
179-
ALWAYS_CANONICAL_TYPE(OpaqueTypeArchetype, ArchetypeType)
179+
TYPE(OpaqueTypeArchetype, ArchetypeType)
180180
ABSTRACT_TYPE(LocalArchetype, ArchetypeType)
181181
ALWAYS_CANONICAL_TYPE(ExistentialArchetype, LocalArchetypeType)
182182
ALWAYS_CANONICAL_TYPE(ElementArchetype, LocalArchetypeType)

include/swift/AST/Types.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7008,7 +7008,7 @@ class ArchetypeType : public SubstitutableType,
70087008
}
70097009
protected:
70107010
ArchetypeType(TypeKind Kind,
7011-
const ASTContext &C,
7011+
const ASTContext *C,
70127012
RecursiveTypeProperties properties,
70137013
Type InterfaceType,
70147014
ArrayRef<ProtocolDecl *> ConformsTo,
@@ -7087,7 +7087,8 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
70877087
}
70887088

70897089
private:
7090-
OpaqueTypeArchetypeType(GenericEnvironment *environment,
7090+
OpaqueTypeArchetypeType(const ASTContext *ctx,
7091+
GenericEnvironment *environment,
70917092
RecursiveTypeProperties properties,
70927093
Type interfaceType,
70937094
ArrayRef<ProtocolDecl*> conformsTo,
@@ -7231,11 +7232,13 @@ class ExistentialArchetypeType final : public LocalArchetypeType,
72317232
}
72327233

72337234
private:
7234-
ExistentialArchetypeType(GenericEnvironment *environment, Type interfaceType,
7235-
ArrayRef<ProtocolDecl *> conformsTo,
7236-
Type superclass,
7237-
LayoutConstraint layout,
7238-
RecursiveTypeProperties properties);
7235+
ExistentialArchetypeType(const ASTContext *ctx,
7236+
GenericEnvironment *environment,
7237+
Type interfaceType,
7238+
ArrayRef<ProtocolDecl *> conformsTo,
7239+
Type superclass,
7240+
LayoutConstraint layout,
7241+
RecursiveTypeProperties properties);
72397242
};
72407243
BEGIN_CAN_TYPE_WRAPPER(ExistentialArchetypeType, LocalArchetypeType)
72417244
END_CAN_TYPE_WRAPPER(ExistentialArchetypeType, LocalArchetypeType)
@@ -7308,7 +7311,7 @@ class ElementArchetypeType final : public LocalArchetypeType,
73087311
}
73097312

73107313
private:
7311-
ElementArchetypeType(const ASTContext &ctx,
7314+
ElementArchetypeType(const ASTContext *ctx,
73127315
GenericEnvironment *environment, Type interfaceType,
73137316
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
73147317
LayoutConstraint layout);

lib/AST/ASTContext.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5731,7 +5731,8 @@ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew(
57315731
ASTContext &ctx = interfaceType->getASTContext();
57325732
auto mem = ctx.Allocate(size, alignof(OpaqueTypeArchetypeType), arena);
57335733
return ::new (mem)
5734-
OpaqueTypeArchetypeType(environment, properties, interfaceType,
5734+
OpaqueTypeArchetypeType(environment->isCanonical() ? &ctx : nullptr,
5735+
environment, properties, interfaceType,
57355736
conformsTo, superclass, layout);
57365737
}
57375738

@@ -5759,6 +5760,7 @@ CanTypeWrapper<ExistentialArchetypeType> ExistentialArchetypeType::getNew(
57595760
void *mem = ctx.Allocate(size, alignof(ExistentialArchetypeType), arena);
57605761

57615762
return CanExistentialArchetypeType(::new (mem) ExistentialArchetypeType(
5763+
environment->isCanonical() ? &ctx : nullptr,
57625764
environment, interfaceType, conformsTo, superclass, layout,
57635765
properties));
57645766
}
@@ -6014,8 +6016,8 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
60146016
unsigned numGenericParams = signature.getGenericParams().size();
60156017
size_t bytes = totalSizeToAlloc<SubstitutionMap,
60166018
OpaqueEnvironmentData,
6017-
OpenedExistentialEnvironmentData,
6018-
OpenedElementEnvironmentData, Type>(
6019+
ExistentialEnvironmentData,
6020+
ElementEnvironmentData, Type>(
60196021
0, 0, 0, 0, numGenericParams);
60206022
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
60216023
return new (mem) GenericEnvironment(signature);
@@ -6025,11 +6027,6 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
60256027
/// outer substitutions.
60266028
GenericEnvironment *GenericEnvironment::forOpaqueType(
60276029
OpaqueTypeDecl *opaque, SubstitutionMap subs) {
6028-
// TODO: We could attempt to preserve type sugar in the substitution map.
6029-
// Currently archetypes are assumed to be always canonical in many places,
6030-
// though, so doing so would require fixing those places.
6031-
subs = subs.getCanonical();
6032-
60336030
auto &ctx = opaque->getASTContext();
60346031

60356032
auto properties = ArchetypeType::archetypeProperties(
@@ -6044,9 +6041,9 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
60446041
auto signature = opaque->getOpaqueInterfaceGenericSignature();
60456042
unsigned numGenericParams = signature.getGenericParams().size();
60466043
size_t bytes = totalSizeToAlloc<SubstitutionMap,
6047-
OpaqueEnvironmentData,
6048-
OpenedExistentialEnvironmentData,
6049-
OpenedElementEnvironmentData, Type>(
6044+
OpaqueEnvironmentData,
6045+
ExistentialEnvironmentData,
6046+
ElementEnvironmentData, Type>(
60506047
1, 1, 0, 0, numGenericParams);
60516048
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
60526049
env = new (mem) GenericEnvironment(signature, opaque, subs);
@@ -6108,8 +6105,8 @@ GenericEnvironment::forOpenedExistential(
61086105
unsigned numGenericParams = signature.getGenericParams().size();
61096106
size_t bytes = totalSizeToAlloc<SubstitutionMap,
61106107
OpaqueEnvironmentData,
6111-
OpenedExistentialEnvironmentData,
6112-
OpenedElementEnvironmentData, Type>(
6108+
ExistentialEnvironmentData,
6109+
ElementEnvironmentData, Type>(
61136110
1, 0, 1, 0, numGenericParams);
61146111
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
61156112
auto *genericEnv =
@@ -6146,8 +6143,8 @@ GenericEnvironment::forOpenedElement(GenericSignature signature,
61466143
unsigned numOpenedParams = signature.getInnermostGenericParams().size();
61476144
size_t bytes = totalSizeToAlloc<SubstitutionMap,
61486145
OpaqueEnvironmentData,
6149-
OpenedExistentialEnvironmentData,
6150-
OpenedElementEnvironmentData,
6146+
ExistentialEnvironmentData,
6147+
ElementEnvironmentData,
61516148
Type>(
61526149
1, 0, 0, 1, numGenericParams + numOpenedParams);
61536150
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3634,16 +3634,6 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
36343634

36353635
if (ShouldPrint) {
36363636
Printer << " = ";
3637-
// FIXME: An inferred associated type witness type alias may reference
3638-
// an opaque type, but OpaqueTypeArchetypes are always canonicalized
3639-
// so lose type sugar for generic params. Bind the generic signature so
3640-
// we can map params back into the generic signature and print them
3641-
// correctly.
3642-
//
3643-
// Remove this when we have a way to represent non-canonical archetypes
3644-
// preserving sugar.
3645-
PrintOptions::OverrideScope scope(Options);
3646-
OVERRIDE_PRINT_OPTION(scope, GenericSig, decl->getGenericSignature().getPointer());
36473637
printTypeLoc(TypeLoc(decl->getUnderlyingTypeRepr(), Ty));
36483638
printDeclGenericRequirements(decl);
36493639
}
@@ -7500,11 +7490,6 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
75007490
if (auto existential = constraint->getAs<ExistentialType>())
75017491
constraint = existential->getConstraintType();
75027492

7503-
// Opaque archetype substitutions are always canonical, so re-sugar the
7504-
// constraint type using the owning declaration's generic parameter names.
7505-
if (genericSig)
7506-
constraint = genericSig->getSugaredType(constraint);
7507-
75087493
visit(constraint);
75097494
return;
75107495
}

lib/AST/CaptureInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ CaptureInfo::CaptureInfo(ASTContext &ctx, ArrayRef<CapturedValue> captures,
7777
// This is the only kind of local generic environment we can capture right now.
7878
#ifndef NDEBUG
7979
for (auto *env : genericEnv) {
80-
assert(env->getKind() == GenericEnvironment::Kind::OpenedElement);
80+
assert(env->getKind() == GenericEnvironment::Kind::Element);
8181
}
8282
#endif
8383

0 commit comments

Comments
 (0)