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

RFC: Generalized Type Ascription #2522

Closed

Conversation

Centril
Copy link
Contributor

@Centril Centril commented Aug 10, 2018

🖼️ Rendered

📝 Summary

This RFC supersedes and subsumes RFC 803. It generalizes existing type ascription in let bindings to everywhere a pattern can occur and makes some changes to ascription in expressions. You may now for example write:

let x = (0..10)
    .map(some_computation)
    .collect() : Result<Vec<_>, _>
    .unwrap()
    .map(other_computation) : Vec<usize>
    .into() : Rc<[_]>;

let alpha: u8 = expr;
    ^^^^^^^^^

let [x: u8, y, z] = stuff();
    ^^^^^^^^^^^^^

if let Some(beta: u8) = expr { .. }
            ^^^^^^^^

for x: i8 in 0..100 { .. }
    ^^^^^

fn foo(Wrapping(alpha: usize): Wrapping<usize>) {}
       ^^^^^^^^^^^^^^^^^^^^^^

Here, the underlined bits are patterns.

Finally, when a user writes Foo { $field: $pat : $type }, and when $pat and $type are syntactically α-equivalent, the compiler emits a warn-by-default lint suggesting: Foo { $field: ($pat : $type) }.

💖 Thanks

To @nrc, @kennytm, @varkor for reviewing the draft version.
To @scottmcm in particular for reviewing and being my rubber duck wrt. type inference.

Edit: Direct link to the pFCP checkboxes: #2522 (comment)

@alexreg
Copy link

alexreg commented Jan 21, 2019

There is no substantial improvement in writing x.collect(): Vec<T> instead of x.collect::<Vec<T>>() obviously. I agree however that foo(...) : Vec<T> could be far clearer than foo::<_,_,_,Vec<T>,_,_>(...), but actually foo(...).identity::<Vec<T>>() works find in such cases.

When partial turbofish finally arrives, this is a moot point though. I'm not sure of the status of this however. @Centril?

@comex
Copy link

comex commented Jan 22, 2019

We could easily add a trait

pub Identity { fn identity(self) -> Self { self } }
impl<T> Identity for T {}

That still would not allow .identity::<i32>() because turbofish on a method only allows specifying parameters on the method itself, not the trait the method came from. You'd have to do something hacky like

pub trait Is<T> {}
impl<T> Is<T> for T {}
pub trait HackyIdentity: Sized {
    fn identity<T>(self) -> Self where Self: Is<T> {
        self
    }
}
impl<T> HackyIdentity for T {}

@mark-i-m
Copy link
Member

I still prefer generalized ascription, but one alternative that solves part of the motivation of this issue might be to allow turbofish to be used for trait methods. For example something like this (syntax is bikeshedable):

trait Bar {
  fn bar<T, U, V>(args: (T, U, V));
}

foo.bar::<as Bar, T, U, V>(args);

@dralley
Copy link

dralley commented May 22, 2019

I'm interested in this RFC, what is the status? It's been 4 months since last comment.

@ExpHP
Copy link

ExpHP commented May 23, 2019

rfcbot's last comment is now hidden under the fold:

#2522 (comment)

There are five concerns currently marked as unresolved.

@joshtriplett
Copy link
Member

(Checking @aturon's box, as he's no longer on the lang team.)

@nikomatsakis
Copy link
Contributor

@rfcbot fcp cancel

I'm going to cancel the FCP on this issue because it's very old. In fact, I'm planning to close this RFC as "postponed". The feature described within still seems potentially desirable, but it's clear that there is plenty of follow-up work to do. I would like to encourage anyone who wants to pursue this design to try and do so through the new, experimental lang-team MCP process described in RFC #2936. One other thought is that it is likely possible to extract some subset of the functionality described in this RFC and move that forward rather than trying to do all the work at once.

@rfcbot
Copy link
Collaborator

rfcbot commented Jul 6, 2020

@nikomatsakis proposal cancelled.

@rfcbot rfcbot removed proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. labels Jul 6, 2020
@nikomatsakis
Copy link
Contributor

As stated above, I'm also going to close this RFC as "postponed" -- if you'd like to pick up activity here, please do reach out on Zulip or consider opening an MCP, and we can discuss whether there is a good candidate to serve as an active liaison. Thanks. ❤️

@nikomatsakis nikomatsakis added the postponed RFCs that have been postponed and may be revisited at a later time. label Jul 6, 2020
@jtmoon79
Copy link

I ran into this problem and posted a SO question about it regarding variable ascription in for loops.

FWIW, I wrote in the question:

Why explicitly annotate i?

Often the original type is declared or annotated in some far away source code, like maybe in a different crate.

  1. Sometimes, my IDE isn't able to deduce the type despite the code being compileable.
  2. Code reviewing humans are unable to deduce the expected type (they are not viewing the code with the help of Intellisense popups).

Being explicit about the type can be helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ascription Type ascription related proposals & ideas A-expressions Term language related proposals & ideas A-inference Type inference related proposals & ideas A-patterns Pattern matching related proposals & ideas A-syntax Syntax related proposals & ideas A-typesystem Type system related proposals & ideas postponed RFCs that have been postponed and may be revisited at a later time. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.