-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Implement field shorthands in struct literal expressions. #11994
Conversation
This is a (nice) syntax change, and so should get some discussion of some sort. |
I'm surprised how easy that was to add! I've added this to the meeting agenda (I'll put my vote in favor of it though). |
One possible ambiguity issue that we've come up with on IRC: for x in Foo { a } { b } |
Maybe we could just allow omitting the field name, but not the colon: let (some_field, other_field) = (1, 2);
for x in Foo { : some_field, : other_field } { ... } ... but that looks rather peculiar. |
@huonw the ambiguity only shows up with one-field structures. How often have you seen |
We'll need a few tests for the comma thing too. |
Even though it leaves a distasteful inconsistency in the language, |
We decided in today's meeting that due to ambiguities and some hygiene related concerns that we don't want this for now. Perhaps in rust 2.0! |
Sad panda. Why as late as 2.0, isn’t it backward-compatible? |
Ah I should clarify by 2.0 I mean "after 1.0" perhaps. We didn't concretely decide for a time for something like this to come in, we decided that now isn't the time for it though. |
(Sorry for the spam: phone touchscreen leads to "pocket commenting" :( ) |
Wouldn't be an ambiguity if we had |
Too bad. I find myself often writing code ending like this:
Where each field has be computed earlier. This sugar would make it much nicer. As to the ambiguities, they only occur in cases where (IMO) it’s rare to have a literal struct expression. (I wanted to write up some arguments that didn’t seem to appear in the meeting notes, but I’ll now stop beating this dead horse.) |
@SimonSapin This seems trivial to work around for now via #[feature(macro_rules)];
macro_rules! struct_fields {
($Struct:ident $($field:ident),+ )
=> { $Struct { $($field: $field),+ } } ;
}
struct SchemeRelativeUrl {
userinfo: ~str,
host: [u8, ..4],
port: u32,
path: ~str
}
fn main() {
let userinfo = ~"hi";
let host = [1,2,3,4];
let port = 56;
let path = ~"/root/";
let s = struct_fields!( SchemeRelativeUrl userinfo, host, port, path );
println!("s: {:?}", s);
} |
@pnkfelix This’ll help, thanks. I didn’t think of using a macro. However this doesn’t as easily cover cases where only some fields are based on a variable of the same name:
Still, sugar baked into the language is always nicer than a macro you have to define :) |
macro_rules! struct_field {
($Struct:ident $($short:ident),*; $($long:ident: $long_e: expr)*) => {
$Struct { $($short: $short, )* $($long: $long_e),* }
}
}
// ...
struct_fields!(
Url scheme, query, fragment; scheme_data: OtherSchemeData(scheme_data)
) |
Nice! Thanks @huonw. Is the |
It doesn't backtrack (I haven't compiled that so there may actually need to be more disambiguation necessary :( ). |
I'm genuinely curious to know how little needs to be updated here for it to work for #37340. |
a2fc2b0
to
4b26bde
Compare
@eddyb I see that in tests you follow the order of fields in a struct. Could you, please, some tests for case like: struct Foo {
x: i32,
y: i32,
}
let x = 5;
let y = 6;
let foo = Foo { y, x }; |
Ha, this seems to parse shortcuts for numeric fields:
Not sure if this is bad, but this is avoided in pattern parsing by calling |
A feature gate is also probably needed now, it's not 2014 anymore :( |
4b26bde
to
6e4ab6a
Compare
6e4ab6a
to
237bd2d
Compare
237bd2d
to
9908711
Compare
@bors: r+ |
📌 Commit 9908711 has been approved by |
Implement field shorthands in struct literal expressions. Implements #37340 in a straight-forward way: `Foo { x, y: f() }` parses as `Foo { x: x, y: f() }`. Because of the added `is_shorthand` to `ast::Field`, this is `[syntax-breaking]` (cc @Manishearth). * [x] Mark the fields as being a shorthand (the exact same way we do it in patterns), for pretty-printing. * [x] Gate the shorthand syntax with `#![feature(field_init_shorthand)]`. * [x] Don't parse numeric field as identifiers. * [x] Arbitrary field order tests.
[`question_mark`]: also trigger on `return` statements This fixes the false negative mentioned in rust-lang#11993: the lint only used to check for `return` expressions, and not a statement containing a `return` expression (doesn't close the issue tho since there's still a useful suggestion that we could make, which is to suggest `.ok_or()?`/`.ok_or_else()?` for `else { return Err(..) }`) changelog: [`question_mark`]: also trigger on `return` statements
Implements #37340 in a straight-forward way:
Foo { x, y: f() }
parses asFoo { x: x, y: f() }
.Because of the added
is_shorthand
toast::Field
, this is[syntax-breaking]
(cc @Manishearth).#![feature(field_init_shorthand)]
.