Skip to content

Commit 10aa1a7

Browse files
authored
Merge pull request #25742 from slavapestov/se0068-part-2
Clean up some old DynamicSelfType debt now that we have an implementation of SE-0068
2 parents f96cbb8 + 4be80ee commit 10aa1a7

36 files changed

+560
-330
lines changed

include/swift/AST/Decl.h

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ class alignas(1 << DeclAlignInBits) Decl {
433433
HasSingleExpressionBody : 1
434434
);
435435

436-
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+2+1+1+1+2,
436+
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+2+1+1+2,
437437
/// Whether this function is a 'static' method.
438438
IsStatic : 1,
439439

@@ -443,9 +443,6 @@ class alignas(1 << DeclAlignInBits) Decl {
443443
/// Whether we are statically dispatched even if overridable
444444
ForcedStaticDispatch : 1,
445445

446-
/// Whether this function has a dynamic Self return type.
447-
HasDynamicSelf : 1,
448-
449446
/// Whether we've computed the 'self' access kind yet.
450447
SelfAccessComputed : 1,
451448

@@ -5923,9 +5920,14 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
59235920
/// True if the declaration is forced to be statically dispatched.
59245921
bool hasForcedStaticDispatch() const;
59255922

5926-
/// Get the interface type of this decl and remove the Self context.
5923+
/// Get the type of this declaration without the Self clause.
5924+
/// Asserts if not in type context.
59275925
Type getMethodInterfaceType() const;
59285926

5927+
/// Tests if this is a function returning a DynamicSelfType, or a
5928+
/// constructor.
5929+
bool hasDynamicSelfResult() const;
5930+
59295931
using DeclContext::operator new;
59305932
using Decl::getASTContext;
59315933
};
@@ -5973,7 +5975,6 @@ class FuncDecl : public AbstractFunctionDecl {
59735975
StaticLoc.isValid() || StaticSpelling != StaticSpellingKind::None;
59745976
Bits.FuncDecl.StaticSpelling = static_cast<unsigned>(StaticSpelling);
59755977

5976-
Bits.FuncDecl.HasDynamicSelf = false;
59775978
Bits.FuncDecl.ForcedStaticDispatch = false;
59785979
Bits.FuncDecl.SelfAccess =
59795980
static_cast<unsigned>(SelfAccessKind::NonMutating);
@@ -6086,15 +6087,6 @@ class FuncDecl : public AbstractFunctionDecl {
60866087
/// This also allows the binary-operator-ness of a func decl to be determined
60876088
/// prior to type checking.
60886089
bool isBinaryOperator() const;
6089-
6090-
/// Determine whether this function has a dynamic \c Self return
6091-
/// type.
6092-
bool hasDynamicSelf() const { return Bits.FuncDecl.HasDynamicSelf; }
6093-
6094-
/// Set whether this function has a dynamic \c Self return or not.
6095-
void setDynamicSelf(bool hasDynamicSelf) {
6096-
Bits.FuncDecl.HasDynamicSelf = hasDynamicSelf;
6097-
}
60986090

60996091
void getLocalCaptures(SmallVectorImpl<CapturedValue> &Result) const {
61006092
return getCaptureInfo().getLocalCaptures(Result);

include/swift/AST/DiagnosticsSema.def

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,9 +2576,21 @@ NOTE(missing_member_type_conformance_prevents_synthesis, none,
25762576
ERROR(dynamic_self_non_method,none,
25772577
"%select{global|local}0 function cannot return 'Self'", (bool))
25782578

2579-
ERROR(self_in_nominal,none,
2580-
"'Self' is only available in a protocol or as the result of a "
2581-
"method in a class; did you mean '%0'?", (StringRef))
2579+
ERROR(dynamic_self_invalid,none,
2580+
"covariant 'Self' can only appear as the type of a property, subscript or method result; "
2581+
"did you mean '%0'?", (StringRef))
2582+
ERROR(dynamic_self_in_mutable_property,none,
2583+
"mutable property cannot have covariant 'Self' type", ())
2584+
ERROR(dynamic_self_in_stored_property,none,
2585+
"stored property cannot have covariant 'Self' type", ())
2586+
ERROR(dynamic_self_in_mutable_subscript,none,
2587+
"mutable subscript cannot have covariant 'Self' type", ())
2588+
ERROR(dynamic_self_invalid_property,none,
2589+
"covariant 'Self' can only appear at the top level of property type", ())
2590+
ERROR(dynamic_self_invalid_subscript,none,
2591+
"covariant 'Self' can only appear at the top level of subscript element type", ())
2592+
ERROR(dynamic_self_invalid_method,none,
2593+
"covariant 'Self' can only appear at the top level of method result type", ())
25822594

25832595
//------------------------------------------------------------------------------
25842596
// MARK: Type Check Attributes

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 496; // changes for lazy storage request
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 497; // remove FuncDecl::hasDynamicSelf()
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1082,7 +1082,6 @@ namespace decls_block {
10821082
StaticSpellingKindField, // spelling of 'static' or 'class'
10831083
BCFixed<1>, // isObjC?
10841084
SelfAccessKindField, // self access kind
1085-
BCFixed<1>, // has dynamic self?
10861085
BCFixed<1>, // has forced static dispatch?
10871086
BCFixed<1>, // throws?
10881087
GenericEnvironmentIDField, // generic environment
@@ -1124,7 +1123,6 @@ namespace decls_block {
11241123
StaticSpellingKindField, // spelling of 'static' or 'class'
11251124
BCFixed<1>, // isObjC?
11261125
SelfAccessKindField, // self access kind
1127-
BCFixed<1>, // has dynamic self?
11281126
BCFixed<1>, // has forced static dispatch?
11291127
BCFixed<1>, // throws?
11301128
GenericEnvironmentIDField, // generic environment

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2412,10 +2412,16 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
24122412
isStatic = FD->isStatic();
24132413
selfAccess = FD->getSelfAccessKind();
24142414

2415+
// `self`s type for subscripts and properties
2416+
if (auto *AD = dyn_cast<AccessorDecl>(AFD)) {
2417+
if (wantDynamicSelf && AD->getStorage()
2418+
->getValueInterfaceType()->hasDynamicSelfType())
2419+
isDynamicSelf = true;
2420+
}
24152421
// Methods returning 'Self' have a dynamic 'self'.
24162422
//
24172423
// FIXME: All methods of non-final classes should have this.
2418-
if (wantDynamicSelf && FD->hasDynamicSelf())
2424+
else if (wantDynamicSelf && FD->hasDynamicSelfResult())
24192425
isDynamicSelf = true;
24202426
} else if (auto *CD = dyn_cast<ConstructorDecl>(AFD)) {
24212427
if (isInitializingCtor) {

lib/AST/ASTPrinter.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,12 +2746,13 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
27462746
}
27472747

27482748
void PrintAST::visitFuncDecl(FuncDecl *decl) {
2749+
ASTContext &Ctx = decl->getASTContext();
2750+
27492751
printDocumentationComment(decl);
27502752
printAttributes(decl);
27512753
printAccess(decl);
27522754

27532755
if (Options.PrintOriginalSourceText && decl->getStartLoc().isValid()) {
2754-
ASTContext &Ctx = decl->getASTContext();
27552756
SourceLoc StartLoc = decl->getStartLoc();
27562757
SourceLoc EndLoc;
27572758
if (!decl->getBodyResultTypeLoc().isNull()) {
@@ -2793,13 +2794,33 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
27932794
Type ResultTy = decl->getResultInterfaceType();
27942795
if (ResultTy && !ResultTy->isVoid()) {
27952796
TypeLoc ResultTyLoc = decl->getBodyResultTypeLoc();
2797+
2798+
// When printing a protocol requirement with types substituted for a
2799+
// conforming class, replace occurrences of the 'Self' generic parameter
2800+
// in the result type with DynamicSelfType, instead of the static
2801+
// conforming type.
2802+
auto *proto = dyn_cast<ProtocolDecl>(decl->getDeclContext());
2803+
if (proto && Options.TransformContext) {
2804+
auto BaseType = Options.TransformContext->getBaseType();
2805+
if (BaseType->getClassOrBoundGenericClass()) {
2806+
ResultTy = ResultTy.subst(
2807+
[&](Type t) -> Type {
2808+
if (t->isEqual(proto->getSelfInterfaceType()))
2809+
return DynamicSelfType::get(t, Ctx);
2810+
return t;
2811+
},
2812+
MakeAbstractConformanceForGenericType());
2813+
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
2814+
}
2815+
}
2816+
27962817
if (!ResultTyLoc.getTypeRepr())
27972818
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
27982819
// FIXME: Hacky way to workaround the fact that 'Self' as return
27992820
// TypeRepr is not getting 'typechecked'. See
28002821
// \c resolveTopLevelIdentTypeComponent function in TypeCheckType.cpp.
28012822
if (auto *simId = dyn_cast_or_null<SimpleIdentTypeRepr>(ResultTyLoc.getTypeRepr())) {
2802-
if (simId->getIdentifier().str() == "Self")
2823+
if (simId->getIdentifier() == Ctx.Id_Self)
28032824
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
28042825
}
28052826
Printer << " -> ";

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6179,6 +6179,12 @@ Type AbstractFunctionDecl::getMethodInterfaceType() const {
61796179
return Ty->castTo<AnyFunctionType>()->getResult();
61806180
}
61816181

6182+
bool AbstractFunctionDecl::hasDynamicSelfResult() const {
6183+
if (auto *funcDecl = dyn_cast<FuncDecl>(this))
6184+
return funcDecl->getResultInterfaceType()->hasDynamicSelfType();
6185+
return isa<ConstructorDecl>(this);
6186+
}
6187+
61826188
bool AbstractFunctionDecl::argumentNameIsAPIByDefault() const {
61836189
// Initializers have argument labels.
61846190
if (isa<ConstructorDecl>(this))

lib/AST/Type.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,9 +1817,11 @@ getObjCObjectRepresentable(Type type, const DeclContext *dc) {
18171817
return ForeignRepresentableKind::Bridged;
18181818
}
18191819

1820-
// Look through DynamicSelfType.
1820+
// DynamicSelfType is always representable in Objective-C, even if
1821+
// the class is not @objc, allowing Self-returning methods to witness
1822+
// @objc protocol requirements.
18211823
if (auto dynSelf = type->getAs<DynamicSelfType>())
1822-
type = dynSelf->getSelfType();
1824+
return ForeignRepresentableKind::Object;
18231825

18241826
// @objc classes.
18251827
if (auto classDecl = type->getClassOrBoundGenericClass()) {
@@ -1844,14 +1846,20 @@ getObjCObjectRepresentable(Type type, const DeclContext *dc) {
18441846
return ForeignRepresentableKind::Bridged;
18451847
}
18461848

1847-
// Class-constrained generic parameters, from ObjC generic classes.
1848-
if (auto tyContext = dc->getInnermostTypeContext())
1849-
if (auto clas = tyContext->getSelfClassDecl())
1850-
if (clas->hasClangNode())
1849+
if (auto tyContext = dc->getInnermostTypeContext()) {
1850+
// Class-constrained generic parameters, from ObjC generic classes.
1851+
if (auto *classDecl = tyContext->getSelfClassDecl())
1852+
if (classDecl->hasClangNode())
18511853
if (auto archetype = type->getAs<ArchetypeType>())
18521854
if (archetype->requiresClass())
18531855
return ForeignRepresentableKind::Object;
18541856

1857+
// The 'Self' parameter in a protocol is representable in Objective-C.
1858+
if (auto *protoDecl = dyn_cast<ProtocolDecl>(tyContext))
1859+
if (type->isEqual(dc->mapTypeIntoContext(protoDecl->getSelfInterfaceType())))
1860+
return ForeignRepresentableKind::Object;
1861+
}
1862+
18551863
return ForeignRepresentableKind::None;
18561864
}
18571865

@@ -2338,7 +2346,7 @@ static bool matches(CanType t1, CanType t2, TypeMatchOptions matchMode,
23382346

23392347
// Class-to-class.
23402348
if (matchMode.contains(TypeMatchFlags::AllowOverride))
2341-
if (t2->isExactSuperclassOf(t1))
2349+
if (t2->eraseDynamicSelfType()->isExactSuperclassOf(t1))
23422350
return true;
23432351

23442352
if (matchMode.contains(TypeMatchFlags::AllowABICompatible))
@@ -2983,6 +2991,9 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
29832991
// If we don't have a substituted base type, fail.
29842992
if (!substBase) return failed();
29852993

2994+
if (auto *selfType = substBase->getAs<DynamicSelfType>())
2995+
substBase = selfType->getSelfType();
2996+
29862997
// Error recovery path.
29872998
// FIXME: Generalized existentials will look here.
29882999
if (substBase->isOpenedExistential())
@@ -3569,17 +3580,19 @@ Type TypeBase::adjustSuperclassMemberDeclType(const ValueDecl *baseDecl,
35693580
}
35703581

35713582
auto type = memberType.subst(subs, SubstFlags::UseErrorType);
3583+
if (baseDecl->getDeclContext()->getSelfProtocolDecl())
3584+
return type;
35723585

3573-
if (isa<AbstractFunctionDecl>(baseDecl) &&
3574-
!baseDecl->getDeclContext()->getSelfProtocolDecl()) {
3586+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(baseDecl)) {
35753587
type = type->replaceSelfParameterType(this);
3576-
if (auto func = dyn_cast<FuncDecl>(baseDecl)) {
3577-
if (func->hasDynamicSelf()) {
3578-
type = type->replaceCovariantResultType(this, /*uncurryLevel=*/2);
3579-
}
3580-
} else if (isa<ConstructorDecl>(baseDecl)) {
3588+
if (afd->hasDynamicSelfResult())
35813589
type = type->replaceCovariantResultType(this, /*uncurryLevel=*/2);
3582-
}
3590+
} else if (auto *sd = dyn_cast<SubscriptDecl>(baseDecl)) {
3591+
if (sd->getElementInterfaceType()->hasDynamicSelfType())
3592+
type = type->replaceCovariantResultType(this, /*uncurryLevel=*/1);
3593+
} else if (auto *vd = dyn_cast<VarDecl>(baseDecl)) {
3594+
if (vd->getValueInterfaceType()->hasDynamicSelfType())
3595+
type = type->replaceCovariantResultType(this, /*uncurryLevel=*/0);
35833596
}
35843597

35853598
return type;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,10 +4109,9 @@ namespace {
41094109
// If the method has a related result type that is representable
41104110
// in Swift as DynamicSelf, do so.
41114111
if (!prop && decl->hasRelatedResultType()) {
4112-
result->setDynamicSelf(true);
4113-
resultTy = DynamicSelfType::get(dc->getSelfInterfaceType(),
4114-
Impl.SwiftContext);
4115-
assert(!dc->getSelfInterfaceType()->getOptionalObjectType());
4112+
resultTy = dc->getSelfInterfaceType();
4113+
if (dc->getSelfClassDecl())
4114+
resultTy = DynamicSelfType::get(resultTy, Impl.SwiftContext);
41164115
isIUO = false;
41174116

41184117
OptionalTypeKind nullability = OTK_ImplicitlyUnwrappedOptional;

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
571571
// Constructors and methods returning DynamicSelf return
572572
// instancetype.
573573
if (isa<ConstructorDecl>(AFD) ||
574-
(isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasDynamicSelf())) {
574+
(isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasDynamicSelfResult())) {
575575
if (errorConvention && errorConvention->stripsResultOptionality()) {
576576
printNullability(OTK_Optional, NullabilityPrintKind::ContextSensitive);
577577
} else if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
@@ -1930,6 +1930,14 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
19301930
decl = type->getDecl();
19311931
}
19321932

1933+
if (auto *proto = dyn_cast<ProtocolDecl>(decl->getDeclContext())) {
1934+
if (type->isEqual(proto->getSelfInterfaceType())) {
1935+
printNullability(optionalKind, NullabilityPrintKind::ContextSensitive);
1936+
os << "instancetype";
1937+
return;
1938+
}
1939+
}
1940+
19331941
assert(decl->getClangDecl() && "can only handle imported ObjC generics");
19341942
os << cast<clang::ObjCTypeParamDecl>(decl->getClangDecl())->getName();
19351943
printNullability(optionalKind);

lib/SIL/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2843,7 +2843,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
28432843

28442844
// If the method returns Self, substitute AnyObject for the result type.
28452845
if (auto fnDecl = dyn_cast<FuncDecl>(method.getDecl())) {
2846-
if (fnDecl->hasDynamicSelf()) {
2846+
if (fnDecl->hasDynamicSelfResult()) {
28472847
auto anyObjectTy = C.getAnyObjectType();
28482848
for (auto &dynResult : dynResults) {
28492849
auto newResultTy

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ getPartialApplyOfDynamicMethodFormalType(SILGenModule &SGM, SILDeclRef member,
110110
// Adjust the result type to replace dynamic-self with AnyObject.
111111
CanType resultType = completeMethodTy.getResult();
112112
if (auto fnDecl = dyn_cast<FuncDecl>(member.getDecl())) {
113-
if (fnDecl->hasDynamicSelf()) {
113+
if (fnDecl->hasDynamicSelfResult()) {
114114
auto anyObjectTy = SGM.getASTContext().getAnyObjectType();
115115
resultType = resultType->replaceCovariantResultType(anyObjectTy, 0)
116116
->getCanonicalType();

lib/SILGen/SILGenPoly.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -452,11 +452,8 @@ ManagedValue Transform::transform(ManagedValue v,
452452

453453
// A base class method returning Self can be used in place of a derived
454454
// class method returning Self.
455-
if (auto outputSelfType = dyn_cast<DynamicSelfType>(outputSubstType)) {
456-
if (auto inputSelfType = dyn_cast<DynamicSelfType>(inputSubstType)) {
457-
inputSubstType = inputSelfType.getSelfType();
458-
outputSubstType = outputSelfType.getSelfType();
459-
}
455+
if (auto inputSelfType = dyn_cast<DynamicSelfType>(inputSubstType)) {
456+
inputSubstType = inputSelfType.getSelfType();
460457
}
461458

462459
// - upcasts for classes

0 commit comments

Comments
 (0)