Skip to content

AST: Remove FuncDecl::getDynamicSelf() and getDynamicSelfInterface() #6022

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
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
9 changes: 0 additions & 9 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5043,15 +5043,6 @@ class FuncDecl final : public AbstractFunctionDecl,
void setDynamicSelf(bool hasDynamicSelf) {
FuncDeclBits.HasDynamicSelf = hasDynamicSelf;
}

/// Retrieve the dynamic \c Self type for this method, or a null type if
/// this method does not have a dynamic \c Self return type.
DynamicSelfType *getDynamicSelf() const;

/// Retrieve the dynamic \c Self interface type for this method, or
/// a null type if this method does not have a dynamic \c Self
/// return type.
DynamicSelfType *getDynamicSelfInterface() const;

/// Determine whether this method has an archetype \c Self return
/// type. This is when a method defined in a protocol extension
Expand Down
61 changes: 17 additions & 44 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3959,12 +3959,19 @@ static Type getSelfTypeForContainer(AbstractFunctionDecl *theMethod,
bool isInitializingCtor,
bool wantInterfaceType) {
auto *dc = theMethod->getDeclContext();
auto &Ctx = dc->getASTContext();

// Determine the type of the container.
Type containerTy = wantInterfaceType ? dc->getDeclaredInterfaceType()
auto containerTy = wantInterfaceType ? dc->getDeclaredInterfaceType()
: dc->getDeclaredTypeInContext();
if (!containerTy)
return ErrorType::get(dc->getASTContext());
if (!containerTy || containerTy->hasError())
return ErrorType::get(Ctx);

// Determine the type of 'self' inside the container.
auto selfTy = wantInterfaceType ? dc->getSelfInterfaceType()
: dc->getSelfTypeInContext();
if (!selfTy || selfTy->hasError())
return ErrorType::get(Ctx);

bool isStatic = false;
bool isMutating = false;
Expand All @@ -3977,8 +3984,9 @@ static Type getSelfTypeForContainer(AbstractFunctionDecl *theMethod,
// The non-interface type of a method that returns DynamicSelf
// uses DynamicSelf for the type of 'self', which is important
// when type checking the body of the function.
if (!wantInterfaceType)
selfTypeOverride = FD->getDynamicSelf();
if (!wantInterfaceType && FD->hasDynamicSelf()) {
selfTy = DynamicSelfType::get(selfTy, Ctx);
}
} else if (isa<ConstructorDecl>(theMethod)) {
if (isInitializingCtor) {
// initializing constructors of value types always have an implicitly
Expand All @@ -3993,37 +4001,19 @@ static Type getSelfTypeForContainer(AbstractFunctionDecl *theMethod,
isMutating = true;
}

Type selfTy = selfTypeOverride;
if (!selfTy) {
// For a protocol, the type of 'self' is the parameter type 'Self', not
// the protocol itself.
if (containerTy->is<ProtocolType>()) {
if (wantInterfaceType)
selfTy = dc->getSelfInterfaceType();
else
selfTy = dc->getSelfTypeInContext();
} else
selfTy = containerTy;
}

// If the self type couldn't be computed, or is the result of an
// upstream error, return an error type.
if (!selfTy || selfTy->hasError())
return ErrorType::get(dc->getASTContext());

// 'static' functions have 'self' of type metatype<T>.
if (isStatic)
return MetatypeType::get(selfTy, dc->getASTContext());
return MetatypeType::get(selfTy, Ctx);

// Reference types have 'self' of type T.
if (containerTy->hasReferenceSemantics())
return selfTy;

// Mutating methods are always passed inout so we can receive the side
// effect.
if (isMutating)
return InOutType::get(selfTy);

// Nonmutating methods on structs and enums pass the receiver by value.
return selfTy;
}
Expand Down Expand Up @@ -4530,23 +4520,6 @@ void DestructorDecl::setSelfDecl(ParamDecl *selfDecl) {
}
}


DynamicSelfType *FuncDecl::getDynamicSelf() const {
if (!hasDynamicSelf())
return nullptr;

return DynamicSelfType::get(getDeclContext()->getSelfTypeInContext(),
getASTContext());
}

DynamicSelfType *FuncDecl::getDynamicSelfInterface() const {
if (!hasDynamicSelf())
return nullptr;

return DynamicSelfType::get(getDeclContext()->getSelfInterfaceType(),
getASTContext());
}

SourceRange FuncDecl::getSourceRange() const {
SourceLoc StartLoc = getStartLoc();
if (StartLoc.isInvalid() ||
Expand Down
6 changes: 2 additions & 4 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3287,10 +3287,9 @@ namespace {
// in Swift as DynamicSelf, do so.
if (decl->hasRelatedResultType()) {
result->setDynamicSelf(true);
resultTy = result->getDynamicSelfInterface();
assert(resultTy && "failed to get dynamic self");
resultTy = DynamicSelfType::get(dc->getSelfInterfaceType(),
Impl.SwiftContext);

Type dynamicSelfTy = result->getDynamicSelfInterface();
OptionalTypeKind nullability = OTK_ImplicitlyUnwrappedOptional;
if (auto typeNullability = decl->getReturnType()->getNullability(
Impl.getClangASTContext())) {
Expand All @@ -3299,7 +3298,6 @@ namespace {
}
if (nullability != OTK_None && !errorConvention.hasValue()) {
resultTy = OptionalType::get(nullability, resultTy);
dynamicSelfTy = OptionalType::get(nullability, dynamicSelfTy);
}

// Update the method type with the new result type.
Expand Down
6 changes: 5 additions & 1 deletion lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,9 @@ static Type getResultType(TypeChecker &TC, FuncDecl *fn, Type resultType) {

// Rewrite dynamic self to the appropriate interface type.
if (resultType->is<DynamicSelfType>()) {
return fn->getDynamicSelfInterface();
return DynamicSelfType::get(
fn->getDeclContext()->getSelfInterfaceType(),
TC.Context);
}

// Weird hacky special case.
Expand Down Expand Up @@ -611,6 +613,8 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func,
auto *dc = ctor->getDeclContext();

funcTy = dc->getSelfInterfaceType();
if (!funcTy)
funcTy = ErrorType::get(Context);

// Adjust result type for failability.
if (ctor->getFailability() != OTK_None)
Expand Down
4 changes: 3 additions & 1 deletion lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,9 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
// The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
// while the 'Self' type is more than just a reference to a TypeDecl.

return func->getDynamicSelf();
return DynamicSelfType::get(
func->getDeclContext()->getSelfTypeInContext(),
TC.Context);
}

// For lookups within the generic signature, look at the generic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

// RUN: not --crash %target-swift-frontend %s -typecheck
// RUN: not %target-swift-frontend %s -typecheck
// Crash type: memory error ("Invalid read of size 2")
class A{func b->Self{{{}}class B<n{let a=self