Skip to content

Commit 2ce48e0

Browse files
committed
[AST/Sema] TypeWrappers: Augment GetTypeWrapper request to produce more info
The request is updated to return attribute, wrapper declaration, the declaration its attached to and whether or not it has been inferred (opposite to being declared directly).
1 parent 7782851 commit 2ce48e0

File tree

8 files changed

+80
-40
lines changed

8 files changed

+80
-40
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "swift/AST/StorageImpl.h"
3636
#include "swift/AST/TypeAlignments.h"
3737
#include "swift/AST/TypeWalker.h"
38+
#include "swift/AST/TypeWrappers.h"
3839
#include "swift/AST/Types.h"
3940
#include "swift/Basic/ArrayRefView.h"
4041
#include "swift/Basic/Compiler.h"
@@ -3903,7 +3904,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
39033904
bool hasTypeWrapper() const { return bool(getTypeWrapper()); }
39043905

39053906
/// Return a type wrapper (if any) associated with this type.
3906-
NominalTypeDecl *getTypeWrapper() const;
3907+
Optional<TypeWrapperInfo> getTypeWrapper() const;
39073908

39083909
/// If this declaration has a type wrapper return a property that
39093910
/// is used for all type wrapper related operations (mainly for

include/swift/AST/TypeCheckRequests.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct TypeWitnessAndDecl;
6464
class ValueDecl;
6565
enum class OpaqueReadOwnership: uint8_t;
6666
class StorageImplInfo;
67+
struct TypeWrapperInfo;
6768

