Skip to content

Conversation

nikomatsakis
Copy link
Contributor

Update type grammar to make + have lower precedence, consistent with the expression grammar, resolving a grammatical ambiguity.

Summary of impact (non-normative, from the RFC):

// Before                             After                         Note
// ~~~~~~                             ~~~~~                         ~~~~
   &Object+Send                       &(Object+Send)
   &'a Object+'a                      &'a (Object+'a)
   Box<Object+Send>                   Box<Object+Send>
   foo::<Object+Send,int>(...)        foo::<Object+Send,int>(...)
   Fn() -> Object+Send                Fn() -> (Object+Send)         // (*)
   Fn() -> &Object+Send               Fn() -> &(Object+Send)

// (*) Must yield a type error

Rendered view


```rust
fn foo<F>(f: F)
where F: FnOnce(&int) -> &Object + Send
Copy link
Contributor

Choose a reason for hiding this comment

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

So, under this scheme, a type written like this is (FnOnce(&int) -> &Object) + Send?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On Tue, Nov 04, 2014 at 03:16:07AM -0800, Huon Wilson wrote:

So, under this scheme, a type written like this is (FnOnce(&int) -> &Object) + Send?

Yes, right. That might occur in a context like Box<FnOnce(&int) -> &Object + Send>

@brendanzab
Copy link

Looks good to me.

@retep998
Copy link
Contributor

retep998 commented Nov 4, 2014

I didn't know how much I wanted this until I saw this RFC, and now I want it.
Making the order consistent with normal expressions just seems like the right thing to do.

| ...
| '(' SUM ')'
SUM = TYPE { '+' TYPE }
PATH = IDS '<' SUM { ',' SUM } '>' '->' TYPE
Copy link

Choose a reason for hiding this comment

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

the '->' TYPE is spurious here, isn't 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.

On Wed, Nov 05, 2014 at 08:26:51AM -0800, Benjamin Herr wrote:

the '->' TYPE is spurious here, isn't it?

Yes, thanks. I was thinking of the () form.

@comex
Copy link

comex commented Nov 6, 2014

FWIW, &'a Foo+'a is already pretty verbose, and adding parentheses makes it more so.

@nikomatsakis
Copy link
Contributor Author

On Wed, Nov 05, 2014 at 05:28:12PM -0800, comex wrote:

FWIW, &'a Foo+'a is already pretty verbose, and adding parentheses makes it more so.

Yes. I'd prefer to find a way to address this allows one to omit the
+'a altogether, just not sure what is the best way to do that in a
non-ad-hoc way yet.

@zwarich
Copy link

zwarich commented Nov 18, 2014

It was brought up in last week's Rust meeting that the precedence of + with respect to -> seems unintuitive.

@brson
Copy link
Contributor

brson commented Nov 18, 2014

Accepted. Discussion. More discussion. Tracking.

bors added a commit to rust-lang/rust that referenced this pull request Jan 29, 2018
syntax: Lower priority of `+` in `impl Trait`/`dyn Trait`

Now you have to write `Fn() -> (impl A + B)` instead of `Fn() -> impl A + B`, this is consistent with priority of `+` in trait objects (`Fn() -> A + B` means `(Fn() -> A) + B`).

To make this viable I changed the syntax to also permit `+` in return types in function declarations
```
fn f() -> dyn A + B { ... } // OK, don't have to write `-> (dyn A + B)`

// This is acceptable, because `dyn A + B` here is an isolated type and
// not part of a larger type with various operator priorities in play
// like `dyn A + B` in `Fn() -> dyn A + B` despite syntax similarities.
```
but you still have to use `-> (dyn A + B)` in function types and function-like trait object types (see this PR's tests for examples).

This can be a breaking change for code using `impl Trait` on nightly. The thing that is most likely to break is `&impl A + B`, it needs to be rewritten as `&(impl A + B)`.

cc #34511 #44662 rust-lang/rfcs#438
bors added a commit to rust-lang/rust that referenced this pull request Jan 30, 2018
syntax: Lower priority of `+` in `impl Trait`/`dyn Trait`

Now you have to write `Fn() -> (impl A + B)` instead of `Fn() -> impl A + B`, this is consistent with priority of `+` in trait objects (`Fn() -> A + B` means `(Fn() -> A) + B`).

To make this viable I changed the syntax to also permit `+` in return types in function declarations
```
fn f() -> dyn A + B { ... } // OK, don't have to write `-> (dyn A + B)`

// This is acceptable, because `dyn A + B` here is an isolated type and
// not part of a larger type with various operator priorities in play
// like `dyn A + B` in `Fn() -> dyn A + B` despite syntax similarities.
```
but you still have to use `-> (dyn A + B)` in function types and function-like trait object types (see this PR's tests for examples).

This can be a breaking change for code using `impl Trait` on nightly. The thing that is most likely to break is `&impl A + B`, it needs to be rewritten as `&(impl A + B)`.

cc #34511 #44662 rust-lang/rfcs#438
@Centril Centril added the A-syntax Syntax related proposals & ideas label Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-syntax Syntax related proposals & ideas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants