Skip to content

[Sema] Implement SE-0110 #4102

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 1 commit into from
Aug 15, 2016
Merged

[Sema] Implement SE-0110 #4102

merged 1 commit into from
Aug 15, 2016

Conversation

MnO2
Copy link
Contributor

@MnO2 MnO2 commented Aug 8, 2016

What's in this pull request?

[Sema] Implement SE-0010

This commit built upon the work of Pull Request 3895 by @dduan. Apart from the work to make the following work

let f: (Int, Int) -> Void = { x in  } // this is now an error

This patch also implement the part 2 mentioned in the #3895

let g: ((Int, Int)) -> Void = { y in  } // y should have type (Int, Int)

Resolved bug number: (SR-2008)


Before merging this pull request to apple/swift repository:

  • Test pull request on Swift continuous integration.

Triggering Swift CI

The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:

Smoke Testing

Platform Comment
All supported platforms @swift-ci Please smoke test
All supported platforms @swift-ci Please smoke test and merge
OS X platform @swift-ci Please smoke test OS X platform
Linux platform @swift-ci Please smoke test Linux platform

A smoke test on macOS does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library only for macOS. Simulator standard libraries and
    device standard libraries are not built.
  3. lldb is not built.
  4. The test and validation-test targets are run only for macOS. The optimized
    version of these tests are not run.

A smoke test on Linux does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library incrementally.
  3. lldb is built incrementally.
  4. The swift test and validation-test targets are run. The optimized version of these
    tests are not run.
  5. lldb is tested.

Validation Testing

Platform Comment
All supported platforms @swift-ci Please test
All supported platforms @swift-ci Please test and merge
OS X platform @swift-ci Please test OS X platform
OS X platform @swift-ci Please benchmark
Linux platform @swift-ci Please test Linux platform

Lint Testing

Language Comment
Python @swift-ci Please Python lint

Note: Only members of the Apple organization can trigger swift-ci.

This commit built upon the work of Pull Request 3895. Apart from the
work to make the following work

let f: (Int, Int) -> Void = { x in  } // this is now an error

This patch also implement the part 2 mentioned in the #3895

let g: ((Int, Int)) -> Void = { y in  } // y should have type (Int, Int)

@dduan
Copy link
Contributor

dduan commented Aug 8, 2016

@swift-ci test

@@ -2482,6 +2482,9 @@ ERROR(tuple_pattern_in_non_tuple_context,none,
ERROR(closure_argument_list_tuple,none,
"contextual closure type %0 expects %1 argument%s1, "
"but %2 were used in closure body", (Type, unsigned, unsigned))
ERROR(closure_argument_list_single_tuple,none,
Copy link
Contributor

@CodaFi CodaFi Aug 8, 2016

Choose a reason for hiding this comment

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

This looks like it's going to need a singular and plural %select for were/was.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to use %switch but couldn't find it in the code base, therefore I use %select instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

My bad. You're correct.

@CodaFi
Copy link
Contributor

CodaFi commented Aug 8, 2016

I noticed that this pull request seems to be digging out the underlying pointer from the type structures it's using. You shouldn't have to do that. Instead, try to either use the invariants of the surrounding conditions and their types or use getAs<T>.

@dduan dduan changed the title [Sema] Implement SE-0010 [Sema] Implement SE-0110 Aug 8, 2016
@MnO2
Copy link
Contributor Author

MnO2 commented Aug 9, 2016

I've updated the code by the good suggestions. Using CanType makes the code much shorter. And I have used getType()->is<T>() with castTo<T>() as much as possible. However, due to the requirement of keeping the type sugared, I still write getPointer() in one of the places until I found a good alternative. Also I documented my thinking according to the feedback. Thanks for reviewing!

@@ -202,7 +202,7 @@ func acceptNothingToInt (_: () -> Int) {}
func testAcceptNothingToInt(ac1: @autoclosure () -> Int) {
// expected-note@-1{{parameter 'ac1' is implicitly non-escaping because it was declared @autoclosure}}
acceptNothingToInt({ac1($0)})
// expected-error@-1{{cannot convert value of type '(_) -> Int' to expected argument type '() -> Int'}}
// expected-error@-1{{contextual closure type '() -> Int' expects 0 arguments, but 1 were used in closure body}}
Copy link
Contributor

Choose a reason for hiding this comment

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

Did this diagnostic not change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the case where contextual type having empty parameter list (ex: () -> Int), I added a constraint where the number of elements has to be greater than or equal to 2. (at TypeCheckConstraints.cpp:1537). The rational behind is because in the case of () -> Int, the parameter would be derived as a TupleType with 0 elements but not ParenType, and for the case of (Int) -> Int it would be a sugared ParenType. And for the case empty tuple it would fall through and catched by TypeCheckPattern.cpp:1573, I cannot handle the case of empty tuple and early return is because it is still likely the closure has zero input, and that would be best delegated to coerceParameterListToType

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean the were/was distinction. This should be in the singular.

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 diagnostic is from closure_argument_list_tuple where I didn't touch (only use it). What I added was closure_argument_list_single_tuple. I think it is a minor bug sticking with closure_argument_list_tuple where it didn't use %select for {was|were}. Do you think the best way would be to put it in this commit? or have a separate bug fixing commit instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's up to you whether you'd like to fix it here or not - it is relevant to the changes you're making. If you choose not to let me know so I can file a JIRA starterbug about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've made the change. I decided to change in this pull request since I realized that the case of singular was would only be triggered by the change in this pull request. Before the change, all of the parameters would be treated as one single tuple and assigned to the single parameter of closure.

"but %2 %select{was|were}3 used in closure body", (Type, unsigned, unsigned, bool))
ERROR(closure_argument_list_single_tuple,none,
"contextual closure type specifies %0, but %1 %select{was|were}2 used in closure body, "
"try add extra parenthesis around the single tuple argument", (Type, unsigned, bool))
Copy link
Member

Choose a reason for hiding this comment

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

Could you add some test cases for this error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the singular was case, it has been covered by test/expr/closure/default_args.swift:6 and 7. For the plural case, it was covered by test/Constraints/closures.swift:118, 121, 127, 130, 135. Is there anything I missed or a better way to organize the tests?

Copy link
Member

Choose a reason for hiding this comment

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

I don't see expected-error that includes try add extra parenthesis around the single tuple argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

my bad. I mis-read your comment as the change on line:2488 since they are quoted as one green block. I would add it, thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Grammar nit: "try adding extra parentheses"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a test case on test/Constraints/closures.swift:326 and corrected the grammar. :)

paramListType);
auto fnType = FunctionType::get(paramListType->getDesugaredType(), FN->getResult());
diagnose(P->getStartLoc(), diag::closure_argument_list_tuple,
fnType, tupleTy->getNumElements(), P->size(), (P->size() > 1));
Copy link
Contributor

