Skip to content

[Parse] Separate compilation condition validation and evaluation #7955

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
May 16, 2017

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Mar 7, 2017

Fixes:
https://bugs.swift.org/browse/SR-3455
https://bugs.swift.org/browse/SR-3663
https://bugs.swift.org/browse/SR-4032
https://bugs.swift.org/browse/SR-4031

Now, compilation conditions are validated at first, then evaluated. Also, in non-Swift3 mode, && now has higher precedence than ||. (i.e. A || B && C || D are evaluated as A || (B && C) || D.)

Swift3 source breaking changes:

  • [SR-3663] This used to be accepted and evaluate to true because of short circuit without any validation.

    #if true || true * 12 = try Anything is OK?
    print("foo")
    #endif

    In this change, remaining expressions are properly validated and diagnosed if it's invalid.

Swift3 compatibility:

  • [SR-4031] Compound names are diagnosed as warnings in Swift3 mode.
    Previously all of these are silently accepted:

    #if BAR(_:)
    #elseif os(x:)(macOS)
    #elseif os(Linux(foo:bar:))
    #endif

    Now it's diagnosed with fix-it:

    warning: ignoring parentheses in compound name, which will be rejected in future version of Swift
    #if BAR(_:)
           ^~~~ 
    

    In Swift4 mode, it's rejected.

  • [SR-3663] The precedence of '||' and '&&' are still the same, and keep the short-circuit rule of Swift3. The following code evaluates to 'true'.

    #if false || true && false
    print("foo")
    #endif

@rintaro
Copy link
Member Author

rintaro commented Mar 7, 2017

@swift-ci Please smoke test

@jrose-apple jrose-apple requested review from bitjammer and CodaFi March 7, 2017 17:43
@rintaro
Copy link
Member Author

rintaro commented Mar 7, 2017

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Mar 7, 2017

@swift-ci Please smoke test

@bitjammer
Copy link
Contributor

Do we have tests that Swift 3 mode is unaffected by this change? If so, LGTM.

@rintaro rintaro force-pushed the parse-ifconfig-validate branch 3 times, most recently from 81f3210 to ce6d7f1 Compare March 8, 2017 04:09
@rintaro
Copy link
Member Author

rintaro commented Mar 8, 2017

@bitjammer Thank you!
Since this PR contains source breaking change even in Swift3 mode,
I inserted a commit adding test cases in -swift-version 3 mode.
It passes with the current master.

You can see how this PR breaks Swift3 mode here
ce6d7f1#diff-2ff9e652924c0aaf763b9ffdf4fabd94

If these breakage are unacceptable, please let me know.

@rintaro
Copy link
Member Author

rintaro commented Mar 8, 2017

@swift-ci Please smoke test

@bitjammer
Copy link
Contributor

You might email swift-dev about it.

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

Well-thought-out structure is refreshing to see here. Just one little thing to discuss that isn't pressing at all.


/// Get the identifier string of the UnresolvedDeclRefExpr.
/// Returns \c true if failed.
static bool getNameStr(Expr *E, StringRef &Name, DeclRefKind Kind) {
Copy link
Contributor

Choose a reason for hiding this comment

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

My only nitpick: I think this could be made to return an Optional<StringRef> - and probably could have a more descriptive name. Right now it matches a member of ValueDecl but does something more specific than ValueDecl's implementation.

@rintaro rintaro force-pushed the parse-ifconfig-validate branch from ce6d7f1 to e5a6375 Compare March 14, 2017 08:06
@rintaro
Copy link
Member Author

rintaro commented Mar 14, 2017

Thanks! @CodaFi
I renamed getNameStr to getDeclRefStr, and make it to return Optional<StringRef>.

@rintaro
Copy link
Member Author

rintaro commented Mar 14, 2017

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor

@rjmccall Please take a look

@CodaFi CodaFi requested a review from rjmccall March 19, 2017 18:30
@rjmccall
Copy link
Contributor

The Core Team believes this is a bug fix and it is acceptable to break strict source compatibility as long as the practical impact is low.

It would be nice to recognize improper precedence in Swift 3 mode and emit an a error with a fixit to add the proper parentheses.

Some people on the Core Team felt that you should add a warning about compound names. I don't think this is actually necessary.

@slavapestov
Copy link
Contributor

Today's core team meeting must've been pretty contentious, it went way over time until 11pm PST :-)

@rintaro
Copy link
Member Author

rintaro commented Mar 22, 2017

Thanks for discussing this!

It would be nice to recognize improper precedence in Swift 3 mode and emit an a error with a fixit to add the proper parentheses.

