Skip to content

Commit f63dff1

Browse files
committed
AST: Don't allow @_transparent on extensions
Quiz: What does @_transparent on an extension actually *do*? 1) Make all members @_transparent? 2) Allow your members to be @_transparent? 3) Some other magical effect that has nothing to do with members? The correct answer is 1), however a few places in the stdlib defined a @_transparent extension and then proceeded to make some or all members also @_transparent, and in a couple of places we defined a @_transparent extension with no members at all. To avoid cargo culting and confusion, remove the ability to make @_transparent extensions altogether, and force usages to be explicit.
1 parent f9d9dcf commit f63dff1

File tree

13 files changed

+95
-54
lines changed

13 files changed

+95
-54
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ SIMPLE_DECL_ATTR(prefix , Prefix , OnFunc | OnOperator | DeclModifier, 24)
152152
SIMPLE_DECL_ATTR(postfix, Postfix, OnFunc | OnOperator | DeclModifier, 25)
153153

154154
SIMPLE_DECL_ATTR(_transparent, Transparent,
155-
OnFunc|OnConstructor|OnVar|OnExtension|UserInaccessible, 26)
155+
OnFunc|OnConstructor|OnVar|UserInaccessible, 26)
156156
SIMPLE_DECL_ATTR(requires_stored_property_inits, RequiresStoredPropertyInits,
157157
OnClass, 27)
158158
DECL_ATTR(autoclosure, AutoClosure, OnParam, 28)

include/swift/AST/Decl.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,6 @@ class alignas(1 << DeclAlignInBits) Decl {
733733

734734
bool walk(ASTWalker &walker);
735735

736-
/// \brief Should this declaration be treated as if annotated with transparent
737-
/// attribute.
738-
bool isTransparent() const;
739-
740736
/// \brief Return whether this declaration has been determined invalid.
741737
bool isInvalid() const { return DeclBits.Invalid; }
742738

@@ -3784,6 +3780,10 @@ class AbstractStorageDecl : public ValueDecl {
37843780
}
37853781
public:
37863782

3783+
/// \brief Should this declaration be treated as if annotated with transparent
3784+
/// attribute.
3785+
bool isTransparent() const;
3786+
37873787
/// \brief Determine whether this storage is a static member, if it
37883788
/// is a member. Currently only variables can be static.
37893789
inline bool isStatic() const; // defined in this header
@@ -4595,8 +4595,13 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
45954595
}
45964596

45974597
void setGenericParams(GenericParamList *GenericParams);
4598-
4598+
45994599
public:
4600+
4601+
/// \brief Should this declaration be treated as if annotated with transparent
4602+
/// attribute.
4603+
bool isTransparent() const;
4604+
46004605
void setGenericSignature(GenericSignature *GenericSig) {
46014606
assert(!this->GenericSig && "already have signature?");
46024607
this->GenericSig = GenericSig;

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,8 +930,6 @@ ERROR(static_functions_not_mutating,none,
930930

931931
ERROR(transparent_stored_property,none,
932932
"@_transparent cannot be applied to stored properties", ())
933-
ERROR(transparent_on_invalid_extension,none,
934-
"@_transparent is only supported on struct and enum extensions", ())
935933
ERROR(transparent_in_protocols_not_supported,none,
936934
"@_transparent is not supported on declarations within protocols", ())
937935
ERROR(transparent_in_classes_not_supported,none,

lib/AST/Decl.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,19 +348,15 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getLoc();
348348
llvm_unreachable("Unknown decl kind");
349349
}
350350

351-
bool Decl::isTransparent() const {
351+
bool AbstractStorageDecl::isTransparent() const {
352+
return getAttrs().hasAttribute<TransparentAttr>();
353+
}
354+
355+
bool AbstractFunctionDecl::isTransparent() const {
352356
// Check if the declaration had the attribute.
353357
if (getAttrs().hasAttribute<TransparentAttr>())
354358
return true;
355359

356-
// Check if this is a function declaration which is within a transparent
357-
// extension.
358-
if (const AbstractFunctionDecl *FD = dyn_cast<AbstractFunctionDecl>(this)) {
359-
if (const ExtensionDecl *ED = dyn_cast<ExtensionDecl>(FD->getParent()))
360-
if (ED->isTransparent())
361-
return true;
362-
}
363-
364360
// If this is an accessor, check if the transparent attribute was set
365361
// on the value decl.
366362
if (const FuncDecl *FD = dyn_cast<FuncDecl>(this)) {

lib/SIL/SILDeclRef.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,15 @@ bool SILDeclRef::isTransparent() const {
482482
if (hasAutoClosureExpr())
483483
return true;
484484

485-
return hasDecl() ? getDecl()->isTransparent() : false;
485+
if (hasDecl()) {
486+
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(getDecl()))
487+
return AFD->isTransparent();
488+
489+
if (auto *ASD = dyn_cast<AbstractStorageDecl>(getDecl()))
490+
return ASD->isTransparent();
491+
}
492+
493+
return false;
486494
}
487495

488496
/// \brief True if the function should have its body serialized.

lib/Sema/TypeCheckAttr.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,15 +219,6 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
219219
} // end anonymous namespace
220220

221221
void AttributeEarlyChecker::visitTransparentAttr(TransparentAttr *attr) {
222-
if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
223-
CanType ExtendedTy = ED->getExtendedType()->getCanonicalType();
224-
const NominalTypeDecl *ExtendedNominal = ExtendedTy->getAnyNominal();
225-
// Only Struct and Enum extensions can be transparent.
226-
if (!isa<StructDecl>(ExtendedNominal) && !isa<EnumDecl>(ExtendedNominal))
227-
return diagnoseAndRemoveAttr(attr,diag::transparent_on_invalid_extension);
228-
return;
229-
}
230-
231222
DeclContext *Ctx = D->getDeclContext();
232223
// Protocol declarations cannot be transparent.
233224
if (isa<ProtocolDecl>(Ctx))

0 commit comments

Comments
 (0)