@CodaFi CodaFi Aug 14, 2016

Choose a reason for hiding this comment

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

Just to be future-proof: Invert the select and make the P->size() > 1 into P->size() == 1 so we can report 0 in the (bizarre) plural correctly.

This commit built upon the work of Pull Request 3895. Apart from the
work to make the following work

```swift
let f: (Int, Int) -> Void = { x in  } // this is now an error
```

This patch also implement the part 2 mentioned in the swiftlang#3895

```swift
let g: ((Int, Int)) -> Void = { y in  } // y should have type (Int, Int)
```
@CodaFi
Copy link
Contributor

CodaFi commented Aug 14, 2016

This is looking fantastic.

@swift-ci please smoke test.

@CodaFi
Copy link
Contributor

CodaFi commented Aug 14, 2016

@swift-ci please smoke test Linux platform.

@MnO2
Copy link
Contributor Author

MnO2 commented Aug 15, 2016

hmm, not sure the root of cause of smoke test failure on Linux.

One of the failure Traceback

======================================================================
FAIL: test_equality_operators_fileprivate_dwarf (TestEqualityOperators.TestUnitTests)
   Test that we resolve expression operators correctly
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1483, in dwarf_test_method
    return attrvalue(self)
  File "/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/lldb/packages/Python/lldbsuite/test/decorators.py", line 121, in wrapper
    func(*args, **kwargs)
  File "/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/lldb/packages/Python/lldbsuite/test/lang/swift/expression/equality_operators/TestEqualityOperators.py", line 37, in test_equality_operators_fileprivate
    self.do_test("Fooey.CompareEm1", "true", 1)
  File "/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/lldb/packages/Python/lldbsuite/test/lang/swift/expression/equality_operators/TestEqualityOperators.py", line 79, in do_test
    self.assertTrue(len(threads) == 1)
AssertionError: False is not True
Config=x86_64-/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/buildbot_linux/llvm-linux-x86_64/bin/clang-3.9

@CodaFi
Copy link
Contributor

CodaFi commented Aug 15, 2016

That's not your fault and you don't have to worry about it. Your patch passed our tests.

@CodaFi
Copy link
Contributor

CodaFi commented Aug 15, 2016

Now that LLDB has been dealt with, let's land this sucker.

@swift-ci please smoke test and merge.

@swift-ci swift-ci merged commit 83f2eb0 into swiftlang:master Aug 15, 2016
@CodaFi
Copy link
Contributor

CodaFi commented Aug 15, 2016

Thank you @MnO2! Please don't forget to update the CHANGELOG and resolve SR-2008

@DougGregor
Copy link
Member

Hrm. So, we're past the point where we can make source changes to Swift 3. We'll need to gate this feature on an as-yet-undesigned version flag.

@MnO2
Copy link
Contributor Author

MnO2 commented Aug 19, 2016

I can help on that, but it would be great to have a reference commit on how to gate a feature so that I can figure out how to do it easily.

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.

7 participants