Sadly, parentheses can't help 😢

// test.swift
#if FOO || BAR && BAZ
  print("OK1")
#endif
#if (FOO || BAR) && BAZ
  print("OK2")
#endif
#if FOO || (BAR && BAZ)
  print("OK3")
#endif
$ swift -D BAR test.swift
OK1

We can emit a warning without fix-it, but I didn't come up with a good message for that.

@rintaro
Copy link
Member Author

rintaro commented Mar 22, 2017

May the fix-it change the behavior in Swift3? If so, how about

warning: future version of Swift have different rule for evaluating condition; add parentheses to make the condition compatible with Swift4
#if FOO || BAR && BAZ
           ^
           (         )

rintaro added 3 commits March 23, 2017 01:25
Fixes:
https://bugs.swift.org/browse/SR-3455
https://bugs.swift.org/browse/SR-3663
https://bugs.swift.org/browse/SR-4032
https://bugs.swift.org/browse/SR-4031

Now, compilation conditions are validated at first, then evaluated. Also,
in non-Swift3 mode, '&&' now has higher precedence than '||'.
'A || B && C || D' are evaluated as 'A || (B && C) || D'.

Swift3 source breaking changes:

* [SR-3663] This used to be accepted and evaluate to 'true' because of short
  circuit without any validation.

  #if true || true * 12 = try Anything is OK?
  print("foo")
  #endif

  In this change, remaining expressions are properly validated and
  diagnosed if it's invalid.

* [SR-4031] Compound name references are now diagnosed as errors.
  e.g. `#if os(foo:bar:)(macOS)` or `#if FLAG(x:y:)`

Swift3 compatibility:

* [SR-3663] The precedence of '||' and '&&' are still the same and the
  following code evaluates to 'true'.

  #if false || true && false
  print("foo")
  #endif
and make it to return 'Optional<StringRef>'
@rintaro rintaro force-pushed the parse-ifconfig-validate branch from e5a6375 to e58c77f Compare March 22, 2017 17:16
@rintaro
Copy link
Member Author

rintaro commented Mar 22, 2017

For || and &&, added warning with fix-it in Swift3 mode.

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Mar 22, 2017

@swift-ci Please smoke test

@rintaro rintaro force-pushed the parse-ifconfig-validate branch from e58c77f to 3943b8a Compare March 24, 2017 09:28
@rintaro
Copy link
Member Author

rintaro commented Mar 24, 2017

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Mar 28, 2017

Implemented warnings for compound names in compilation condition in Swift3 mode.
Now,

#if FOO(_:)
#endif

is accepted with a warning with fix-it to remove parentheses.

test.swift:1:8: warning: ignoring parentheses in compound name, which will be rejected in future version of Swift
#if FOO(_:)
       ^~~~ 

@rintaro
Copy link
Member Author

rintaro commented Mar 28, 2017

@rjmccall Any suggestion for warning messages?

@rintaro rintaro force-pushed the parse-ifconfig-validate branch from 21dac13 to bd3b2c6 Compare March 28, 2017 15:43
@rintaro
Copy link
Member Author

rintaro commented Mar 28, 2017

@swift-ci Please smoke test

@rintaro
Copy link
Member Author

rintaro commented Apr 10, 2017

@rjmccall Friendly ping :)

@CodaFi
Copy link
Contributor

CodaFi commented Apr 27, 2017

@swift-ci please test source compatibility

1 similar comment
@rintaro
Copy link
Member Author

rintaro commented Apr 29, 2017

@swift-ci please test source compatibility

@CodaFi
Copy link
Contributor

CodaFi commented May 7, 2017

Once more because I doubt this patch was the cause of the breakage.

@swift-ci please test source compatibility

@rintaro
Copy link
Member Author

rintaro commented May 10, 2017

Please anyone can review this?
I want to get this in Swift4 because this is source breaking change.

@rintaro
Copy link
Member Author

rintaro commented May 11, 2017

@DougGregor Can I ask you to approve this, as the code owner of Parse?

@jrose-apple
Copy link
Contributor

@bitjammer approved the early version, and @rjmccall said it's okay for Swift 4. @bitjammer, maybe you can look it over once more, and then @rintaro can land this?

@bitjammer
Copy link
Contributor

Sure thing.

@bitjammer
Copy link
Contributor

LGTM.

@bitjammer
Copy link
Contributor

Thank you for this patch, @rintaro, and thanks for your patience in landing it.

@rintaro
Copy link
Member Author

rintaro commented May 16, 2017

Thank you! test again
@swift-ci Please smoke test

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