Skip to content

Remove even more usages of DeclChecker::IsFirstPass #15729

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
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
25 changes: 18 additions & 7 deletions lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2085,18 +2085,29 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
AccessLevel access = classDecl->getFormalAccess();
access = std::max(access, AccessLevel::Internal);
access = std::min(access, superclassCtor->getFormalAccess());

ctor->setAccess(access);

// Inherit the @usableFromInline attribute.
if (superclassCtor->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
auto *clonedAttr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
ctor->getAttrs().add(clonedAttr);
// This is really painful. We need better abstractions for dealing with
// @usableFromInline.
if (superclassCtor->getFormalAccess(/*useDC=*/nullptr,
/*isUsableFromInline=*/true)
>= AccessLevel::Public) {
if (access == AccessLevel::Internal &&
!superclassCtor->isDynamic()) {
auto *clonedAttr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
ctor->getAttrs().add(clonedAttr);
}
}

// Inherit the @inlinable attribute.
if (superclassCtor->getAttrs().hasAttribute<InlinableAttr>()) {
auto *clonedAttr = new (ctx) InlinableAttr(/*implicit=*/true);
ctor->getAttrs().add(clonedAttr);
if (ctor->getFormalAccess(/*useDC=*/nullptr,
/*isUsableFromInline=*/true)
>= AccessLevel::Public) {
if (superclassCtor->getAttrs().hasAttribute<InlinableAttr>()) {
auto *clonedAttr = new (ctx) InlinableAttr(/*implicit=*/true);
ctor->getAttrs().add(clonedAttr);
}
}

// Make sure the constructor is only as available as its superclass's
Expand Down
46 changes: 23 additions & 23 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4771,22 +4771,20 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
}

void visitFuncDecl(FuncDecl *FD) {
if (!IsFirstPass) {
if (FD->hasBody()) {
// Record the body.
TC.definedFunctions.push_back(FD);
} else if (requiresDefinition(FD)) {
// Complain if we should have a body.
TC.diagnose(FD->getLoc(), diag::func_decl_without_brace);
}

if (!IsFirstPass)
return;
}

TC.validateDecl(FD);
checkAccessControl(TC, FD);
}

if (FD->hasBody()) {
// Record the body.
TC.definedFunctions.push_back(FD);
} else if (requiresDefinition(FD)) {
// Complain if we should have a body.
TC.diagnose(FD->getLoc(), diag::func_decl_without_brace);
}
}

void visitModuleDecl(ModuleDecl *) { }

Expand Down Expand Up @@ -6297,15 +6295,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
}

void visitConstructorDecl(ConstructorDecl *CD) {
if (!IsFirstPass) {
if (CD->getBody()) {
TC.definedFunctions.push_back(CD);
} else if (requiresDefinition(CD)) {
// Complain if we should have a body.
TC.diagnose(CD->getLoc(), diag::missing_initializer_def);
}
}

if (!IsFirstPass) {
return;
}
Expand Down Expand Up @@ -6354,18 +6343,25 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

TC.checkDeclAttributes(CD);
checkAccessControl(TC, CD);

if (CD->hasBody() && !CD->isMemberwiseInitializer()) {
TC.definedFunctions.push_back(CD);
} else if (requiresDefinition(CD)) {
// Complain if we should have a body.
TC.diagnose(CD->getLoc(), diag::missing_initializer_def);
}
}

void visitDestructorDecl(DestructorDecl *DD) {
if (!IsFirstPass) {
if (DD->getBody())
TC.definedFunctions.push_back(DD);

return;
}

TC.validateDecl(DD);
TC.checkDeclAttributes(DD);

if (DD->hasBody())
TC.definedFunctions.push_back(DD);
}
};
} // end anonymous namespace
Expand Down Expand Up @@ -9037,6 +9033,7 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
// We have a designated initializer. Create an override of it.
if (auto ctor = createDesignatedInitOverride(
*this, classDecl, superclassCtor, kind)) {
Context.addSynthesizedDecl(ctor);
classDecl->addMember(ctor);
}
}
Expand Down Expand Up @@ -9267,6 +9264,9 @@ void TypeChecker::defineDefaultConstructor(NominalTypeDecl *decl) {
// Create an empty body for the default constructor. The type-check of the
// constructor body will introduce default initializations of the members.
ctor->setBody(BraceStmt::create(Context, SourceLoc(), { }, SourceLoc()));

// Make sure we type check the constructor later.
Context.addSynthesizedDecl(ctor);
}

static void validateAttributes(TypeChecker &TC, Decl *D) {
Expand Down
21 changes: 21 additions & 0 deletions test/attr/attr_inlinable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,27 @@ class Derived : Middle {
}
}

// More inherited initializers
@_fixed_layout
public class Base2 {
@inlinable
public init(x: Int) {}
}

@_fixed_layout
@usableFromInline
class Middle2 : Base2 {}

@_fixed_layout
@usableFromInline
class Derived2 : Middle2 {
@usableFromInline
@inlinable
init(y: Int) {
super.init(x: y)
}
}

// Stored property initializer expressions.
//
// Note the behavior here does not depend on the state of the -enable-resilience
Expand Down
4 changes: 3 additions & 1 deletion test/decl/overload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ struct X6<T> {

extension X6 {
var k: Int { return 0 } // expected-note{{previously declared here}}
func k() // expected-error{{invalid redeclaration of 'k()'}}
func k()
// expected-error@-1{{invalid redeclaration of 'k()'}}
// expected-error@-2{{expected '{' in body of function declaration}}
}

// Subscripting
Expand Down