mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Check default arguments even if a function has no body (#18864)
This is needed for textual interfaces, but the behavior doesn't have to be specific to that, since functions without bodies don't come up in other situations.
This commit is contained in:
@@ -3123,12 +3123,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (FD->hasBody()) {
|
||||
// Record the body.
|
||||
TC.definedFunctions.push_back(FD);
|
||||
} else if (requiresDefinition(FD)) {
|
||||
if (requiresDefinition(FD) && !FD->hasBody()) {
|
||||
// Complain if we should have a body.
|
||||
TC.diagnose(FD->getLoc(), diag::func_decl_without_brace);
|
||||
} else {
|
||||
// Record the body.
|
||||
TC.definedFunctions.push_back(FD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3354,20 +3354,18 @@ public:
|
||||
AccessControlChecker::checkAccessControl(TC, CD);
|
||||
UsableFromInlineChecker::checkUsableFromInline(TC, CD);
|
||||
|
||||
if (CD->hasBody() && !CD->isMemberwiseInitializer()) {
|
||||
TC.definedFunctions.push_back(CD);
|
||||
} else if (requiresDefinition(CD)) {
|
||||
if (requiresDefinition(CD) && !CD->hasBody()) {
|
||||
// Complain if we should have a body.
|
||||
TC.diagnose(CD->getLoc(), diag::missing_initializer_def);
|
||||
} else {
|
||||
TC.definedFunctions.push_back(CD);
|
||||
}
|
||||
}
|
||||
|
||||
void visitDestructorDecl(DestructorDecl *DD) {
|
||||
TC.validateDecl(DD);
|
||||
TC.checkDeclAttributes(DD);
|
||||
|
||||
if (DD->hasBody())
|
||||
TC.definedFunctions.push_back(DD);
|
||||
TC.definedFunctions.push_back(DD);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -1537,6 +1537,7 @@ void TypeChecker::checkDefaultArguments(ParameterList *params,
|
||||
bool TypeChecker::typeCheckAbstractFunctionBodyUntil(AbstractFunctionDecl *AFD,
|
||||
SourceLoc EndTypeCheckLoc) {
|
||||
validateDecl(AFD);
|
||||
checkDefaultArguments(AFD->getParameters(), AFD);
|
||||
|
||||
if (!AFD->getBody())
|
||||
return false;
|
||||
@@ -1558,9 +1559,6 @@ bool TypeChecker::typeCheckAbstractFunctionBody(AbstractFunctionDecl *AFD) {
|
||||
if (AFD->isBodyTypeChecked())
|
||||
return false;
|
||||
|
||||
if (!AFD->getBody())
|
||||
return false;
|
||||
|
||||
FrontendStatsTracer StatsTracer(Context.Stats, "typecheck-fn", AFD);
|
||||
PrettyStackTraceDecl StackEntry("type-checking", AFD);
|
||||
|
||||
@@ -1579,7 +1577,9 @@ bool TypeChecker::typeCheckAbstractFunctionBody(AbstractFunctionDecl *AFD) {
|
||||
if (error)
|
||||
return true;
|
||||
|
||||
performAbstractFuncDeclDiagnostics(*this, AFD);
|
||||
if (AFD->getBody())
|
||||
performAbstractFuncDeclDiagnostics(*this, AFD);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1587,9 +1587,6 @@ bool TypeChecker::typeCheckAbstractFunctionBody(AbstractFunctionDecl *AFD) {
|
||||
// named function or an anonymous func expression.
|
||||
bool TypeChecker::typeCheckFunctionBodyUntil(FuncDecl *FD,
|
||||
SourceLoc EndTypeCheckLoc) {
|
||||
// Check the default argument definitions.
|
||||
checkDefaultArguments(FD->getParameters(), FD);
|
||||
|
||||
// Clang imported inline functions do not have a Swift body to
|
||||
// typecheck.
|
||||
if (FD->getClangDecl())
|
||||
@@ -1692,12 +1689,8 @@ static bool isKnownEndOfConstructor(ASTNode N) {
|
||||
|
||||
bool TypeChecker::typeCheckConstructorBodyUntil(ConstructorDecl *ctor,
|
||||
SourceLoc EndTypeCheckLoc) {
|
||||
// Check the default argument definitions.
|
||||
checkDefaultArguments(ctor->getParameters(), ctor);
|
||||
|
||||
BraceStmt *body = ctor->getBody();
|
||||
if (!body)
|
||||
return true;
|
||||
assert(body);
|
||||
|
||||
// For constructors, we make sure that the body ends with a "return" stmt,
|
||||
// which we either implicitly synthesize, or the user can write. This
|
||||
@@ -1826,8 +1819,7 @@ bool TypeChecker::typeCheckDestructorBodyUntil(DestructorDecl *DD,
|
||||
StmtChecker SC(*this, static_cast<AbstractFunctionDecl *>(DD));
|
||||
SC.EndTypeCheckLoc = EndTypeCheckLoc;
|
||||
BraceStmt *Body = DD->getBody();
|
||||
if (!Body)
|
||||
return false;
|
||||
assert(Body);
|
||||
|
||||
bool HadError = SC.typeCheckBody(Body);
|
||||
|
||||
|
||||
22
test/ModuleInterface/DefaultArgs.swiftinterface
Normal file
22
test/ModuleInterface/DefaultArgs.swiftinterface
Normal file
@@ -0,0 +1,22 @@
|
||||
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
|
||||
|
||||
class SomeClass {
|
||||
// Has defaults, but no body.
|
||||
public func hasDefaults(a: Int = 4, b: Int = 1 + 2)
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S11DefaultArgs9SomeClassC11hasDefaults1a1bySi_SitFfA_
|
||||
// CHECK: integer_literal $Builtin.Int2048, 4
|
||||
// CHECK: end sil function '$S11DefaultArgs9SomeClassC11hasDefaults1a1bySi_SitFfA_'
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S11DefaultArgs9SomeClassC11hasDefaults1a1bySi_SitFfA0_
|
||||
// CHECK: integer_literal $Builtin.Int2048, 1
|
||||
// CHECK: integer_literal $Builtin.Int2048, 2
|
||||
// CHECK: function_ref @$SSi1poiyS2i_SitFZ
|
||||
// CHECK: end sil function '$S11DefaultArgs9SomeClassC11hasDefaults1a1bySi_SitFfA0_'
|
||||
|
||||
public init(a: Int = 5)
|
||||
|
||||
// CHECK-LABEL: sil hidden @$S11DefaultArgs9SomeClassC1aACSi_tcfcfA_
|
||||
// CHECK: integer_literal $Builtin.Int2048, 5
|
||||
// CHECK: end sil function '$S11DefaultArgs9SomeClassC1aACSi_tcfcfA_'
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import MutualDependency
|
||||
|
||||
public protocol MyDelegate {
|
||||
func doSomething(sender: MyClass)
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// RUN: %target-swift-frontend -typecheck %s -enable-source-import -I %S/Inputs -parse-as-library
|
||||
// RUN: %target-swift-frontend -typecheck %s -enable-source-import -I %S/Inputs
|
||||
// RUN: %target-swift-frontend -typecheck %S/Inputs/MutualDependencyHelper.swift -enable-source-import -I %S
|
||||
|
||||
// RUN: %target-swift-frontend -interpret -I %S/Inputs -enable-source-import %s -verify
|
||||
|
||||
|
||||
import MutualDependencyHelper
|
||||
|
||||
public class MyClass {
|
||||
public var delegate : MyDelegate // expected-note {{'self.delegate' not initialized}}
|
||||
|
||||
public init() {} // expected-error {{return from initializer without initializing all stored properties}}
|
||||
}
|
||||
Reference in New Issue
Block a user