Skip to content

[InterfaceGen] Only print 'mutating' and 'nonmutating' on accessors #19459

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 3 commits into from
Sep 26, 2018

Conversation

harlanhaskins
Copy link
Contributor

@harlanhaskins harlanhaskins commented Sep 21, 2018

This PR restricts the allowed set of implicit contextual decl modifiers on accessors to just 'mutating' and 'nonmutating'.

This comes up because we'll print dynamic on accessors, so the previous patch to disallow final is insufficient.

// CHECK-NEXT: {{^}} @objc get
// CHECK-NEXT: set[[NEWVALUE]] {}
// CHECK-NEXT: }
public @objc dynamic var d: Int {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh. You shouldn't be able to mix attributes in the middle of modifiers like this…

Also, please do add tests for mutating get and nonmutating set, now that it's come up.

@harlanhaskins harlanhaskins force-pushed the nsattributedgetter branch 3 times, most recently from 6f7fad5 to 1d66ef3 Compare September 21, 2018 23:57
@harlanhaskins
Copy link
Contributor Author

@swift-ci please smoke test

@harlanhaskins
Copy link
Contributor Author

@swift-ci please smoke test

auto ctxType = ASD->getDeclContext()->getDeclaredInterfaceType();
return !ASD->isSetterMutating() &&
ASD->isInstanceMember() &&
!ctxType->hasReferenceSemantics();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slavapestov, there's not really a better way to do this check that'll handle constrained protocol extensions, right?

(Also, the ASD->isInstanceMember check isn't quite right; if it's a non-instance member, it might still have a nonmutating setter. I think it's !A && (!B || !C).)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same logic that was factored out of PrintAST::printAccessors, but I think you're right about the logic being wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out several tests were relying on the existing behavior 😞

if (asd->getGetter() == D && hasMutatingGetter(asd))
Printer << "mutating ";
if (asd->getSetter() == D && hasNonMutatingSetter(accessor->getStorage()))
Printer << "nonmutating ";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: printKeyword.

@harlanhaskins harlanhaskins force-pushed the nsattributedgetter branch 2 times, most recently from 4a64948 to da75805 Compare September 25, 2018 21:12
// PASS_RW_PROP_GET_SET-NEXT: {{^}} static var extStaticProp: Int { get set }{{$}}
// PASS_RW_PROP_NO_GET_SET-NEXT: {{^}} static var extStaticProp: Int{{$}}
// PASS_RW_PROP_GET_SET-NEXT: {{^}} static var extStaticProp: Int { get nonmutating set }{{$}}
// PASS_RW_PROP_NO_GET_SET-NEXT: {{^}} static var extStaticProp: Int { get nonmutating set }{{$}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrose-apple What do you think about fallout like this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's incorrect; those are mutating sets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh. You're right.

@harlanhaskins harlanhaskins force-pushed the nsattributedgetter branch 2 times, most recently from 1013ef1 to cd70f0f Compare September 25, 2018 22:58
@harlanhaskins
Copy link
Contributor Author

@swift-ci please smoke test

@harlanhaskins
Copy link
Contributor Author

@jrose-apple I think this is correct now.

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whew, I think this is finally it.

lib/AST/Decl.cpp Outdated
case AccessorKind::Modify:
return false;
}
llvm_unreachable("bad addressor kind");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy/paste error:"addressor" instead of "accessor". Also, the switch statement is over-indented.

// RUN: %FileCheck %s < %t/Test.swiftinterface
// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-interface-path - -module-name Test | %FileCheck %s

// REQUIRES: objc_interop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this, Saleem's been having us put -enable-objc-interop in the RUN lines. That works as long as you don't need the ObjC runtime.

@harlanhaskins
Copy link
Contributor Author

@swift-ci please smoke test


@inlinable public func foo() {
let x = MyObjCClass()
// CHECK: objc_method %{{[0-9]+}} : $MyObjCClass, #MyObjCClass.a!getter.1.foreign
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrose-apple Do you think this test is sufficient? It runs on the SIL from both the original source and the generated interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a check for a subscript too, but other than that yes, this looks good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o /dev/null -disable-objc-attr-requires-foundation-module -emit-interface-path %t/dynamic_accessors.swiftinterface %s
// RUN: %target-swift-emit-silgen -disable-objc-attr-requires-foundation-module %s | %FileCheck %s
// RUN: %target-swift-frontend -emit-silgen -disable-objc-attr-requires-foundation-module %t/dynamic_accessors.swiftinterface | %FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing -enable-objc-interop on these. (I'm checking because I just got bitten by it.)

@harlanhaskins
Copy link
Contributor Author

@swift-ci please smoke test

@harlanhaskins harlanhaskins merged commit 2aac886 into swiftlang:master Sep 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants