Skip to content

Fix @escaping printing #4905

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 5 commits into from
Sep 23, 2016
Merged

Conversation

milseman
Copy link
Member

@milseman milseman commented Sep 21, 2016

[Cleanup] Drop needless TupleTypeElt constructor calls

Now that TupleTypeElts are simpler in Swift 3 (though they're about to
become more complicated for other reasons), most of the cases where we
are explicitly constructing ones are really just plain copies or can
otherwise use existing helper functions.

[AST] Create ParameterTypeFlags and put them on function params

Long term, we want to refactor the AST to reflect the current
programming model in Swift. This would include refactoring
FunctionType to take a list of ParameterTypeElt, or something with a
better name, that can contain both the type and flags/bits that are
only specific to types in parameter position, such as @autoclosure and
@escaping. At the same time, noescape-by-default has severely hurt our
ability to print types without significant context, as we either have
to choose to too aggressively print @escaping or not print it in every
situation it occurs, or both.

As a gentle step towards the final solution, without uprooting our
overall AST structure, and as a way towards fixing the @escaping
printing ails, put these bits on the TupleTypeElt and ParenType, which
will serve as a model for what ParameterTypeElt will be like in the
future. Re-use these flags on CallArgParam, to leverage shared
knowledge in the type system. It is a little painful to tack onto
these types, but it's minor and will be overhauled soon, which will
eventually result in size savings and less complexity overall.

This includes all the constraint system adjustments to make these
types work and influence type equality and overload resolution as
desired. They are encoded in the module format. Additional tests
added.

[ASTPrinter] Switch to new ParameterTypeFlags

Switch printing off of using Function's ExtInfo for autoclosure and
escaping, and onto the ParameterTypeFlags, which let us do precise and
accurate context-sensitive printing of these parameter type
attributes. This fixes a huge list of issues where we were printing
@escaping for things like optional ObjC completion handlers, among
many others. We now correctly print @escaping in more places, and
don't print it when it's not correct.

Also updates the dumper to be consistent and give a good view of the
AST as represented in memory. Tests updated, more involved testing
coming soon.

Resolves SR-2324, and potentially many other duplicates. I will be re-evaluating each of the SRs to see which have probably been fixed, as well as expanding corner case test coverage in lit.

I want to get this process started so that improvements can start landing.

@milseman milseman force-pushed the escaping_printing_fix_clean branch from a2afa24 to 7c4ac88 Compare September 21, 2016 20:59
@milseman
Copy link
Member Author

@swift-ci please test

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.

Nice work. It still feels kind of big for a 3.0.1, but on the other hand it's definitely the direction we want to move in, and it makes some things a lot better.

