Skip to content

Attribute @_implements & deriving enum equality not-named == #8735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ SIMPLE_DECL_ATTR(discardableResult, DiscardableResult,

SIMPLE_DECL_ATTR(GKInspectable, GKInspectable, OnVar, 66)

DECL_ATTR(_implements, Implements,
OnFunc | OnVar | OnSubscript | OnTypeAlias
| NotSerialized | UserInaccessible,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the intent is for these declarations to be invisible to normal name lookup (is that the intent?) or hide it from code completion, then you'll probably need to serialize the attribute.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attribute isn't what triggers either of those things, so we're okay.

/* Not serialized */ 67)

#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
#undef SIMPLE_DECL_ATTR
Expand Down
33 changes: 32 additions & 1 deletion include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
#include "swift/AST/Identifier.h"
#include "swift/AST/AttrKind.h"
#include "swift/AST/ConcreteDeclRef.h"
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/KnownProtocols.h"
#include "swift/AST/Ownership.h"
#include "swift/AST/PlatformKind.h"
#include "swift/AST/Requirement.h"
#include "swift/AST/TypeLoc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
Expand All @@ -43,7 +45,6 @@ class Decl;
class ClassDecl;
class GenericFunctionType;
class TrailingWhereClause;
struct TypeLoc;

/// TypeAttributes - These are attributes that may be applied to types.
class TypeAttributes {
Expand Down Expand Up @@ -1127,6 +1128,36 @@ class SpecializeAttr : public DeclAttribute {
}
};

/// The @_implements attribute, which treats a decl as the implementation for
/// some named protocol requirement (but otherwise not-visible by that name).
class ImplementsAttr : public DeclAttribute {

TypeLoc ProtocolType;
DeclName MemberName;
DeclNameLoc MemberNameLoc;

public:
ImplementsAttr(SourceLoc atLoc, SourceRange Range,
TypeLoc ProtocolType,
DeclName MemberName,
DeclNameLoc MemberNameLoc);

static ImplementsAttr *create(ASTContext &Ctx, SourceLoc atLoc,
SourceRange Range,
TypeLoc ProtocolType,
DeclName MemberName,
DeclNameLoc MemberNameLoc);

TypeLoc getProtocolType() const;
TypeLoc &getProtocolType();
DeclName getMemberName() const { return MemberName; }
DeclNameLoc getMemberNameLoc() const { return MemberNameLoc; }

static bool classof(const DeclAttribute *DA) {
return DA->getKind() == DAK_Implements;
}
};

/// \brief Attributes that may be applied to declarations.
class DeclAttributes {
/// Linked list of declaration attributes.
Expand Down
66 changes: 35 additions & 31 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define SWIFT_DECL_H

#include "swift/AST/AccessScope.h"
#include "swift/AST/Attr.h"
#include "swift/AST/CaptureInfo.h"
#include "swift/AST/ClangNode.h"
#include "swift/AST/ConcreteDeclRef.h"
Expand Down Expand Up @@ -286,8 +287,12 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Whether we have already checked whether this declaration is a
/// redeclaration.
unsigned CheckedRedeclaration : 1;

/// Whether the decl can be accessed by swift users; for instance,
/// a.storage for lazy var a is a decl that cannot be accessed.
unsigned IsUserAccessible : 1;
};
enum { NumValueDeclBits = NumDeclBits + 2 };
enum { NumValueDeclBits = NumDeclBits + 3 };
static_assert(NumValueDeclBits <= 32, "fits in an unsigned");

