Skip to content

Commit 0013b19

Browse files
committed
[AST] TypeWrappers: Always allow attributes that come from swiftinterfaces
Since type wrapper attributes could be applied to protocols and the protocol types could be used as existential values, it's not always possible to wrap all uses of feature into `#if $TypeWrappers` block so let's allow use of attributes if they come from a Swift interface file.
1 parent e9d1d30 commit 0013b19

File tree

5 files changed

+11
-84
lines changed

5 files changed

+11
-84
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3762,23 +3762,6 @@ class GetTypeWrapperInitializer
37623762
bool isCached() const { return true; }
37633763
};
37643764

3765-
/// Check whether this is a protocol that has a type wrapper attribute
3766-
/// or one of its dependencies does.
3767-
class UsesTypeWrapperFeature
3768-
: public SimpleRequest<UsesTypeWrapperFeature, bool(NominalTypeDecl *),
3769-
RequestFlags::Cached> {
3770-
public:
3771-
using SimpleRequest::SimpleRequest;
3772-
3773-
private:
3774-
friend SimpleRequest;
3775-
3776-
bool evaluate(Evaluator &evaluator, NominalTypeDecl *) const;
3777-
3778-
public:
3779-
bool isCached() const { return true; }
3780-
};
3781-
37823765
/// Find the definition of a given macro.
37833766
class MacroDefinitionRequest
37843767
: public SimpleRequest<MacroDefinitionRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,6 @@ 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)
449446
SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
450447
MacroDefinition(MacroDecl *),
451448
Cached, NoLocationInfo)

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,19 +2949,7 @@ static bool usesFeatureSpecializeAttributeWithAvailability(Decl *decl) {
29492949
}
29502950

29512951
static bool usesFeatureTypeWrappers(Decl *decl) {
2952-
NullablePtr<NominalTypeDecl> typeDecl;
2953-
2954-
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
2955-
typeDecl = extension->getExtendedNominal();
2956-
} else {
2957-
typeDecl = dyn_cast<NominalTypeDecl>(decl);
2958-
}
2959-
2960-
if (!typeDecl)
2961-
return false;
2962-
2963-
return evaluateOrDefault(decl->getASTContext().evaluator,
2964-
UsesTypeWrapperFeature{typeDecl.get()}, false);
2952+
return false;
29652953
}
29662954

29672955
static bool usesFeatureRuntimeDiscoverableAttrs(Decl *decl) {

lib/AST/TypeWrapper.cpp

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -44,53 +44,3 @@ bool VarDecl::isTypeWrapperLocalStorageForInitializer() const {
4444
}
4545
return false;
4646
}
47-
48-
bool UsesTypeWrapperFeature::evaluate(Evaluator &evaluator,
49-
NominalTypeDecl *decl) const {
50-
// This is a type wrapper type.
51-
if (decl->getAttrs().hasAttribute<TypeWrapperAttr>())
52-
return true;
53-
54-
// This is a type wrapped type.
55-
if (decl->hasTypeWrapper())
56-
return true;
57-
58-
// This type could be depending on a type wrapper feature
59-
// indirectly by conforming to a protocol with a type
60-
// wrapper attribute. To determine that we need to walk
61-
// protocol dependency chains and check each one.
62-
63-
auto &ctx = decl->getASTContext();
64-
65-
auto usesTypeWrapperFeature = [&](ProtocolDecl *protocol) {
66-
return evaluateOrDefault(ctx.evaluator, UsesTypeWrapperFeature{protocol},
67-
false);
68-
};
69-
70-
for (unsigned i : indices(decl->getInherited())) {
71-
auto inheritedType = evaluateOrDefault(
72-
ctx.evaluator,
73-
InheritedTypeRequest{decl, i, TypeResolutionStage::Interface}, Type());
74-
75-
if (!(inheritedType && inheritedType->isConstraintType()))
76-
continue;
77-
78-
if (auto *protocol =
79-
dyn_cast_or_null<ProtocolDecl>(inheritedType->getAnyNominal())) {
80-
if (usesTypeWrapperFeature(protocol))
81-
return true;
82-
}
83-
84-
if (auto composition = inheritedType->getAs<ProtocolCompositionType>()) {
85-
for (auto member : composition->getMembers()) {
86-
if (auto *protocol =
87-
dyn_cast_or_null<ProtocolDecl>(member->getAnyNominal())) {
88-
if (usesTypeWrapperFeature(protocol))
89-
return true;
90-
}
91-
}
92-
}
93-
}
94-
95-
return false;
96-
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3826,7 +3826,16 @@ void AttributeChecker::visitPropertyWrapperAttr(PropertyWrapperAttr *attr) {
38263826
}
38273827

38283828
void AttributeChecker::visitTypeWrapperAttr(TypeWrapperAttr *attr) {
3829-
if (!Ctx.LangOpts.hasFeature(Feature::TypeWrappers)) {
3829+
auto isEnabled = [&]() {
3830+
if (Ctx.LangOpts.hasFeature(Feature::TypeWrappers))
3831+
return true;
3832+
3833+
// Accept attributes that come from swiftinterface files.
3834+
auto *parentSF = D->getDeclContext()->getParentSourceFile();
3835+
return parentSF && parentSF->Kind == SourceFileKind::Interface;
3836+
};
3837+
3838+
if (!isEnabled()) {
38303839
diagnose(attr->getLocation(), diag::type_wrappers_are_experimental);
38313840
attr->setInvalid();
38323841
return;

0 commit comments

Comments
 (0)