6869
/// Display a nominal type or extension thereof.
6970
void simple_display(
@@ -3522,15 +3523,17 @@ class GetSourceFileAsyncNode
35223523

35233524
/// Return a type wrapper (if any) associated with the given declaration.
35243525
class GetTypeWrapper
3525-
: public SimpleRequest<GetTypeWrapper, NominalTypeDecl *(NominalTypeDecl *),
3526+
: public SimpleRequest<GetTypeWrapper,
3527+
Optional<TypeWrapperInfo>(NominalTypeDecl *),
35263528
RequestFlags::Cached> {
35273529
public:
35283530
using SimpleRequest::SimpleRequest;
35293531

35303532
private:
35313533
friend SimpleRequest;
35323534

3533-
NominalTypeDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *) const;
3535+
Optional<TypeWrapperInfo> evaluate(Evaluator &evaluator,
3536+
NominalTypeDecl *) const;
35343537

35353538
public:
35363539
bool isCached() const { return true; }

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ SWIFT_REQUEST(TypeChecker, GetSourceFileAsyncNode,
402402
AwaitExpr *(const SourceFile *),
403403
Cached, NoLocationInfo)
404404
SWIFT_REQUEST(TypeChecker, GetTypeWrapper,
405-
NominalTypeDecl *(NominalTypeDecl *),
405+
Optional<TypeWrapperInfo>(NominalTypeDecl *),
406406
Cached, NoLocationInfo)
407407
SWIFT_REQUEST(TypeChecker, GetTypeWrapperType,
408408
Type(NominalTypeDecl *),

include/swift/AST/TypeWrappers.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===--------- TypeWrappers.h - Type Wrapper ASTs ---------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 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+
// This file defines helper types for type wrappers.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_TYPE_WRAPPERS_H
18+
#define SWIFT_AST_TYPE_WRAPPERS_H
19+
20+
namespace swift {
21+
22+
struct TypeWrapperInfo {
23+
CustomAttr *Attr;
24+
NominalTypeDecl *Wrapper;
25+
NominalTypeDecl *AttachedTo;
26+
bool IsInferred;
27+
28+
TypeWrapperInfo(CustomAttr *attr, NominalTypeDecl *wrapperDecl,
29+
NominalTypeDecl *attachedTo, bool isInferred)
30+
: Attr(attr), Wrapper(wrapperDecl), AttachedTo(attachedTo),
31+
IsInferred(isInferred) {}
32+
33+
TypeWrapperInfo asInferred() const {
34+
return {Attr, Wrapper, AttachedTo, true};
35+
}
36+
};
37+
38+
} // end namespace swift
39+
40+
#endif // SWIFT_AST_TYPE_WRAPPERS_H

lib/AST/TypeWrapper.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
#include "swift/AST/Decl.h"
1919
#include "swift/AST/TypeCheckRequests.h"
2020
#include "swift/AST/TypeResolutionStage.h"
21+
#include "swift/AST/TypeWrappers.h"
2122

2223
using namespace swift;
2324

24-
NominalTypeDecl *NominalTypeDecl::getTypeWrapper() const {
25+
Optional<TypeWrapperInfo> NominalTypeDecl::getTypeWrapper() const {
2526
auto *mutableSelf = const_cast<NominalTypeDecl *>(this);
2627
return evaluateOrDefault(getASTContext().evaluator,
27-
GetTypeWrapper{mutableSelf}, nullptr);
28+
GetTypeWrapper{mutableSelf},
29+
Optional<TypeWrapperInfo>());
2830
}
2931

3032
VarDecl *ConstructorDecl::getLocalTypeWrapperStorageVar() const {

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,9 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
12571257
{
12581258
bool isClass = isa<ClassDecl>(parentType);
12591259

1260-
auto typeWrapper = parentType->getTypeWrapper();
1261-
auto *typeWrapperInit = typeWrapper->getTypeWrapperInitializer();
1260+
auto typeWrapperInfo = parentType->getTypeWrapper();
1261+
auto *typeWrapperInit =
1262+
typeWrapperInfo->Wrapper->getTypeWrapperInitializer();
12621263
SILValue typeWrapperInitRef = createInitRef(typeWrapperInit);
12631264

12641265
auto *self = TheMemory.findUninitializedSelfValue();

lib/Sema/CodeSynthesis.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,10 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
364364
} else if (ICK == ImplicitConstructorKind::TypeWrapperStorage) {
365365
accessLevel = AccessLevel::Public;
366366

367-
auto *typeWrapper = decl->getTypeWrapper();
367+
auto typeWrapperInfo = decl->getTypeWrapper();
368+
assert(typeWrapperInfo);
369+
370+
auto *typeWrapper = typeWrapperInfo->Wrapper;
368371

369372
auto *arg = new (ctx) ParamDecl(SourceLoc(), Loc, ctx.Id_storageWrapper,
370373
Loc, ctx.Id_storageWrapper, decl);

lib/Sema/TypeCheckTypeWrapper.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/Pattern.h"
2121
#include "swift/AST/Stmt.h"
2222
#include "swift/AST/TypeCheckRequests.h"
23+
#include "swift/AST/TypeWrappers.h"
2324
#include "swift/Basic/LLVM.h"
2425
#include "swift/Basic/SourceLoc.h"
2526

@@ -77,12 +78,6 @@ VarDecl *VarDecl::getUnderlyingTypeWrapperStorage() const {
7778
nullptr);
7879
}
7980

80-
struct TypeWrapperAttrInfo {
81-
CustomAttr *Attr;
82-
NominalTypeDecl *Wrapper;
83-
NominalTypeDecl *AttachedTo;
84-
};
85-
8681
static void
8782
getDeclaredProtocolConformances(NominalTypeDecl *decl,
8883
SmallVectorImpl<ProtocolDecl *> &protocols) {
@@ -110,9 +105,8 @@ getDeclaredProtocolConformances(NominalTypeDecl *decl,
110105
}
111106
}
112107

113-
static void
114-
getTypeWrappers(NominalTypeDecl *decl,
115-
SmallVectorImpl<TypeWrapperAttrInfo> &typeWrappers) {
108+
static void getTypeWrappers(NominalTypeDecl *decl,
109+
SmallVectorImpl<TypeWrapperInfo> &typeWrappers) {
116110
auto &ctx = decl->getASTContext();
117111

118112
// Attributes applied directly to the type.
@@ -126,7 +120,8 @@ getTypeWrappers(NominalTypeDecl *decl,
126120

127121
auto *typeWrapper = nominal->getAttrs().getAttribute<TypeWrapperAttr>();
128122
if (typeWrapper && typeWrapper->isValid())
129-
typeWrappers.push_back({mutableAttr, nominal, decl});
123+
typeWrappers.push_back(
124+
{mutableAttr, nominal, decl, /*isInferred=*/false});
130125
}
131126

132127
// Do not allow transitive protocol inference between protocols.
@@ -139,33 +134,33 @@ getTypeWrappers(NominalTypeDecl *decl,
139134
getDeclaredProtocolConformances(decl, protocols);
140135

141136
for (auto *protocol : protocols) {
142-
SmallVector<TypeWrapperAttrInfo, 2> inferredAttrs;
137+
SmallVector<TypeWrapperInfo, 2> inferredAttrs;
143138
getTypeWrappers(protocol, inferredAttrs);
144139

145140
// De-duplicate inferred type wrappers. This also makes sure
146141
// that if both protocol and conforming type explicitly declare
147142
// the same type wrapper there is no clash between them.
148143
for (const auto &inferredAttr : inferredAttrs) {
149-
if (llvm::find_if(typeWrappers, [&](const TypeWrapperAttrInfo &attr) {
144+
if (llvm::find_if(typeWrappers, [&](const TypeWrapperInfo &attr) {
150145
return attr.Wrapper == inferredAttr.Wrapper;
151146
}) == typeWrappers.end())
152-
typeWrappers.push_back(inferredAttr);
147+
typeWrappers.push_back(inferredAttr.asInferred());
153148
}
154149
}
155150
}
156151

157-
NominalTypeDecl *GetTypeWrapper::evaluate(Evaluator &evaluator,
158-
NominalTypeDecl *decl) const {
152+
Optional<TypeWrapperInfo>
153+
GetTypeWrapper::evaluate(Evaluator &evaluator, NominalTypeDecl *decl) const {
159154
auto &ctx = decl->getASTContext();
160155

161156
// Note that we don't actually care whether there are duplicates,
162157
// using the same type wrapper multiple times is still an error.
163-
SmallVector<TypeWrapperAttrInfo, 2> typeWrappers;
158+
SmallVector<TypeWrapperInfo, 2> typeWrappers;
164159

165160
getTypeWrappers(decl, typeWrappers);
166161

167162
if (typeWrappers.empty())
168-
return nullptr;
163+
return None;
169164

170165
if (typeWrappers.size() != 1) {
171166
ctx.Diags.diagnose(decl, diag::cannot_use_multiple_type_wrappers,
@@ -183,25 +178,21 @@ NominalTypeDecl *GetTypeWrapper::evaluate(Evaluator &evaluator,
183178
}
184179
}
185180

186-
return nullptr;
181+
return None;
187182
}
188183

189-
return typeWrappers.front().Wrapper;
184+
return typeWrappers.front();
190185
}
191186

192187
Type GetTypeWrapperType::evaluate(Evaluator &evaluator,
193188
NominalTypeDecl *decl) const {
194-
SmallVector<TypeWrapperAttrInfo, 2> typeWrappers;
195-
196-
getTypeWrappers(decl, typeWrappers);
197-
198-
if (typeWrappers.size() != 1)
189+
auto typeWrapperInfo = decl->getTypeWrapper();
190+
if (!typeWrapperInfo)
199191
return Type();
200192

201-
auto *typeWrapperAttr = typeWrappers.front().Attr;
202193
auto type = evaluateOrDefault(
203194
evaluator,
204-
CustomAttrTypeRequest{typeWrapperAttr, decl->getDeclContext(),
195+
CustomAttrTypeRequest{typeWrapperInfo->Attr, decl->getDeclContext(),
205196
CustomAttrTypeKind::TypeWrapper},
206197
Type());
207198

@@ -325,7 +316,7 @@ GetTypeWrapperProperty::evaluate(Evaluator &evaluator,
325316
NominalTypeDecl *parent) const {
326317
auto &ctx = parent->getASTContext();
327318

328-
auto *typeWrapper = parent->getTypeWrapper();
319+
auto typeWrapper = parent->getTypeWrapper();
329320
if (!typeWrapper)
330321
return nullptr;
331322

@@ -339,10 +330,9 @@ GetTypeWrapperProperty::evaluate(Evaluator &evaluator,
339330

340331
// $storage: Wrapper<<ParentType>, <ParentType>.$Storage>
341332
auto propertyTy = BoundGenericType::get(
342-
typeWrapper, /*Parent=*/typeWrapperType->getParent(),
333+
typeWrapper->Wrapper, /*Parent=*/typeWrapperType->getParent(),
343334
/*genericArgs=*/
344-
{parent->getSelfInterfaceType(),
345-
storage->getDeclaredInterfaceType()});
335+
{parent->getSelfInterfaceType(), storage->getDeclaredInterfaceType()});
346336

347337
return injectProperty(parent, ctx.Id_TypeWrapperProperty, propertyTy,
348338
VarDecl::Introducer::Var,
@@ -426,7 +416,7 @@ static SubscriptExpr *subscriptTypeWrappedProperty(VarDecl *var,
426416
ctx, DeclBaseName::createSubscript(),
427417
{ctx.Id_wrappedSelf, ctx.Id_propertyKeyPath, ctx.Id_storageKeyPath});
428418

429-
auto *typeWrapper = parent->getTypeWrapper();
419+
auto *typeWrapper = parent->getTypeWrapper()->Wrapper;
430420
auto candidates = typeWrapper->lookupDirect(subscriptName);
431421

432422
if (!candidates.empty()) {

0 commit comments

Comments
 (0)