class AbstractStorageDeclBitfields {
Expand Down Expand Up @@ -327,11 +332,8 @@ class alignas(1 << DeclAlignInBits) Decl {
/// It is up to the debugger to instruct SIL how to access this variable.
unsigned IsDebuggerVar : 1;

/// Whether the decl can be accessed by swift users; for instance,
/// a.storage for lazy var a is a decl that cannot be accessed.
unsigned IsUserAccessible : 1;
};
enum { NumVarDeclBits = NumAbstractStorageDeclBits + 6 };
enum { NumVarDeclBits = NumAbstractStorageDeclBits + 5 };
static_assert(NumVarDeclBits <= 32, "fits in an unsigned");

class EnumElementDeclBitfields {
Expand Down Expand Up @@ -383,10 +385,8 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Whether this function has a dynamic Self return type.
unsigned HasDynamicSelf : 1;

/// Whether we are statically dispatched even if overridable
unsigned ForcedStaticDispatch : 1;
};
enum { NumFuncDeclBits = NumAbstractFunctionDeclBits + 6 };
enum { NumFuncDeclBits = NumAbstractFunctionDeclBits + 5 };
static_assert(NumFuncDeclBits <= 32, "fits in an unsigned");

class ConstructorDeclBitfields {
Expand All @@ -400,9 +400,6 @@ class alignas(1 << DeclAlignInBits) Decl {
/// analysis and SIL generation.
unsigned ComputedBodyInitKind : 3;

/// The kind of initializer we have.
unsigned InitKind : 2;

/// Whether this initializer is a stub placed into a subclass to
/// catch invalid delegations to a designated initializer not
/// overridden by the subclass. A stub will always trap at runtime.
Expand All @@ -412,7 +409,7 @@ class alignas(1 << DeclAlignInBits) Decl {
/// an object construction that will invoke a stub.
unsigned HasStubImplementation : 1;
};
enum { NumConstructorDeclBits = NumAbstractFunctionDeclBits + 6 };
enum { NumConstructorDeclBits = NumAbstractFunctionDeclBits + 4 };
static_assert(NumConstructorDeclBits <= 32, "fits in an unsigned");

class TypeDeclBitfields {
Expand Down Expand Up @@ -523,10 +520,8 @@ class alignas(1 << DeclAlignInBits) Decl {
/// control inserting the implicit destructor.
unsigned HasDestructorDecl : 1;

/// Whether the class has @objc ancestry.
unsigned ObjCClassKind : 3;
};
enum { NumClassDeclBits = NumNominalTypeDeclBits + 11 };
enum { NumClassDeclBits = NumNominalTypeDeclBits + 8 };
static_assert(NumClassDeclBits <= 32, "fits in an unsigned");

class StructDeclBitfields {
Expand Down Expand Up @@ -2090,6 +2085,7 @@ class ValueDecl : public Decl {
: Decl(K, context), Name(name), NameLoc(NameLoc) {
ValueDeclBits.AlreadyInLookupTable = false;
ValueDeclBits.CheckedRedeclaration = false;
ValueDeclBits.IsUserAccessible = true;
}

public:
Expand All @@ -2115,6 +2111,14 @@ class ValueDecl : public Decl {
ValueDeclBits.CheckedRedeclaration = checked;
}

void setUserAccessible(bool Accessible) {
ValueDeclBits.IsUserAccessible = Accessible;
}

bool isUserAccessible() const {
return ValueDeclBits.IsUserAccessible;
}

bool hasName() const { return bool(Name); }
/// TODO: Rename to getSimpleName?
Identifier getName() const { return Name.getBaseName(); }
Expand Down Expand Up @@ -3182,6 +3186,9 @@ class ClassDecl : public NominalTypeDecl {
SourceLoc ClassLoc;
ObjCMethodLookupTable *ObjCMethodLookup = nullptr;

/// Whether the class has @objc ancestry.
unsigned ObjCKind : 3;

/// Create the Objective-C member lookup table.
void createObjCMethodLookup();

Expand Down Expand Up @@ -3795,7 +3802,7 @@ struct alignas(1 << 3) BehaviorRecord {
: ProtocolName(ProtocolName), Param(Param)
{}

SourceLoc getLoc() const { return ProtocolName->getLoc(); }
SourceLoc getLoc() const;
};

/// AbstractStorageDecl - This is the common superclass for VarDecl and
Expand Down Expand Up @@ -4277,7 +4284,6 @@ class VarDecl : public AbstractStorageDecl {
SourceLoc NameLoc, Identifier Name, Type Ty, DeclContext *DC)
: AbstractStorageDecl(Kind, DC, Name, NameLoc)
{
VarDeclBits.IsUserAccessible = true;
VarDeclBits.IsStatic = IsStatic;
VarDeclBits.IsLet = IsLet;
VarDeclBits.IsCaptureList = IsCaptureList;
Expand All @@ -4299,14 +4305,6 @@ class VarDecl : public AbstractStorageDecl {

SourceRange getSourceRange() const;

void setUserAccessible(bool Accessible) {
VarDeclBits.IsUserAccessible = Accessible;
}

bool isUserAccessible() const {
return VarDeclBits.IsUserAccessible;
}

TypeLoc &getTypeLoc() { return typeLoc; }
TypeLoc getTypeLoc() const { return typeLoc; }

Expand Down Expand Up @@ -5030,6 +5028,9 @@ class FuncDecl final : public AbstractFunctionDecl,
unsigned HaveSearchedForCommonOverloadReturnType : 1;
unsigned HaveFoundCommonOverloadReturnType : 1;

/// Whether we are statically dispatched even if overridable
unsigned ForcedStaticDispatch : 1;

/// \brief If this FuncDecl is an accessor for a property, this indicates
/// which property and what kind of accessor.
llvm::PointerIntPair<AbstractStorageDecl*, 3, AccessorKind> AccessorDecl;
Expand Down Expand Up @@ -5059,8 +5060,8 @@ class FuncDecl final : public AbstractFunctionDecl,
assert(NumParameterLists > 0 && "Must have at least an empty tuple arg");
FuncDeclBits.Mutating = false;
FuncDeclBits.HasDynamicSelf = false;
FuncDeclBits.ForcedStaticDispatch = false;

ForcedStaticDispatch = false;
HaveSearchedForCommonOverloadReturnType = false;
HaveFoundCommonOverloadReturnType = false;
}
Expand Down Expand Up @@ -5290,10 +5291,10 @@ class FuncDecl final : public AbstractFunctionDecl,

/// Returns true if the function is forced to be statically dispatched.
bool hasForcedStaticDispatch() const {
return FuncDeclBits.ForcedStaticDispatch;
return ForcedStaticDispatch;
}
void setForcedStaticDispatch(bool flag) {
FuncDeclBits.ForcedStaticDispatch = flag;
ForcedStaticDispatch = flag;
}

static bool classof(const Decl *D) { return D->getKind() == DeclKind::Func; }
Expand Down Expand Up @@ -5510,6 +5511,9 @@ enum class CtorInitializerKind {
/// }
/// \endcode
class ConstructorDecl : public AbstractFunctionDecl {
/// The kind of initializer we have.
unsigned InitKind : 2;

/// The failability of this initializer, which is an OptionalTypeKind.
unsigned Failability : 2;

Expand Down Expand Up @@ -5615,12 +5619,12 @@ class ConstructorDecl : public AbstractFunctionDecl {

/// Determine the kind of initializer this is.
CtorInitializerKind getInitKind() const {
return static_cast<CtorInitializerKind>(ConstructorDeclBits.InitKind);
return static_cast<CtorInitializerKind>(InitKind);
}

/// Set whether this is a convenience initializer.
void setInitKind(CtorInitializerKind kind) {
ConstructorDeclBits.InitKind = static_cast<unsigned>(kind);
InitKind = static_cast<unsigned>(kind);
}

/// Whether this is a designated initializer.
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/DiagnosticEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef SWIFT_BASIC_DIAGNOSTICENGINE_H
#define SWIFT_BASIC_DIAGNOSTICENGINE_H

#include "swift/AST/Attr.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/DiagnosticConsumer.h"
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,10 @@ ERROR(attr_specialize_parameter_already_defined,none,
ERROR(attr_specialize_expected_partial_or_full,none,
"expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute", ())

// _implements
ERROR(attr_implements_expected_member_name,PointsToFirstBadToken,
"expected a member name as second parameter in '_implements' attribute", ())

//------------------------------------------------------------------------------
// Generics parsing diagnostics
//------------------------------------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,17 @@ ERROR(lazy_not_observable,none,
ERROR(attr_for_debugger_support_only,none,
"@LLDBDebuggerSupport may only be used when debugger support is on", ())

// @_implements
ERROR(implements_attr_protocol_lacks_member,none,
"protocol %0 has no member %1", (DeclName, DeclName))

ERROR(implements_attr_non_protocol_type,none,
"non-protocol type in @_implements attribute", ())

ERROR(implements_attr_protocol_not_conformed_to,none,
"containing type %0 does not conform to protocol %1",
(DeclName, DeclName))

//------------------------------------------------------------------------------
// Type Check Expressions
//------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "swift/AST/ProtocolConformanceRef.h"
#include "swift/AST/TypeAlignments.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/TypeRepr.h"
#include "swift/AST/Availability.h"
#include "llvm/Support/TrailingObjects.h"

Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "swift/AST/Identifier.h"
#include "swift/AST/Types.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/TypeRepr.h"
#include "swift/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ IDENTIFIER_WITH_NAME(NativeClassLayout, "_NativeClass")
// Operators
IDENTIFIER_WITH_NAME(MatchOperator, "~=")
IDENTIFIER_WITH_NAME(EqualsOperator, "==")
IDENTIFIER_WITH_NAME(derived_enum_equals, "__derived_enum_equals")

// Precedence groups
IDENTIFIER(AssignmentPrecedence)
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/LazyResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ class DelegatingLazyResolver : public LazyResolver {
}
};

class LazyMemberLoader;

/// Context data for lazy deserialization.
class LazyContextData {
public:
Expand Down
18 changes: 3 additions & 15 deletions include/swift/AST/TypeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

#include "swift/Basic/SourceLoc.h"
#include "swift/AST/Type.h"
#include "swift/AST/TypeRepr.h"
#include "llvm/ADT/PointerIntPair.h"

namespace swift {

class ASTContext;
class TypeRepr;

/// TypeLoc - Provides source location information for a parsed type.
/// A TypeLoc is stored in AST nodes which use an explicitly written type.
Expand Down Expand Up @@ -54,11 +54,7 @@ struct TypeLoc {

/// Get the representative location of this type, for diagnostic
/// purposes.
SourceLoc getLoc() const {
if (TyR) return TyR->getLoc();
return SourceLoc();
}

SourceLoc getLoc() const;
SourceRange getSourceRange() const;

bool hasLocation() const { return TyR != nullptr; }
Expand All @@ -72,15 +68,7 @@ struct TypeLoc {
TAndValidBit.setPointerAndInt(Ty, validated);
}

TypeLoc clone(ASTContext &ctx) const {
if (TyR) {
TypeLoc result(TyR->clone(ctx));
result.TAndValidBit = this->TAndValidBit;
return result;
}

return *this;
}
TypeLoc clone(ASTContext &ctx) const;
};

} // end namespace llvm
Expand Down
Loading