Skip to content

Commit 6a94c9f

Browse files
authored
Merge pull request #8735 from graydon/rdar-30959593-operators-defeat-incrementality
Attribute @_implements & deriving enum equality not-named ==
2 parents 504b6f2 + e6027ee commit 6a94c9f

34 files changed

+510
-73
lines changed

include/swift/AST/Attr.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ SIMPLE_DECL_ATTR(discardableResult, DiscardableResult,
267267

268268
SIMPLE_DECL_ATTR(GKInspectable, GKInspectable, OnVar, 66)
269269

270+
DECL_ATTR(_implements, Implements,
271+
OnFunc | OnVar | OnSubscript | OnTypeAlias
272+
| NotSerialized | UserInaccessible,
273+
/* Not serialized */ 67)
274+
270275
#undef TYPE_ATTR
271276
#undef DECL_ATTR_ALIAS
272277
#undef SIMPLE_DECL_ATTR

include/swift/AST/Attr.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
#include "swift/AST/Identifier.h"
2626
#include "swift/AST/AttrKind.h"
2727
#include "swift/AST/ConcreteDeclRef.h"
28+
#include "swift/AST/DeclNameLoc.h"
2829
#include "swift/AST/KnownProtocols.h"
2930
#include "swift/AST/Ownership.h"
3031
#include "swift/AST/PlatformKind.h"
3132
#include "swift/AST/Requirement.h"
33+
#include "swift/AST/TypeLoc.h"
3234
#include "llvm/ADT/SmallVector.h"
3335
#include "llvm/ADT/StringRef.h"
3436
#include "llvm/Support/ErrorHandling.h"
@@ -43,7 +45,6 @@ class Decl;
4345
class ClassDecl;
4446
class GenericFunctionType;
4547
class TrailingWhereClause;
46-
struct TypeLoc;
4748

4849
/// TypeAttributes - These are attributes that may be applied to types.
4950
class TypeAttributes {
@@ -1127,6 +1128,36 @@ class SpecializeAttr : public DeclAttribute {
11271128
}
11281129
};
11291130

1131+
/// The @_implements attribute, which treats a decl as the implementation for
1132+
/// some named protocol requirement (but otherwise not-visible by that name).
1133+
class ImplementsAttr : public DeclAttribute {
1134+
1135+
TypeLoc ProtocolType;
1136+
DeclName MemberName;
1137+
DeclNameLoc MemberNameLoc;
1138+
1139+
public:
1140+
ImplementsAttr(SourceLoc atLoc, SourceRange Range,
1141+
TypeLoc ProtocolType,
1142+
DeclName MemberName,
1143+
DeclNameLoc MemberNameLoc);
1144+
1145+
static ImplementsAttr *create(ASTContext &Ctx, SourceLoc atLoc,
1146+
SourceRange Range,
1147+
TypeLoc ProtocolType,
1148+
DeclName MemberName,
1149+
DeclNameLoc MemberNameLoc);
1150+
1151+
TypeLoc getProtocolType() const;
1152+
TypeLoc &getProtocolType();
1153+
DeclName getMemberName() const { return MemberName; }
1154+
DeclNameLoc getMemberNameLoc() const { return MemberNameLoc; }
1155+
1156+
static bool classof(const DeclAttribute *DA) {
1157+
return DA->getKind() == DAK_Implements;
1158+
}
1159+
};
1160+
11301161
/// \brief Attributes that may be applied to declarations.
11311162
class DeclAttributes {
11321163
/// Linked list of declaration attributes.

include/swift/AST/Decl.h

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define SWIFT_DECL_H
1919

2020
#include "swift/AST/AccessScope.h"
21+
#include "swift/AST/Attr.h"
2122
#include "swift/AST/CaptureInfo.h"
2223
#include "swift/AST/ClangNode.h"
2324
#include "swift/AST/ConcreteDeclRef.h"
@@ -286,8 +287,12 @@ class alignas(1 << DeclAlignInBits) Decl {
286287
/// Whether we have already checked whether this declaration is a
287288
/// redeclaration.
288289
unsigned CheckedRedeclaration : 1;
290+
291+
/// Whether the decl can be accessed by swift users; for instance,
292+
/// a.storage for lazy var a is a decl that cannot be accessed.
293+
unsigned IsUserAccessible : 1;
289294
};
290-
enum { NumValueDeclBits = NumDeclBits + 2 };
295+
enum { NumValueDeclBits = NumDeclBits + 3 };
291296
static_assert(NumValueDeclBits <= 32, "fits in an unsigned");
292297

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

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

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

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

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

403-
/// The kind of initializer we have.
404-
unsigned InitKind : 2;
405-
406403
/// Whether this initializer is a stub placed into a subclass to
407404
/// catch invalid delegations to a designated initializer not
408405
/// overridden by the subclass. A stub will always trap at runtime.
@@ -412,7 +409,7 @@ class alignas(1 << DeclAlignInBits) Decl {
412409
/// an object construction that will invoke a stub.
413410
unsigned HasStubImplementation : 1;
414411
};
415-
enum { NumConstructorDeclBits = NumAbstractFunctionDeclBits + 6 };
412+
enum { NumConstructorDeclBits = NumAbstractFunctionDeclBits + 4 };
416413
static_assert(NumConstructorDeclBits <= 32, "fits in an unsigned");
417414

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

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

532527
class StructDeclBitfields {
@@ -2090,6 +2085,7 @@ class ValueDecl : public Decl {
20902085
: Decl(K, context), Name(name), NameLoc(NameLoc) {
20912086
ValueDeclBits.AlreadyInLookupTable = false;
20922087
ValueDeclBits.CheckedRedeclaration = false;
2088+
ValueDeclBits.IsUserAccessible = true;
20932089
}
20942090

20952091
public:
@@ -2115,6 +2111,14 @@ class ValueDecl : public Decl {
21152111
ValueDeclBits.CheckedRedeclaration = checked;
21162112
}
21172113

2114+
void setUserAccessible(bool Accessible) {
2115+
ValueDeclBits.IsUserAccessible = Accessible;
2116+
}
2117+
2118+
bool isUserAccessible() const {
2119+
return ValueDeclBits.IsUserAccessible;
2120+
}
2121+
21182122
bool hasName() const { return bool(Name); }
21192123
/// TODO: Rename to getSimpleName?
21202124
Identifier getName() const { return Name.getBaseName(); }
@@ -3182,6 +3186,9 @@ class ClassDecl : public NominalTypeDecl {
31823186
SourceLoc ClassLoc;
31833187
ObjCMethodLookupTable *ObjCMethodLookup = nullptr;
31843188

3189+
/// Whether the class has @objc ancestry.
3190+
unsigned ObjCKind : 3;
3191+
31853192
/// Create the Objective-C member lookup table.
31863193
void createObjCMethodLookup();
31873194

@@ -3795,7 +3802,7 @@ struct alignas(1 << 3) BehaviorRecord {
37953802
: ProtocolName(ProtocolName), Param(Param)
37963803
{}
37973804

3798-
SourceLoc getLoc() const { return ProtocolName->getLoc(); }
3805+
SourceLoc getLoc() const;
37993806
};
38003807

38013808
/// AbstractStorageDecl - This is the common superclass for VarDecl and
@@ -4277,7 +4284,6 @@ class VarDecl : public AbstractStorageDecl {
42774284
SourceLoc NameLoc, Identifier Name, Type Ty, DeclContext *DC)
42784285
: AbstractStorageDecl(Kind, DC, Name, NameLoc)
42794286
{
4280-
VarDeclBits.IsUserAccessible = true;
42814287
VarDeclBits.IsStatic = IsStatic;
42824288
VarDeclBits.IsLet = IsLet;
42834289
VarDeclBits.IsCaptureList = IsCaptureList;
@@ -4299,14 +4305,6 @@ class VarDecl : public AbstractStorageDecl {
42994305

43004306
SourceRange getSourceRange() const;
43014307

4302-
void setUserAccessible(bool Accessible) {
4303-
VarDeclBits.IsUserAccessible = Accessible;
4304-
}
4305-
4306-
bool isUserAccessible() const {
4307-
return VarDeclBits.IsUserAccessible;
4308-
}
4309-
43104308
TypeLoc &getTypeLoc() { return typeLoc; }
43114309
TypeLoc getTypeLoc() const { return typeLoc; }
43124310

@@ -5030,6 +5028,9 @@ class FuncDecl final : public AbstractFunctionDecl,
50305028
unsigned HaveSearchedForCommonOverloadReturnType : 1;
50315029
unsigned HaveFoundCommonOverloadReturnType : 1;
50325030

5031+
/// Whether we are statically dispatched even if overridable
5032+
unsigned ForcedStaticDispatch : 1;
5033+
50335034
/// \brief If this FuncDecl is an accessor for a property, this indicates
50345035
/// which property and what kind of accessor.
50355036
llvm::PointerIntPair<AbstractStorageDecl*, 3, AccessorKind> AccessorDecl;
@@ -5059,8 +5060,8 @@ class FuncDecl final : public AbstractFunctionDecl,
50595060
assert(NumParameterLists > 0 && "Must have at least an empty tuple arg");
50605061
FuncDeclBits.Mutating = false;
50615062
FuncDeclBits.HasDynamicSelf = false;
5062-
FuncDeclBits.ForcedStaticDispatch = false;
5063-
5063+
5064+
ForcedStaticDispatch = false;
50645065
HaveSearchedForCommonOverloadReturnType = false;
50655066
HaveFoundCommonOverloadReturnType = false;
50665067
}
@@ -5290,10 +5291,10 @@ class FuncDecl final : public AbstractFunctionDecl,
52905291

52915292
/// Returns true if the function is forced to be statically dispatched.
52925293
bool hasForcedStaticDispatch() const {
5293-
return FuncDeclBits.ForcedStaticDispatch;
5294+
return ForcedStaticDispatch;
52945295
}
52955296
void setForcedStaticDispatch(bool flag) {
5296-
FuncDeclBits.ForcedStaticDispatch = flag;
5297+
ForcedStaticDispatch = flag;
52975298
}
52985299

52995300
static bool classof(const Decl *D) { return D->getKind() == DeclKind::Func; }
@@ -5510,6 +5511,9 @@ enum class CtorInitializerKind {
55105511
/// }
55115512
/// \endcode
55125513
class ConstructorDecl : public AbstractFunctionDecl {
5514+
/// The kind of initializer we have.
5515+
unsigned InitKind : 2;
5516+
55135517
/// The failability of this initializer, which is an OptionalTypeKind.
55145518
unsigned Failability : 2;
55155519

@@ -5615,12 +5619,12 @@ class ConstructorDecl : public AbstractFunctionDecl {
56155619

56165620
/// Determine the kind of initializer this is.
56175621
CtorInitializerKind getInitKind() const {
5618-
return static_cast<CtorInitializerKind>(ConstructorDeclBits.InitKind);
5622+
return static_cast<CtorInitializerKind>(InitKind);
56195623
}
56205624

56215625
/// Set whether this is a convenience initializer.
56225626
void setInitKind(CtorInitializerKind kind) {
5623-
ConstructorDeclBits.InitKind = static_cast<unsigned>(kind);
5627+
InitKind = static_cast<unsigned>(kind);
56245628
}
56255629

56265630
/// Whether this is a designated initializer.

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_BASIC_DIAGNOSTICENGINE_H
1919
#define SWIFT_BASIC_DIAGNOSTICENGINE_H
2020

21+
#include "swift/AST/Attr.h"
2122
#include "swift/AST/TypeLoc.h"
2223
#include "swift/AST/DeclNameLoc.h"
2324
#include "swift/AST/DiagnosticConsumer.h"

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,10 @@ ERROR(attr_specialize_parameter_already_defined,none,
13521352
ERROR(attr_specialize_expected_partial_or_full,none,
13531353
"expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute", ())
13541354

1355+
// _implements
1356+
ERROR(attr_implements_expected_member_name,PointsToFirstBadToken,
1357+
"expected a member name as second parameter in '_implements' attribute", ())
1358+
13551359
//------------------------------------------------------------------------------
13561360
// Generics parsing diagnostics
13571361
//------------------------------------------------------------------------------

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,6 +2154,17 @@ ERROR(lazy_not_observable,none,
21542154
ERROR(attr_for_debugger_support_only,none,
21552155
"@LLDBDebuggerSupport may only be used when debugger support is on", ())
21562156

2157+
// @_implements
2158+
ERROR(implements_attr_protocol_lacks_member,none,
2159+
"protocol %0 has no member %1", (DeclName, DeclName))
2160+
2161+
ERROR(implements_attr_non_protocol_type,none,
2162+
"non-protocol type in @_implements attribute", ())
2163+
2164+
ERROR(implements_attr_protocol_not_conformed_to,none,
2165+
"containing type %0 does not conform to protocol %1",
2166+
(DeclName, DeclName))
2167+
21572168
//------------------------------------------------------------------------------
21582169
// Type Check Expressions
21592170
//------------------------------------------------------------------------------

include/swift/AST/Expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ProtocolConformanceRef.h"
2525
#include "swift/AST/TypeAlignments.h"
2626
#include "swift/AST/TypeLoc.h"
27+
#include "swift/AST/TypeRepr.h"
2728
#include "swift/AST/Availability.h"
2829
#include "llvm/Support/TrailingObjects.h"
2930

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/Identifier.h"
2626
#include "swift/AST/Types.h"
2727
#include "swift/AST/TypeLoc.h"
28+
#include "swift/AST/TypeRepr.h"
2829
#include "swift/Basic/LLVM.h"
2930
#include "llvm/ADT/ArrayRef.h"
3031
#include "llvm/ADT/FoldingSet.h"

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ IDENTIFIER_WITH_NAME(NativeClassLayout, "_NativeClass")
9090
// Operators
9191
IDENTIFIER_WITH_NAME(MatchOperator, "~=")
9292
IDENTIFIER_WITH_NAME(EqualsOperator, "==")
93+
IDENTIFIER_WITH_NAME(derived_enum_equals, "__derived_enum_equals")
9394

9495
// Precedence groups
9596
IDENTIFIER(AssignmentPrecedence)

include/swift/AST/LazyResolver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ class DelegatingLazyResolver : public LazyResolver {
173173
}
174174
};
175175

176+
class LazyMemberLoader;
177+
176178
/// Context data for lazy deserialization.
177179
class LazyContextData {
178180
public:

include/swift/AST/TypeLoc.h

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919

2020
#include "swift/Basic/SourceLoc.h"
2121
#include "swift/AST/Type.h"
22-
#include "swift/AST/TypeRepr.h"
2322
#include "llvm/ADT/PointerIntPair.h"
2423

2524
namespace swift {
2625

2726
class ASTContext;
27+
class TypeRepr;
2828

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

5555
/// Get the representative location of this type, for diagnostic
5656
/// purposes.
57-
SourceLoc getLoc() const {
58-
if (TyR) return TyR->getLoc();
59-
return SourceLoc();
60-
}
61-
57+
SourceLoc getLoc() const;
6258
SourceRange getSourceRange() const;
6359

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

75-
TypeLoc clone(ASTContext &ctx) const {
76-
if (TyR) {
77-
TypeLoc result(TyR->clone(ctx));
78-
result.TAndValidBit = this->TAndValidBit;
79-
return result;
80-
}
81-
82-
return *this;
83-
}
71+
TypeLoc clone(ASTContext &ctx) const;
8472
};
8573

8674
} // end namespace llvm

0 commit comments

Comments
 (0)