@@ -1353,6 +1353,11 @@ class TupleTypeElt {
TupleTypeElt getWithType(Type T) const {
return TupleTypeElt(T, getName(), isVararg());
}

/// Retrieve a copy of this tuple type element with the name replaced.
TupleTypeElt getWithName(Identifier name = Identifier()) const {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: It seems weird to be able to call getWithName() and not have to explicitly specify "no name".


ParameterTypeFlags() : value(None) {}

ParameterTypeFlags(uint8_t val) : value(val) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

This probably shouldn't be public.

bool isAutoClosure() const { return 0 != (value & AutoClosure); }
bool isEscaping() const { return 0 != (value & Escaping); }

bool operator==(const ParameterTypeFlags &other) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: const.

@@ -1351,12 +1411,20 @@ class TupleTypeElt {

/// Retrieve a copy of this tuple type element with the type replaced.
TupleTypeElt getWithType(Type T) const {
return TupleTypeElt(T, getName(), isVararg());
return TupleTypeElt(T, getName(), isVararg(), isAutoClosure(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't these use the constructor that takes a ParameterTypeFlags?


/// Retrieve a copy of this tuple type element with the type and name
/// replaced.
TupleTypeElt getWithTypeAndName(Type T, Identifier name) const {
Copy link
Contributor

@jrose-apple jrose-apple Sep 21, 2016

Choose a reason for hiding this comment

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

I feel like it's fine to use constructor syntax for this one rather than a getWith… method. TupleTypeElt(T, name, orig.getParameterFlags().

printParameterFlags(Printer, Options, paramFlags);

// Special case, if we're not going to use the type repr printing, peek
// through the paren types so that we don't print excessive @escapings
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: period.

Copy link
Member Author

Choose a reason for hiding this comment

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

What? Please clarify?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, sorry. A lot of your comments are missing final periods. Very tiny nitpick!

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I didn't realize there was a convention there
(period in this comment intentionally absent just to drive you crazy :-)


for (unsigned CurrPattern = 0, NumPatterns = BodyParams.size();
CurrPattern != NumPatterns; ++CurrPattern) {
printParameterList(BodyParams[CurrPattern], /*Curried=*/CurrPattern > 0,
// Be extra careful in the event of printing mal-formed ASTs
auto paramListType = parameterListTypes.size() > CurrPattern
Copy link
Contributor

Choose a reason for hiding this comment

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

Off-by-one error here.

@@ -672,7 +672,7 @@ func overloadSetResultType(_ a : Int, b : Int) -> Int {
// https://twitter.com/_jlfischer/status/712337382175952896
// TODO: <rdar://problem/27391581> QoI: Nonsensical "binary operator '&&' cannot be applied to two 'Bool' operands"
return a == b && 1 == 2 // expected-error {{binary operator '&&' cannot be applied to two 'Bool' operands}}
// expected-note @-1 {{expected an argument list of type '(Bool, @autoclosure () throws -> Bool)'}}
// expected-note @-1 {{expected an argument list of type '(Bool, () throws -> Bool)'}}
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a problem; the autoclosure is important to the call site.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, right, @autoclosure is irrelevant inside of the definition but totally relevant to the caller

Copy link
Member Author

@milseman milseman Sep 22, 2016

Choose a reason for hiding this comment

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

Also, code might be a little different for operators. I'll look into this, and also expand test coverage for operators with e.g. escaping

Copy link
Member Author

Choose a reason for hiding this comment

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

Argh... This is CSDiag having it's own custom printer. I'll try to make it use the ASTPrinter...

func testDarwinBooleanFnToBlockTypedef(_: DarwinBooleanFn) -> DarwinBooleanBlock
func testCBoolFnToBlockTypedef(_: @escaping CBoolFn) -> CBoolBlock
func testObjCBoolFnToBlockTypedef(_: @escaping ObjCBoolFn) -> ObjCBoolBlock
func testDarwinBooleanFnToBlockTypedef(_: @escaping DarwinBooleanFn) -> DarwinBooleanBlock
Copy link
Contributor

Choose a reason for hiding this comment

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

Sweet!

func produceDarwinBooleanBlockTypedef(_ outBlock: AutoreleasingUnsafeMutablePointer<(@escaping @convention(block) (DarwinBoolean) -> DarwinBoolean)?>)
func produceCBoolBlockTypedef(_ outBlock: AutoreleasingUnsafeMutablePointer<(@convention(block) (Bool) -> Bool)?>)
func produceObjCBoolBlockTypedef(_ outBlock: AutoreleasingUnsafeMutablePointer<(@convention(block) (ObjCBool) -> ObjCBool)?>)
func produceDarwinBooleanBlockTypedef(_ outBlock: AutoreleasingUnsafeMutablePointer<(@convention(block) (DarwinBoolean) -> DarwinBoolean)?>)
Copy link
Contributor

Choose a reason for hiding this comment

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

Also sweet!

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 7c4ac884227ddd568a3e993a58d9b66be531bfed
Test requested by - @milseman

@milseman
Copy link
Member Author

(build failure was Foundation casting with Any)

@milseman
Copy link
Member Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 111b2074bc838b34ce53f5df4426006b5530ebb8
Test requested by - @milseman

@@ -2742,7 +2742,7 @@ void PrintAST::printFunctionParameters(AbstractFunctionDecl *AFD) {
for (unsigned CurrPattern = 0, NumPatterns = BodyParams.size();
CurrPattern != NumPatterns; ++CurrPattern) {
// Be extra careful in the event of printing mal-formed ASTs
auto paramListType = parameterListTypes.size() > CurrPattern
auto paramListType = CurrPattern < parameterListTypes.size()
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't off-by-one. Thanks for putting this in the conventional order so that I don't get confused.

Now that TupleTypeElts are simpler in Swift 3 (though they're about to
become more complicated for other reasons), most of the cases where we
are explicitly constructing ones are really just plain copies or can
otherwise use existing helper functions.

NFC
Long term, we want to refactor the AST to reflect the current
programming model in Swift. This would include refactoring
FunctionType to take a list of ParameterTypeElt, or something with a
better name, that can contain both the type and flags/bits that are
only specific to types in parameter position, such as @autoclosure and
@escaping. At the same time, noescape-by-default has severely hurt our
ability to print types without significant context, as we either have
to choose to too aggressively print @escaping or not print it in every
situation it occurs, or both.

As a gentle step towards the final solution, without uprooting our
overall AST structure, and as a way towards fixing the @escaping
printing ails, put these bits on the TupleTypeElt and ParenType, which
will serve as a model for what ParameterTypeElt will be like in the
future. Re-use these flags on CallArgParam, to leverage shared
knowledge in the type system. It is a little painful to tack onto
these types, but it's minor and will be overhauled soon, which will
eventually result in size savings and less complexity overall.

This includes all the constraint system adjustments to make these
types work and influence type equality and overload resolution as
desired. They are encoded in the module format. Additional tests
added.
Switch printing off of using Function's ExtInfo for autoclosure and
escaping, and onto the ParameterTypeFlags, which let us do precise and
accurate context-sensitive printing of these parameter type
attributes. This fixes a huge list of issues where we were printing
@escaping for things like optional ObjC completion handlers, among
many others. We now correctly print @escaping in more places, and
don't print it when it's not correct.

Also updates the dumper to be consistent and give a good view of the
AST as represented in memory. Tests updated, more involved testing
coming soon.
@milseman milseman force-pushed the escaping_printing_fix_clean branch from 111b207 to 81acf49 Compare September 22, 2016 19:24
@milseman milseman force-pushed the escaping_printing_fix_clean branch from 81acf49 to 0bb868a Compare September 22, 2016 19:24
@milseman
Copy link
Member Author

I rebased, and did a minor version bump because I think the old modules were getting mixed in.

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 111b2074bc838b34ce53f5df4426006b5530ebb8
Test requested by - @milseman

@milseman
Copy link
Member Author

12:34:39 ERROR: Error cloning remote repo 'origin'
12:34:39 hudson.plugins.git.GitException: Could not init /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 111b2074bc838b34ce53f5df4426006b5530ebb8
Test requested by - @milseman

@milseman
Copy link
Member Author

@jrose-apple I believe I have addressed all of your feedback for this PR, can you confirm?

@milseman milseman force-pushed the escaping_printing_fix_clean branch from 16c72cb to 4324d8f Compare September 22, 2016 20:19
@milseman
Copy link
Member Author

milseman commented Sep 22, 2016

Passes for me locally, waiting on CI to come back up. Note the this PR doesn't fix one corner case where you have nested closures in closures, and at the same time are switching off between the Decl ASTPrinter and the TypeRepr printer. Unlikely to get the fix in for that for 3.0.1, but probably for later. Regardless, that's a niche case, and better to get a fix for the super common scenarios in quickly.

@milseman
Copy link
Member Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 0bb868a
Test requested by - @milseman

@shahmishal
Copy link
Member

@swift-ci Please test OS X

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 4324d8f
Test requested by - @shahmishal

@milseman
Copy link
Member Author

@shahmishal 14:28:52 Setting status of 4324d8f to FAILURE with url https://ci.swift.org/job/swift-PR-osx/3756/ and message: 'Build finished. No test results found.'

Any idea what failed?

@shahmishal
Copy link
Member

This is the error it failed at: Do we need to do clean build?

<unknown>:0: error: module file was created by an older version of the compiler; rebuild 'CoreLocation' and try again: /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/buildbot_incremental/swift-macosx-x86_64/./lib/swift/watchos/armv7k/CoreLocation.swiftmodule

@jrose-apple
Copy link
Contributor

That usually means a missing dependency. @jckarter, did you get a chance to look through your new overlays and anything that might depend on them?

@milseman
Copy link
Member Author

@shahmishal yeah, can you please do a clean build?

@shahmishal
Copy link
Member

@swift-ci Please clean test OS X

Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

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

This looks great.

/// escaping.
class ParameterTypeFlags {
enum ParameterFlags : uint8_t {
None = 0,
Copy link
Member

Choose a reason for hiding this comment

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

None seems unnecessary, since we're working with option sets.

@milseman
Copy link
Member Author

@swift-ci please smoke test Linux Platform

1 similar comment
@shahmishal
Copy link
Member

@swift-ci please smoke test Linux Platform

@milseman milseman merged commit 3619738 into swiftlang:master Sep 23, 2016
tkremenek added a commit that referenced this pull request Sep 23, 2016
@milseman milseman deleted the escaping_printing_fix_clean branch September 29, 2016 18:12
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.

6 participants