You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Disable parsing of type ascription in beta and stable #48016
Type ascription is a nightly only feature. Due to its syntax, this feature can cause some confusing error messages. Some of these have been handled by checking against typos (like when meaning ;), but given that the feature is only available in nightly, I think we should gate the feature at the parser level as well, so that error messages do not even mention type ascription. The big draw backs of doing this is that once the feature gets stabilized it won't have good diagnostics as it would otherwise have (because they'd only be shown in nightly, so we'd have fewer bug reports about it) and if somebody tries to use a nightly only crate that uses type ascriptions, the compiler would complain about syntax errors, instead of the feature being nightly only.
Having said that, there might be a middle point, where the feature is still being probed for diagnostic purposes, but never actually parsed on its entirety. At the same time, as pointed above, it probably would be worth to instead improve the diagnostics involving type ascription. If that is the decision, this issue can be closed.
cc @rust-lang/compiler
Reacted by Hanna Kruppe and Taylor Cramer
Reacted by kennytm, Eduard-Mihai Burtescu and Vadim Petrochenkov
First thought: this sounds like it might lead to odd behavior on nightly. Generally, nightly behaves the same as stable/beta unless you turn on a feature flag (and if you do something that is gated it tells you which feature flag to use). If nightly parses type ascription but gates it (current behavior), while stable/beta don't parse it at all, that's a behavior difference with no feature flag. But if nightly-without-feature-flag doesn't parse the syntax, there's no way to discover the flag. Maybe you'd have to run the parser in both modes, and say "warning: this parses differently with #![feature(type_ascription)]"?
Second thought: would this affect macros? When type ascription was implemented it changed the meaning of macros such as ($e:expr) => {}; ($n:ident : $t:ty) => {}. This sounds like it might end up changing that back, on stable/beta?
So this seems like maybe a good idea to improve error messages but would have to be done really carefully.
I mean it went through the RFC process, seems weird to simply drop it
without another one. But it was never fully implemented (i.e. to do
coercions) AFAIK.
It is not my intention to completely rip out the feature, but rather to acknowledge that the feature has introduced difficulty to learn the language an significantly bad in such a way that is not actionable for stable/beta users. If the syntax is ever to be stabilized, the learnability and diagnostic problems will need to be addressed, but as it stands now, I feel there are better places to focus on.
As for @durka's comments, they are very valid points.
I mean it went through the RFC process, seems weird to simply drop it without another one.
(I didn't mean we would drop it without some sort of FCP. In part, I am interested in culling "minor" features that have niggling issues that don't seem worth resolving at the moment.)
In general, I am still vaguely against the current type ascription syntax. I agree that : is used for types and that is nice, but I think it has a number of other strikes against it:
In general, have expressing forms (like <expr> as <Ty> and <exor>: <ty>) that end in types is annoying from a parsing perspective. It leads to conflicts around the <> operators (e.g., foo as vec < u32 .... -- quick, which way does it parse? I don't remember.)
Type ascription in general mixes poorly with explicit ref bindings, but the syntax of expr: Ty makes it look like an lvalue, so we can't just uniformly make it a coercion and make those problems go away.
Nonetheless I agree with @nrc's motivations, though I am less negative about turbofish than he is (and I sort of would prefr that if we hate it so much that we solve it more directly, though maybe there's no hope).
I wonder about repurposing as as a prefix operator:
as<T>(expr)
with the semantics of it being always an rvalue, thus side-stepping the coercion soundness problems.
So let x = as<u32>(22)?
Maybe it's confusing that as wouldn't have to use turbofish when other things must. And of course as::<u32>(22) wouldn't solve nrc's "no turbofish" constraint.
I do like that a name related to type ascription gives it more of an obvious purpose, since my first reaction to seeing identity is "why did you need to specify that?". For example drop, coerce, and moving could all be implemented fine as an identity function, but different names help the intent. (And could even have lints like always turbofish cast, but never turbofish moving.)
@durka I'm hoping we get to the world where anything that's not a coercion is accessible through a method or function with clearer semantics. For example, from, try_from, and new wrapping_from (bikeshedded, of course) for going between all the integer types.
Reacted by Alex Burka, Esteban Kuber and Daniel P. Clark
I believe that #59150 covers a lot of ground of what disabling was meant to accomplish, although there are still cases where errors are not great, namely the following three:
error: expected type, found keyword `box`
--> file5.rs:2:25
|
2 | let _ = Option:Some(vec![0, 1]);
| ^^^^^^^^^^ in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0425]: cannot find value `foo` in this scope
--> file4.rs:5:9
|
5 | foo: Vec::new()
| ^^^
| |
| `self` value is a keyword only available in methods with `self` parameter
| help: try: `self.foo`
error: parenthesized type parameters may only be used with a `Fn` trait
--> file4.rs:5:22
|
5 | foo: Vec::new()
| ^^
|
= note: #[deny(parenthesized_params_in_types_and_modules)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
error[E0107]: wrong number of type arguments: expected 1, found 0
--> file4.rs:5:14
|
5 | foo: Vec::new()
| ^^^^^^^^^^ expected 1 type argument
Now with #62791 the only two cases left are the last two in the previous comment. Those are tracked in #47666 and #34255 respectively. For the macro one a fix will require carrying state around from the Parser to the MacroExpander, while for the latter I believe that code is so close to real code that the parser should attempt to parse it outright (for diagnostic purposes). Given this, the raison d'être for this issue is no longer pressing. The rest of the discussion can continue in the tracking issue #23416. Closing.
Activity
durka commentedon Feb 5, 2018
First thought: this sounds like it might lead to odd behavior on nightly. Generally, nightly behaves the same as stable/beta unless you turn on a feature flag (and if you do something that is gated it tells you which feature flag to use). If nightly parses type ascription but gates it (current behavior), while stable/beta don't parse it at all, that's a behavior difference with no feature flag. But if nightly-without-feature-flag doesn't parse the syntax, there's no way to discover the flag. Maybe you'd have to run the parser in both modes, and say "warning: this parses differently with
#![feature(type_ascription)]"?Second thought: would this affect macros? When type ascription was implemented it changed the meaning of macros such as
($e:expr) => {}; ($n:ident : $t:ty) => {}. This sounds like it might end up changing that back, on stable/beta?So this seems like maybe a good idea to improve error messages but would have to be done really carefully.
nikomatsakis commentedon Feb 5, 2018
I'm kind of tempted to just rip out type ascription, maybe try again some other time.
eddyb commentedon Feb 5, 2018
GitHub needs 😞/😭 reactions.
nikomatsakis commentedon Feb 5, 2018
I confess I've never really wanted it though =) I'm happy to be persuaded to keep it...
durka commentedon Feb 5, 2018
estebank commentedon Feb 5, 2018
It is not my intention to completely rip out the feature, but rather to acknowledge that the feature has introduced difficulty to learn the language an significantly bad in such a way that is not actionable for stable/beta users. If the syntax is ever to be stabilized, the learnability and diagnostic problems will need to be addressed, but as it stands now, I feel there are better places to focus on.
As for @durka's comments, they are very valid points.
nikomatsakis commentedon Feb 5, 2018
(I didn't mean we would drop it without some sort of FCP. In part, I am interested in culling "minor" features that have niggling issues that don't seem worth resolving at the moment.)
nikomatsakis commentedon Feb 5, 2018
@estebank
Can you elaborate on these? I think that'd be useful information for the feature stabilization process in general.
cramertj commentedon Feb 5, 2018
@nikomatsakis This is the one I see all the time:
estebank commentedon Feb 5, 2018
@nikomatsakis a few other that I've seen recently:
#39126
#37509
#34255
#47360
nikomatsakis commentedon Feb 6, 2018
Thanks!
A middle ground, I suppose, would be to generate a better error, right? That might be a pain to do in this case though.
6 remaining items
nikomatsakis commentedon Mar 9, 2018
Heh, I just hit this error and it confused me for a good 5 minutes (I had
ty::ParamEnv:reveal_all()).nikomatsakis commentedon Mar 9, 2018
In general, I am still vaguely against the current type ascription syntax. I agree that
:is used for types and that is nice, but I think it has a number of other strikes against it:<expr> as <Ty>and<exor>: <ty>) that end in types is annoying from a parsing perspective. It leads to conflicts around the<>operators (e.g.,foo as vec < u32 ....-- quick, which way does it parse? I don't remember.)refbindings, but the syntax ofexpr: Tymakes it look like an lvalue, so we can't just uniformly make it a coercion and make those problems go away.Nonetheless I agree with @nrc's motivations, though I am less negative about turbofish than he is (and I sort of would prefr that if we hate it so much that we solve it more directly, though maybe there's no hope).
I wonder about repurposing
asas a prefix operator:with the semantics of it being always an rvalue, thus side-stepping the coercion soundness problems.
So
let x = as<u32>(22)?Maybe it's confusing that
aswouldn't have to useturbofishwhen other things must. And of courseas::<u32>(22)wouldn't solve nrc's "no turbofish" constraint.nikomatsakis commentedon Mar 9, 2018
(also, given that
asas I wrote is basically equivalent to:it seems sort of silly to bake it in the language. Though I do wonder if we could replace type ascripton with putting that function into the prelude.)
durka commentedon Mar 9, 2018
That function has other uses as well.
scottmcm commentedon Mar 9, 2018
And there's rust-lang/rfcs#2306 to add it as
convert::identity.I do like that a name related to type ascription gives it more of an obvious purpose, since my first reaction to seeing
identityis "why did you need to specify that?". For exampledrop,coerce, andmovingcould all be implemented fine as an identity function, but different names help the intent. (And could even have lints like always turbofishcast, but never turbofishmoving.)durka commentedon Mar 9, 2018
scottmcm commentedon Mar 9, 2018
@durka I'm hoping we get to the world where anything that's not a coercion is accessible through a method or function with clearer semantics. For example,
from,try_from, and newwrapping_from(bikeshedded, of course) for going between all the integer types.estebank commentedon Mar 14, 2019
I believe that #59150 covers a lot of ground of what disabling was meant to accomplish, although there are still cases where errors are not great, namely the following three:
Rollup merge of rust-lang#59150 - estebank:type-ascription, r=varkor
Rollup merge of rust-lang#59150 - estebank:type-ascription, r=varkor
Rollup merge of rust-lang#59150 - estebank:type-ascription, r=varkor
estebank commentedon Jul 19, 2019
Now with #62791 the only two cases left are the last two in the previous comment. Those are tracked in #47666 and #34255 respectively. For the macro one a fix will require carrying state around from the
Parserto theMacroExpander, while for the latter I believe that code is so close to real code that the parser should attempt to parse it outright (for diagnostic purposes). Given this, the raison d'être for this issue is no longer pressing. The rest of the discussion can continue in the tracking issue #23416. Closing.Rollup merge of rust-lang#62791 - estebank:type-ascription, r=petroch…
Rollup merge of rust-lang#62791 - estebank:type-ascription, r=petroch…