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

De-RFC: Remove type ascription #3307

Merged
merged 6 commits into from
Sep 12, 2022
Merged

Conversation

Manishearth
Copy link
Member

@Manishearth Manishearth commented Aug 28, 2022

From the community that brought you the Pre-RFC and the e-RFC, we now introduce: the de-RFC!

Type ascription (RFC #803, tracking issue) has been a merged RFC for seven years, with no clear path to stabilization. Since then, syntactic norms in Rust have shifted significantly and it's becoming increasingly unlikely that this RFC if posted would have landed today. During this time the nightly support for this feature has impacted the quality of parser diagnostics; creating a large black hole of potential mistakes that lead to a suggestion around ascription (a feature most cannot use) when there could have been a more targeted and accurate diagnostic.

This RFC intends to advocate for the feature being removed entirely (or at least moving the implementation to a less prime area of the syntactic space) with a fresh RFC being necessary to add it again (which this RFC encourages the community to do!)

(While I've taken some ... liberties with the RFC template here; it is not a joke; it's a serious attempt to give us a clean slate when it comes to this feature.)

💻 Rendered 💻

@Manishearth Manishearth added the T-lang Relevant to the language team, which will review and decide on the RFC. label Aug 28, 2022
@jhpratt
Copy link
Member

jhpratt commented Aug 28, 2022

ELI5 reference-level obfuscation?

Co-authored-by: Simonas Kazlauskas <[email protected]>
@joshtriplett joshtriplett added the I-lang-nominated Indicates that an issue has been nominated for prioritizing at the next lang team meeting. label Aug 28, 2022
@joshtriplett
Copy link
Member

LGTM; nominating for lang team consideration in our next meeting.

@steffahn
Copy link
Member

steffahn commented Aug 28, 2022

.<Type> feels particularly nice.

That feels like a fun parsing exercise in case we’d want to make this support things like 42.<u8>, too. Because…

1 as <A>::B::C > D
1 as <A>::B::C   > D
1 .< <A>::B::C > > D
1.<<A>::B::C>> D
1. << A > ::B::C >> D

(TBH, 42_u8 is the better alternative anyway, so maybe disallowing 42.<u8> or 42.<MY_CFGD_TYPE_SYNONYM> isn’t too bad; the latter might need to use 42 .<MY_CFGD_TYPE_SYNONYM> or 42 as MY_CFGD_TYPE_SYNONYM.)

Sorry, this comment is mostly off-topic presumably, but I didn’t know a good other place to post it.

@lambda
Copy link
Contributor

lambda commented Aug 28, 2022

ELI5 reference-level obfuscation?

Since this is a removal of a feature proposed by an existing RFC, as a joke all of the section names are reversed from what they are in the RFC Template. One of the template sections is "Reference level explanation", so this De-RFC has a "Reference level obfuscation".

The content of that section is a screenshot of a summary of the diff that would result from removing type ascription from the reference; 276,000 lines deleted from the reference. That feels high to me, so I believe the screenshot is a joke as well, simply indicating "this will allow us to delete a lot of things from the reference."

Copy link

@CAD97 CAD97 left a comment

Choose a reason for hiding this comment

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

I'm a +1 on eventually fully removing ascription syntax from the compiler.

As a member of wg-grammar, but speaking for myself, there's as I recall nothing formally blocking about : Type syntax, but it fails the "syntactic redundancy" and clarity rules that provide for strong parser recovery, because while type ascription is not in and of itself ambiguous, it is highly "typo-ambiguous".

HOWEVER, there is a wrinkle that will make removing ascription more difficult: the syntax is accidentally syntax-stable. rust-lang/rust#99935 just recently managed to enable warnings for the use of type ascription. Actual removal will need to go through a few cycles of upgrading the warning for type ascription to deny-by-default and future-compat-report.

Comment on lines 61 to 64
- `.is::<Type>`
- `.<Type>`
- `.::<Type>`
- `.become::<Type>` (already reserved! credit @mystor)

This comment was marked as resolved.

Copy link
Contributor

@estebank estebank Aug 29, 2022

Choose a reason for hiding this comment

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

Given that as is already a keyword, .as(Type) and .as<Type> are available syntactic space (arguments about operators looking like function calls notwithstanding).

@Manishearth
Copy link
Member Author

@lambda the screenshot was supposed to be for the compiler, as a joke about the number of diagnostics hacks we can remove

guide/reference level don't quite make sense for this RFC so I had fun with it

@jhpratt
Copy link
Member

jhpratt commented Aug 28, 2022

I figured it had something to do with the diff if this was removed, but it's also obviously not an actual diff count. No issue keeping a joke in, just wasn't certain if it was to be taken seriously for whatever reason.

@CAD97
Copy link

CAD97 commented Aug 29, 2022

Actual removal will need to go through a few cycles of upgrading the warning for type ascription to deny-by-default and future-compat-report.

I'm not super familiar with the future compat lint mechanism, but I did just recently implement syntax warnings for type ascription (among other unstable syntax). As such, I made a potential patch for pulling type ascription into its own warning: rust-lang/rust@master...CAD97:deny-type-ascription

This is made extra interesting by the fact this is being done in rustc_session::parse before we have access to the normal rustc_middle lint infrastructure. This should prove that the migration lint is feasible, though.

@joshtriplett
Copy link
Member

I would propose that this thread should avoid speculations on what the syntax should be if this is added back. @Manishearth, you might consider adding an explicit note in that section disclaiming the speculation as non-normative for the RFC; that's already normally the case but I think this de-RFC might be more than usually prone to such bikeshedding.

@Manishearth
Copy link
Member Author

@joshtriplett done.

@clarfonthey
Copy link
Contributor

clarfonthey commented Aug 29, 2022

Back when it was first proposed, I really loved type ascriptions and tried to use them despite the weird errors. Back then, type inference also wasn't nearly as good as it is now, and such a feature was more useful.

Nowadays I find very few uses that can't be done via turbofish and aren't unreasonable to do via separate bindings, since something that is sufficiently complex to need those ascriptions is probably sufficiently complex to factor into a separate binding anyway.

I think that we shouldn't really be looking for alternative syntax for generic type ascription and instead really take a hard look at what problems it's trying to solve, and what problems are left in a state where they're best solved by type ascription. This also means keeping in mind that f(g(x): T) can easily be written as let y: T = g(x); f(y).

@scooter-dangle
Copy link

Process question: for a De-RFC, would it make sense to also include a link at the top of the original RFC? Or would it just be discoverable from that RFC by visiting its tracking issue?

@Manishearth
Copy link
Member Author

Probably the latter: we typically do not edit RFCs after the fact. But I wouldn't be opposed.

@joshtriplett
Copy link
Member

@Manishearth We have edited some RFCs to indicate that they were withdrawn or similar. We should do the same here.

@joshtriplett
Copy link
Member

We discussed this in today's @rust-lang/lang meeting.

Several of us want type ascription in some form, but not in this form, and there seemed to be general consensus that we should remove this syntax and require a new RFC.

@rfcbot merge

@rfcbot
Copy link
Collaborator

rfcbot commented Aug 30, 2022

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added 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 Aug 30, 2022
@scottmcm
Copy link
Member

scottmcm commented Aug 30, 2022

Given that Rust sacrificed "colon introduces a type" to keep struct initializers and struct definitions the same, I think that : is really the obvious syntax here in expressions for the same symmetry reasons. (I really wish struct initializers had used = like let does, but churn means it's probably too late to ever do that.)

That said, I can't refute that this has been around for a long time and hasn't been making progress, so
@rfcbot reviewed


Probably the latter: we typically do not edit RFCs after the fact. But I wouldn't be opposed.

I think putting a note at the top of the other RFC makes sense. We did that in https://rust-lang.github.io/rfcs/2203-const-repeat-expr.html, as an example.

We generally don't edit the body, but adding a kind of "historical note" is reasonable.


for example, : syntax does make a lot of sense in patterns, and perhaps pattern ascription can use that whilst expression ascription ends up with something new

I'd love to see ascription on bindings in patterns. Here's an old Zulip thread about it, if anyone gets inspired: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/type.20ascription.20*in.20patterns*/near/213985025

Of course, that does hit the "colon used for a value" mistake again, since a Color { red: u8, .. } pattern already exists today and doesn't at all do what it looks like it should do or what the person who wrote that clearly wanted to happen.

@Manishearth
Copy link
Member Author

Given that Rust sacrificed "colon introduces a type" to keep struct initializers and struct definitions the same, I think that : is really the obvious syntax here in expressions for the same symmetry reasons. (I really wish struct initializers had used = like let does, but churn means it's probably too late to ever do that.)

Yeah, though "<> introduces a type" is also true, and is the way types get introduced in expressions (whereas : works in patterns and items)

@rfcbot rfcbot added final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. and removed proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. labels Aug 31, 2022
@rfcbot
Copy link
Collaborator

rfcbot commented Aug 31, 2022

🔔 This is now entering its final comment period, as per the review above. 🔔

@estebank
Copy link
Contributor

estebank commented Sep 1, 2022

Of course, that does hit the "colon used for a value" mistake again, since a Color { red: u8, .. } pattern already exists today and doesn't at all do what it looks like it should do or what the person who wrote that clearly wanted to happen.

(whereas : works in patterns and items)

Interestingly enough, : is not supported in top patterns, which means that we could have type ascription in patterns by only supporting them on the top level:

match foo {
    Foo { bar }: Foo<i32> => {}
}

@scottmcm
Copy link
Member

scottmcm commented Sep 1, 2022

Well, we can have it on bindings too, it's just stuck with being Foo { bar: bar: i32 } =>.

And that at least works nicely on tuple-structs, as Ok(v: i32) => or Color(r: u8, ..) => are perfectly reasonable.

@mark-i-m
Copy link
Member

mark-i-m commented Sep 2, 2022

To clarify, this does not remove type ascription in already-stable places, right? For example:

let foo: u64 = 42;

fn foo(arg: &str) -> Baz {...}

@jhpratt
Copy link
Member

jhpratt commented Sep 2, 2022

Yes, this only removes type ascription on expressions.

@slanterns
Copy link
Contributor

slanterns commented Sep 5, 2022

May also be worth noting that there was previously a postponed RFC talked about some related things (could be a future reference).

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this RFC. to-announce and removed final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. labels Sep 10, 2022
@rfcbot
Copy link
Collaborator

rfcbot commented Sep 10, 2022

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@Manishearth Manishearth merged commit d4439eb into rust-lang:master Sep 12, 2022
@Manishearth Manishearth deleted the de-rfc branch September 12, 2022 17:03
fpoli added a commit to viperproject/prusti-dev that referenced this pull request Jun 30, 2023
Type asccription has been removed by RFC 803: rust-lang/rfcs#3307
fpoli added a commit to viperproject/prusti-dev that referenced this pull request Jun 30, 2023
Type ascription has been removed by RFC 803: rust-lang/rfcs#3307
vakaras pushed a commit to viperproject/prusti-dev that referenced this pull request Jul 20, 2023
Type ascription has been removed by RFC 803: rust-lang/rfcs#3307
klinvill added a commit to klinvill/rust that referenced this pull request Nov 10, 2023
It's not clear to me (klinvill) that UserTypeProjections are produced
anymore with the removal of type ascriptions as per
rust-lang/rfcs#3307. Furthermore, it's not clear
to me which variants of ProjectionElem could appear in such projections.
For these reasons, I'm reverting projections in UserTypeProjections to
simple strings until I can get more clarity on UserTypeProjections.
klinvill added a commit to klinvill/rust that referenced this pull request Nov 10, 2023
It's not clear to me (klinvill) that UserTypeProjections are produced
anymore with the removal of type ascriptions as per
rust-lang/rfcs#3307. Furthermore, it's not clear
to me which variants of ProjectionElem could appear in such projections.
For these reasons, I'm reverting projections in UserTypeProjections to
simple strings until I can get more clarity on UserTypeProjections.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this RFC. I-lang-nominated Indicates that an issue has been nominated for prioritizing at the next lang team meeting. T-lang Relevant to the language team, which will review and decide on the RFC. to-announce
Projects
None yet
Development

Successfully merging this pull request may close these issues.