Skip to content

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

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

Closed
wants to merge 1 commit into from

Conversation

petrochenkov
Copy link
Contributor

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
Copy link
Contributor

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 nikomatsakis added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels May 3, 2016
@nikomatsakis
Copy link
Contributor

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

@petrochenkov
Copy link
Contributor Author

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
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
Copy link
Contributor Author

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.

@kriomant
Copy link

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 ascrdot branch September 21, 2016 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants