Skip to content

Commit fa62cf3

Browse files
committed
[ASTPrinter] Expand type wrapper feature coverage
`usesFeatureTypeWrappers` should return `true` for all of the declarations that use the feature directly or indirectly e.g. type wrapper types, type wrapped types, and types with conformance to a type wrapped protocol (with or without wrapper attribute inference).
1 parent acc4621 commit fa62cf3

File tree

6 files changed

+113
-7
lines changed

6 files changed

+113
-7
lines changed

Diff for: include/swift/AST/TypeCheckRequests.h

+17
Original file line numberDiff line numberDiff line change
@@ -3752,6 +3752,23 @@ class GetTypeWrapperInitializer
37523752
bool isCached() const { return true; }
37533753
};
37543754

3755+
/// Check whether this is a protocol that has a type wrapper attribute
3756+
/// or one of its dependencies does.
3757+
class UsesTypeWrapperFeature
3758+
: public SimpleRequest<UsesTypeWrapperFeature, bool(NominalTypeDecl *),
3759+
RequestFlags::Cached> {
3760+
public:
3761+
using SimpleRequest::SimpleRequest;
3762+
3763+
private:
3764+
friend SimpleRequest;
3765+
3766+
bool evaluate(Evaluator &evaluator, NominalTypeDecl *) const;
3767+
3768+
public:
3769+
bool isCached() const { return true; }
3770+
};
3771+
37553772
/// Find the definition of a given macro.
37563773
class MacroDefinitionRequest
37573774
: public SimpleRequest<MacroDefinitionRequest,

Diff for: include/swift/AST/TypeCheckerTypeIDZone.def

+3
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ SWIFT_REQUEST(TypeChecker, ContinueTargetRequest,
443443
SWIFT_REQUEST(TypeChecker, GetTypeWrapperInitializer,
444444
ConstructorDecl *(NominalTypeDecl *),
445445
Cached, NoLocationInfo)
446+
SWIFT_REQUEST(TypeChecker, UsesTypeWrapperFeature,
447+
bool(NominalTypeDecl *),
448+
Cached, NoLocationInfo)
446449
SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
447450
MacroDefinition(MacroDecl *),
448451
Cached, NoLocationInfo)

Diff for: lib/AST/ASTPrinter.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "swift/AST/ProtocolConformance.h"
3838
#include "swift/AST/SILLayout.h"
3939
#include "swift/AST/Stmt.h"
40+
#include "swift/AST/TypeCheckRequests.h"
4041
#include "swift/AST/TypeVisitor.h"
4142
#include "swift/AST/TypeWalker.h"
4243
#include "swift/AST/Types.h"
@@ -2935,7 +2936,19 @@ static bool usesFeatureSpecializeAttributeWithAvailability(Decl *decl) {
29352936
}
29362937

29372938
static bool usesFeatureTypeWrappers(Decl *decl) {
2938-
return decl->getAttrs().hasAttribute<TypeWrapperAttr>();
2939+
NullablePtr<NominalTypeDecl> typeDecl;
2940+
2941+
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
2942+
typeDecl = extension->getExtendedNominal();
2943+
} else {
2944+
typeDecl = dyn_cast<NominalTypeDecl>(decl);
2945+
}
2946+
2947+
if (!typeDecl)
2948+
return false;
2949+
2950+
return evaluateOrDefault(decl->getASTContext().evaluator,
2951+
UsesTypeWrapperFeature{typeDecl.get()}, false);
29392952
}
29402953

29412954
static bool usesFeatureRuntimeDiscoverableAttrs(Decl *decl) {

Diff for: lib/AST/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ add_swift_host_library(swiftAST STATIC
116116
TypeRefinementContext.cpp
117117
TypeRepr.cpp
118118
TypeWalker.cpp
119+
TypeWrapper.cpp
119120
UnqualifiedLookup.cpp
120121
USRGeneration.cpp
121122

Diff for: lib/AST/TypeWrapper.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===--- TypeWrapper.cpp - Type Traversal ---------------------------------===//
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 implements functionality related to type wrapper feature.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#include "swift/AST/ASTContext.h"
18+
#include "swift/AST/Decl.h"
19+
#include "swift/AST/TypeCheckRequests.h"
20+
#include "swift/AST/TypeResolutionStage.h"
21+
22+
using namespace swift;
23+
24+
NominalTypeDecl *NominalTypeDecl::getTypeWrapper() const {
25+
auto *mutableSelf = const_cast<NominalTypeDecl *>(this);
26+
return evaluateOrDefault(getASTContext().evaluator,
27+
GetTypeWrapper{mutableSelf}, nullptr);
28+
}
29+
30+
bool UsesTypeWrapperFeature::evaluate(Evaluator &evaluator,
31+
NominalTypeDecl *decl) const {
32+
// This is a type wrapper type.
33+
if (decl->getAttrs().hasAttribute<TypeWrapperAttr>())
34+
return true;
35+
36+
// This is a type wrapped type.
37+
if (decl->hasTypeWrapper())
38+
return true;
39+
40+
// This type could be depending on a type wrapper feature
41+
// indirectly by conforming to a protocol with a type
42+
// wrapper attribute. To determine that we need to walk
43+
// protocol dependency chains and check each one.
44+
45+
auto &ctx = decl->getASTContext();
46+
47+
auto usesTypeWrapperFeature = [&](ProtocolDecl *protocol) {
48+
return evaluateOrDefault(ctx.evaluator, UsesTypeWrapperFeature{protocol},
49+
false);
50+
};
51+
52+
for (unsigned i : indices(decl->getInherited())) {
53+
auto inheritedType = evaluateOrDefault(
54+
ctx.evaluator,
55+
InheritedTypeRequest{decl, i, TypeResolutionStage::Interface}, Type());
56+
57+
if (!(inheritedType && inheritedType->isConstraintType()))
58+
continue;
59+
60+
if (auto *protocol =
61+
dyn_cast_or_null<ProtocolDecl>(inheritedType->getAnyNominal())) {
62+
if (usesTypeWrapperFeature(protocol))
63+
return true;
64+
}
65+
66+
if (auto composition = inheritedType->getAs<ProtocolCompositionType>()) {
67+
for (auto member : composition->getMembers()) {
68+
if (auto *protocol =
69+
dyn_cast_or_null<ProtocolDecl>(member->getAnyNominal())) {
70+
if (usesTypeWrapperFeature(protocol))
71+
return true;
72+
}
73+
}
74+
}
75+
}
76+
77+
return false;
78+
}

Diff for: lib/Sema/TypeCheckTypeWrapper.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,6 @@ VarDecl *VarDecl::getUnderlyingTypeWrapperStorage() const {
7777
nullptr);
7878
}
7979

80-
NominalTypeDecl *NominalTypeDecl::getTypeWrapper() const {
81-
auto *mutableSelf = const_cast<NominalTypeDecl *>(this);
82-
return evaluateOrDefault(getASTContext().evaluator,
83-
GetTypeWrapper{mutableSelf}, nullptr);
84-
}
85-
8680
struct TypeWrapperAttrInfo {
8781
CustomAttr *Attr;
8882
NominalTypeDecl *Wrapper;

0 commit comments

Comments
 (0)