Skip to content

Commit e4905b9

Browse files
authored
Merge pull request #8770 from slavapestov/anyobject-removal-preparations
AnyObject removal preparations
2 parents 54e1f83 + 0708323 commit e4905b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+797
-479
lines changed

docs/ABI.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,8 @@ Types
10441044
type ::= associated-type
10451045
type ::= nominal-type
10461046
type ::= protocol-list 'p' // existential type
1047-
type ::= protocol-list superclass 'XE' // existential type with superclass
1047+
type ::= protocol-list superclass 'Xc' // existential type with superclass
1048+
type ::= protocol-list 'Xl' // existential type with AnyObject
10481049
type ::= type-list 't' // tuple
10491050
type ::= type generic-signature 'u' // generic type
10501051
type ::= 'x' // generic param, depth=0, idx=0

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ class ASTContext {
407407
/// Retrieve the declaration of the "pointee" property of a pointer type.
408408
VarDecl *getPointerPointeePropertyDecl(PointerTypeKind ptrKind) const;
409409

410+
/// Retrieve the type Swift.AnyObject.
411+
CanType getAnyObjectType() const;
412+
410413
/// Retrieve the type Swift.Never.
411414
CanType getNeverType() const;
412415

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,6 @@ WARNING(expr_keypath_swift3_objc_inference,none,
419419
"argument of '#keyPath' refers to property %0 in %1 that depends on "
420420
"'@objc' attribute inference deprecated in Swift 4",
421421
(DeclName, Identifier))
422-
ERROR(stdlib_anyobject_not_found,none,
423-
"broken standard library: cannot find 'AnyObject' protocol", ())
424422
ERROR(expr_keypath_type_of_property,none,
425423
"cannot refer to type member %0 within instance of type %1",
426424
(DeclName, Type))

include/swift/AST/ExistentialLayout.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ struct ExistentialLayout {
7171
return multipleProtocols;
7272
}
7373

74+
LayoutConstraint getLayoutConstraint() const;
75+
7476
private:
7577
// Inline storage for 'protocols' member above when computing
7678
// layout of a single ProtocolType

include/swift/AST/Type.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,6 @@ class CanType : public Type {
353353
static bool isAnyExistentialTypeImpl(CanType type);
354354
static void getExistentialTypeProtocolsImpl(CanType type,
355355
SmallVectorImpl<ProtocolDecl*> &protocols);
356-
static void getAnyExistentialTypeProtocolsImpl(CanType type,
357-
SmallVectorImpl<ProtocolDecl*> &protocols);
358356
static bool isObjCExistentialTypeImpl(CanType type);
359357
static CanType getAnyOptionalObjectTypeImpl(CanType type,
360358
OptionalTypeKind &kind);
@@ -413,11 +411,6 @@ class CanType : public Type {
413411
void getExistentialTypeProtocols(
414412
SmallVectorImpl<ProtocolDecl *> &protocols);
415413

416-
/// Given that this type is any kind of existential, return its
417-
/// protocols in a canonical order.
418-
void getAnyExistentialTypeProtocols(
419-
SmallVectorImpl<ProtocolDecl *> &protocols);
420-
421414
/// Break an existential down into a set of constraints.
422415
ExistentialLayout getExistentialLayout();
423416

@@ -434,11 +427,6 @@ class CanType : public Type {
434427
NominalTypeDecl *getAnyNominal() const;
435428
GenericTypeDecl *getAnyGeneric() const;
436429

437-
/// Returns information about the layout constraint represented by
438-
/// this type. If this type does not represent a layout constraint,
439-
/// it returns an empty LayoutConstraint.
440-
LayoutConstraint getLayoutConstraint() const;
441-
442430
CanType getAnyOptionalObjectType() const {
443431
OptionalTypeKind kind;
444432
return getAnyOptionalObjectTypeImpl(*this, kind);

include/swift/AST/Types.h

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ class alignas(1 << TypeAlignInBits) TypeBase {
325325
};
326326
enum { NumAnyMetatypeTypeBits = NumTypeBaseBits + 2 };
327327
static_assert(NumAnyMetatypeTypeBits <= 32, "fits in an unsigned");
328+
329+
struct ProtocolCompositionTypeBitfields {
330+
unsigned : NumTypeBaseBits;
331+
/// Whether we have an explicitly-stated class constraint not
332+
/// implied by any of our members.
333+
unsigned HasExplicitAnyObject : 1;
334+
};
335+
enum { NumProtocolCompositionTypeBits = NumTypeBaseBits + 1 };
336+
static_assert(NumProtocolCompositionTypeBits <= 32, "fits in an unsigned");
328337

329338
union {
330339
TypeBaseBitfields TypeBaseBits;
@@ -334,6 +343,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
334343
ArchetypeTypeBitfields ArchetypeTypeBits;
335344
SILFunctionTypeBitfields SILFunctionTypeBits;
336345
AnyMetatypeTypeBitfields AnyMetatypeTypeBits;
346+
ProtocolCompositionTypeBitfields ProtocolCompositionTypeBits;
337347
};
338348

339349
protected:
@@ -580,10 +590,6 @@ class alignas(1 << TypeAlignInBits) TypeBase {
580590
/// its list of protocols.
581591
void getExistentialTypeProtocols(SmallVectorImpl<ProtocolDecl *> &protocols);
582592

583-
/// Given that this type is any kind of existential type, produce
584-
/// its list of protocols.
585-
void getAnyExistentialTypeProtocols(SmallVectorImpl<ProtocolDecl *> &protocols);
586-
587593
/// Break an existential down into a set of constraints.
588594
ExistentialLayout getExistentialLayout();
589595

@@ -707,12 +713,6 @@ class alignas(1 << TypeAlignInBits) TypeBase {
707713
/// concrete types to form the argument type.
708714
bool isBindableTo(Type ty, LazyResolver *resolver);
709715

710-
/// \brief Retrieve the layout constraint of this type.
711-
///
712-
/// \returns The layout constraint of this type, or a null layout constraint
713-
/// if it has no layout constraint.
714-
LayoutConstraint getLayoutConstraint();
715-
716716
/// \brief Determines whether this type is permitted as a method override
717717
/// of the \p other.
718718
bool canOverride(Type other, OverrideMatchMode matchMode,
@@ -3662,44 +3662,66 @@ END_CAN_TYPE_WRAPPER(ProtocolType, NominalType)
36623662
/// protocol, then the canonical type is that protocol type. Otherwise, it is
36633663
/// a composition of the protocols in that list.
36643664
class ProtocolCompositionType : public TypeBase, public llvm::FoldingSetNode {
3665-
ArrayRef<Type> Protocols;
3665+
ArrayRef<Type> Members;
36663666

36673667
public:
36683668
/// \brief Retrieve an instance of a protocol composition type with the
3669-
/// given set of protocols.
3670-
static Type get(const ASTContext &C, ArrayRef<Type> Protocols);
3669+
/// given set of members.
3670+
static Type get(const ASTContext &C, ArrayRef<Type> Members,
3671+
bool HasExplicitAnyObject);
36713672

3672-
/// \brief Retrieve the set of protocols composed to create this type.
3673-
ArrayRef<Type> getProtocols() const { return Protocols; }
3673+
/// \brief Retrieve the set of members composed to create this type.
3674+
///
3675+
/// For non-canonical types, this can contain classes, protocols and
3676+
/// protocol compositions in any order. There can be at most one unique
3677+
/// class constraint, either stated directly or as recursive member.
3678+
///
3679+
/// In canonical types, this list will contain the superclass first if
3680+
/// any, followed by zero or more protocols in a canonical sorted order,
3681+
/// minimized to remove duplicates or protocols implied by inheritance.
3682+
///
3683+
/// Note that the list of members is not sufficient to uniquely identify
3684+
/// a protocol composition type; you also have to look at
3685+
/// hasExplicitAnyObject().
3686+
ArrayRef<Type> getMembers() const { return Members; }
36743687

36753688
void Profile(llvm::FoldingSetNodeID &ID) {
3676-
Profile(ID, Protocols);
3689+
Profile(ID, Members, hasExplicitAnyObject());
36773690
}
3678-
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<Type> Protocols);
3691+
static void Profile(llvm::FoldingSetNodeID &ID,
3692+
ArrayRef<Type> Members,
3693+
bool HasExplicitAnyObject);
36793694

3680-
/// True if one or more of the protocols is class.
3695+
/// True if the composition requires the concrete conforming type to
3696+
/// be a class, either via a directly-stated superclass constraint or
3697+
/// one of its member protocols being class-constrained.
36813698
bool requiresClass();
3682-
3699+
3700+
/// True if the class requirement is stated directly via '& AnyObject'.
3701+
bool hasExplicitAnyObject() {
3702+
return ProtocolCompositionTypeBits.HasExplicitAnyObject;
3703+
}
3704+
36833705
// Implement isa/cast/dyncast/etc.
36843706
static bool classof(const TypeBase *T) {
36853707
return T->getKind() == TypeKind::ProtocolComposition;
36863708
}
36873709

36883710
private:
36893711
static ProtocolCompositionType *build(const ASTContext &C,
3690-
ArrayRef<Type> Protocols);
3712+
ArrayRef<Type> Members,
3713+
bool HasExplicitAnyObject);
36913714

3692-
ProtocolCompositionType(const ASTContext *ctx, ArrayRef<Type> protocols,
3715+
ProtocolCompositionType(const ASTContext *ctx, ArrayRef<Type> members,
3716+
bool hasExplicitAnyObject,
36933717
RecursiveTypeProperties properties)
36943718
: TypeBase(TypeKind::ProtocolComposition, /*Context=*/ctx,
36953719
properties),
3696-
Protocols(protocols) { }
3720+
Members(members) {
3721+
ProtocolCompositionTypeBits.HasExplicitAnyObject = hasExplicitAnyObject;
3722+
}
36973723
};
36983724
BEGIN_CAN_TYPE_WRAPPER(ProtocolCompositionType, Type)
3699-
/// In the canonical representation, these are all ProtocolTypes.
3700-
CanTypeArrayRef getProtocols() const {
3701-
return CanTypeArrayRef(getPointer()->getProtocols());
3702-
}
37033725
END_CAN_TYPE_WRAPPER(ProtocolCompositionType, Type)
37043726

37053727
/// LValueType - An l-value is a handle to a physical object. The

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ NODE(ProtocolConformance)
124124
NODE(ProtocolDescriptor)
125125
NODE(ProtocolList)
126126
NODE(ProtocolListWithClass)
127+
NODE(ProtocolListWithAnyObject)
127128
NODE(ProtocolWitness)
128129
NODE(ProtocolWitnessTable)
129130
NODE(ProtocolWitnessTableAccessor)

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ class Demangler : public NodeFactory {
447447
NodePointer demangleMetatypeRepresentation();
448448
NodePointer demangleFunctionEntity();
449449
NodePointer demangleEntity(Node::Kind Kind);
450+
NodePointer demangleProtocolList();
450451
NodePointer demangleProtocolListType();
451452
NodePointer demangleGenericSignature(bool hasParamCounts);
452453
NodePointer demangleGenericRequirement();

include/swift/Runtime/Metadata.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2441,6 +2441,11 @@ struct TargetExistentialTypeMetadata : public TargetMetadata<Runtime> {
24412441
return Flags.getClassConstraint() == ProtocolClassConstraint::Class;
24422442
}
24432443

2444+
const Metadata *getSuperclassConstraint() const {
2445+
// FIXME
2446+
return nullptr;
2447+
}
2448+
24442449
static bool classof(const TargetMetadata<Runtime> *metadata) {
24452450
return metadata->getKind() == MetadataKind::Existential;
24462451
}
@@ -3176,7 +3181,9 @@ swift_getExistentialMetatypeMetadata(const Metadata *instanceType);
31763181
/// referenced by \c protocols will be sorted in-place.
31773182
SWIFT_RT_ENTRY_VISIBILITY
31783183
const ExistentialTypeMetadata *
3179-
swift_getExistentialTypeMetadata(size_t numProtocols,
3184+
swift_getExistentialTypeMetadata(ProtocolClassConstraint classConstraint,
3185+
const Metadata *superclassConstraint,
3186+
size_t numProtocols,
31803187
const ProtocolDescriptor **protocols)
31813188
SWIFT_CC(RegisterPreservingCC);
31823189

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,12 +791,17 @@ FUNCTION(GetTupleMetadata3, swift_getTupleTypeMetadata3, DefaultCC,
791791
Int8PtrTy, WitnessTablePtrTy),
792792
ATTRS(NoUnwind, ReadOnly))
793793

794-
// Metadata *swift_getExistentialTypeMetadata(size_t numProtocols,
794+
// Metadata *swift_getExistentialTypeMetadata(
795+
// ProtocolClassConstraint classConstraint,
796+
// const Metadata *superclassConstraint,
797+
// size_t numProtocols,
795798
// const protocol_descriptor_t * const *protocols);
799+
//
800+
// Note: ProtocolClassConstraint::Class is 0, ::Any is 1.
796801
FUNCTION(GetExistentialMetadata,
797802
swift_getExistentialTypeMetadata, RegisterPreservingCC,
798803
RETURNS(TypeMetadataPtrTy),
799-
ARGS(SizeTy,
804+
ARGS(Int1Ty, TypeMetadataPtrTy, SizeTy,
800805
ProtocolDescriptorPtrTy->getPointerTo()),
801806
ATTRS(NoUnwind, ReadOnly))
802807

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 333; // Last change: AST constant_string_literal
57+
const uint16_t VERSION_MINOR = 334; // Last change: AnyObject bit in ProtocolCompositionType
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -660,6 +660,7 @@ namespace decls_block {
660660

661661
using ProtocolCompositionTypeLayout = BCRecordLayout<
662662
PROTOCOL_COMPOSITION_TYPE,
663+
BCFixed<1>, // has AnyObject constraint
663664
BCArray<TypeIDField> // protocols
664665
>;
665666

lib/AST/ASTContext.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ struct ASTContext::Implementation {
112112
/// The declaration of Swift.DefaultPrecedence.
113113
PrecedenceGroupDecl *DefaultPrecedence = nullptr;
114114

115+
/// The AnyObject type.
116+
CanType AnyObjectType;
117+
115118
#define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \
116119
/** The declaration of Swift.NAME. */ \
117120
DECL_CLASS *NAME##Decl = nullptr;
@@ -415,7 +418,8 @@ ASTContext::ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
415418
TheUnresolvedType(new (*this, AllocationArena::Permanent)
416419
UnresolvedType(*this)),
417420
TheEmptyTupleType(TupleType::get(ArrayRef<TupleTypeElt>(), *this)),
418-
TheAnyType(ProtocolCompositionType::get(*this, ArrayRef<Type>())),
421+
TheAnyType(ProtocolCompositionType::get(*this, ArrayRef<Type>(),
422+
/*hasExplicitAnyObject=*/false)),
419423
TheNativeObjectType(new (*this, AllocationArena::Permanent)
420424
BuiltinNativeObjectType(*this)),
421425
TheBridgeObjectType(new (*this, AllocationArena::Permanent)
@@ -670,6 +674,29 @@ ASTContext::getPointerPointeePropertyDecl(PointerTypeKind ptrKind) const {
670674
llvm_unreachable("bad pointer kind");
671675
}
672676

677+
CanType ASTContext::getAnyObjectType() const {
678+
if (Impl.AnyObjectType) {
679+
return Impl.AnyObjectType;
680+
}
681+
682+
// Go find 'AnyObject' in the Swift module.
683+
//
684+
// FIXME: This is going away.
685+
SmallVector<ValueDecl *, 1> results;
686+
lookupInSwiftModule("AnyObject", results);
687+
for (auto result : results) {
688+
if (auto proto = dyn_cast<ProtocolDecl>(result)) {
689+
Impl.AnyObjectType = proto->getDeclaredType()->getCanonicalType();
690+
return Impl.AnyObjectType;
691+
}
692+
}
693+
694+
Impl.AnyObjectType = CanType(
695+
ProtocolCompositionType::get(
696+
*this, {}, /*hasExplicitAnyObject=*/true));
697+
return Impl.AnyObjectType;
698+
}
699+
673700
CanType ASTContext::getNeverType() const {
674701
return getNeverDecl()->getDeclaredType()->getCanonicalType();
675702
}
@@ -2834,15 +2861,16 @@ void ClassType::Profile(llvm::FoldingSetNodeID &ID, ClassDecl *D, Type Parent) {
28342861
}
28352862

28362863
ProtocolCompositionType *
2837-
ProtocolCompositionType::build(const ASTContext &C, ArrayRef<Type> Protocols) {
2864+
ProtocolCompositionType::build(const ASTContext &C, ArrayRef<Type> Members,
2865+
bool HasExplicitAnyObject) {
28382866
// Check to see if we've already seen this protocol composition before.
28392867
void *InsertPos = nullptr;
28402868
llvm::FoldingSetNodeID ID;
2841-
ProtocolCompositionType::Profile(ID, Protocols);
2869+
ProtocolCompositionType::Profile(ID, Members, HasExplicitAnyObject);
28422870

28432871
bool isCanonical = true;
28442872
RecursiveTypeProperties properties;
2845-
for (Type t : Protocols) {
2873+
for (Type t : Members) {
28462874
if (!t->isCanonical())
28472875
isCanonical = false;
28482876
properties |= t->getRecursiveProperties();
@@ -2859,7 +2887,8 @@ ProtocolCompositionType::build(const ASTContext &C, ArrayRef<Type> Protocols) {
28592887
auto compTy
28602888
= new (C, arena)
28612889
ProtocolCompositionType(isCanonical ? &C : nullptr,
2862-
C.AllocateCopy(Protocols),
2890+
C.AllocateCopy(Members),
2891+
HasExplicitAnyObject,
28632892
properties);
28642893
C.Impl.getArena(arena).ProtocolCompositionTypes
28652894
.InsertNode(compTy, InsertPos);
@@ -3510,17 +3539,21 @@ CanArchetypeType ArchetypeType::getOpened(Type existential,
35103539
for (auto proto : layout.getProtocols())
35113540
protos.push_back(proto->getDecl());
35123541

3542+
auto layoutConstraint = layout.getLayoutConstraint();
3543+
35133544
auto arena = AllocationArena::Permanent;
35143545
void *mem = ctx.Allocate(
35153546
totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint, UUID>(
3516-
protos.size(), layout.superclass ? 1 : 0, 0, 1),
3547+
protos.size(),
3548+
layout.superclass ? 1 : 0,
3549+
layoutConstraint ? 1 : 0, 1),
35173550
alignof(ArchetypeType), arena);
35183551

35193552
// FIXME: Pass in class layout constraint
35203553
auto result =
35213554
::new (mem) ArchetypeType(ctx, existential,
35223555
protos, layout.superclass,
3523-
existential->getLayoutConstraint(), *knownID);
3556+
layoutConstraint, *knownID);
35243557
openedExistentialArchetypes[*knownID] = result;
35253558

35263559
return CanArchetypeType(result);

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3075,7 +3075,9 @@ namespace {
30753075
void visitProtocolCompositionType(ProtocolCompositionType *T,
30763076
StringRef label) {
30773077
printCommon(T, label, "protocol_composition_type");
3078-
for (auto proto : T->getProtocols()) {
3078+
if (T->hasExplicitAnyObject())
3079+
OS << " any_object";
3080+
for (auto proto : T->getMembers()) {
30793081
printRec(proto);
30803082
}
30813083
OS << ")";

0 commit comments

Comments
 (0)