Skip to content
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

syntax: Parse field/method access after type ascription and cast expressions #33380

Closed
wants to merge 1 commit into from

Conversation

Projects
None yet
3 participants
@petrochenkov
Copy link
Contributor

petrochenkov commented May 3, 2016

Addresses #23416 (comment) / rust-lang/rfcs#1539 (comment)

This patch allows type ascription (and cast expressions) to be followed by field/method access syntax.
Therefore it allows type ascription to be used in method chains like

let sv = v.iter().
           collect(): Vec<_>.
           into_sorted();

and also makes unsuffixed integer literals with type ascription almost as convenient as literal suffixes

let s = 10u8.to_string();
let s = 10: u8.to_string();

r? @nikomatsakis

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented May 3, 2016

Hmm. This has implications for possible future extensions to the type grammar (. is largely out of bounds). I'd want @rust-lang/lang to weight in on this.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented May 3, 2016

But I agree 10:u8.foo() is pretty (though 10_u8.foo() seems ok too).

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented May 3, 2016

To give some practical example, here's a commit converting lrs library to use type ascription: lrs-lang/lib@5dc95b6.
That commit would look much nicer if type ascription supported chaining.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented May 6, 2016

We discussed this in the recent @rust-lang/lang meeting. We all agreed that the motivation here is pretty reasonable. In particular, this change enables the use of : in method chains:

vec.iter()
   .map()
   .collect(): Vec<_>
   .something()

which is a pretty clear improvement on the version with ():

(vec.iter()
    .map()
    .collect(): Vec<_>)
    .something()

@aturon has also harbored secret dreams of removing the need for "special purpose" converter methods. The commit you cited for example has a number of lines that convert calls to as_ref to use foo.as_ref(): &[u8]. We did some various comparisons of possibly syntaxes:

(self.as_ref():&[u8]).to_rmo_with(pool)
(self.as_ref(): &[u8]).to_rmo_with(pool) // current rustfmt output
self.as_ref():&[u8].to_rmo_with(pool)
self.as_ref::<[u8]>().to_rmo_with(pool)
self.as_ref<[u8]>().to_rmo_with(pool) // what we wanted, but can't get
self.as_bytes().to_rmo_with(pool)

Opinions were somewhat varied, but basically we didn't feel like any of the first three examples (using ascription) were really improvements over as_bytes. The existing self.as_ref::<[u8]>() is also generally considered unergonomic, of course, and sadly self.as_ref<[u8]>() introduces parsing ambiguities.

As another example, here are some calls with into:

(self.into():PathBuf).do_something()
self.into():PathBuf.do_something()
self.into::<PathBuf>().do_something()
self.into<PathBuf>().do_something() // what we wanted, but can't get yet
self.into_path_buf().do_something()
self.into(PathBuf).do_something() // magical

In general, we were very concerned that this syntax produces some things that are just plain conusing and hard to parse (for a human, that is). Example:

self.into():PathBuf.do_something()

On the other hand, not having this syntax really devalues type ascription, since it makes usage in method chains unergonomic.

In the end, we decided that we would rather not accept this PR. If you're really enthusiastically in favor of this syntax, we would of course consider an RFC, which would then get a broader set of feedback than this PR.

However, if we don't accept this PR, it does raise some questions as to whether type ascription carries its weight, given that using it with collect is kind of unergonomic in a method chain. There are still uses -- to be sure -- but they are fewer than before, and it introduces some confusion, since there is this overlap in purpose between : and as (also considered one of the features of type ascription, of course). However, @nrc felt strongly that we ought to wait until we have the full semantics of type ascription implemented before rendering a final judgement.

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented May 6, 2016

If you're really enthusiastically in favor of this syntax, we would of course consider an RFC

I do consider this a noticeable improvement, however this is a simple backward compatible change and it can be applied at any moment, so I'll just wait for the decision about type ascription in general.

@petrochenkov petrochenkov referenced this pull request May 6, 2016

Open

Type ascription (tracking issue for RFC 803) #23416

1 of 6 tasks complete
@kriomant

This comment has been minimized.

Copy link

kriomant commented May 10, 2016

10: u8.to_string() is interpreted by me (not compiler) as calling .to_string() on variable named u8, and some strange 10: syntax before. While space before type is a good thing, here it doesn't agree with operation order.

@petrochenkov petrochenkov deleted the petrochenkov:ascrdot branch Sep 21, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.