Skip to content

Commit 3939194

Browse files
committed
Support parsing #![feature(default_field_values)]
- RFC: rust-lang/rfcs#3681 - Tracking issue: rust-lang/rust#132162 - Feature gate: `#![feature(default_field_values)]` ```rust struct Pet { name: Option<String>, age: i128 = 42, // ^^^^ } ``` Fix #1774.
1 parent aed58d1 commit 3939194

12 files changed

+167
-1
lines changed

src/data.rs

+12
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ ast_struct! {
196196
pub colon_token: Option<Token![:]>,
197197

198198
pub ty: Type,
199+
200+
/// Default value: `field_name: i32 = 1`
201+
///
202+
/// `#![feature(default_field_values)]`
203+
pub default: Option<(Token![=], Expr)>,
199204
}
200205
}
201206

@@ -345,6 +350,11 @@ pub(crate) mod parsing {
345350
} else {
346351
input.parse()?
347352
};
353+
let mut default: Option<(Token![=], Expr)> = None;
354+
if input.peek(Token![=]) {
355+
let eq_token: Token![=] = input.parse()?;
356+
default = Some((eq_token, input.parse()?));
357+
}
348358

349359
Ok(Field {
350360
attrs,
@@ -353,6 +363,7 @@ pub(crate) mod parsing {
353363
ident: Some(ident),
354364
colon_token: Some(colon_token),
355365
ty,
366+
default,
356367
})
357368
}
358369

@@ -366,6 +377,7 @@ pub(crate) mod parsing {
366377
ident: None,
367378
colon_token: None,
368379
ty: input.parse()?,
380+
default: None,
369381
})
370382
}
371383
}

src/gen/clone.rs

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/debug.rs

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/eq.rs

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/fold.rs

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/hash.rs

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/visit.rs

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gen/visit_mut.rs

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/parse_quote.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl<T: Parse> ParseQuote for T {
149149

150150
use crate::punctuated::Punctuated;
151151
#[cfg(any(feature = "full", feature = "derive"))]
152-
use crate::{attr, Attribute, Field, FieldMutability, Ident, Type, Visibility};
152+
use crate::{attr, Attribute, Expr, Field, FieldMutability, Ident, Type, Visibility};
153153
#[cfg(feature = "full")]
154154
use crate::{Arm, Block, Pat, Stmt};
155155

@@ -194,13 +194,20 @@ impl ParseQuote for Field {
194194

195195
let ty: Type = input.parse()?;
196196

197+
let mut default: Option<(Token![=], Expr)> = None;
198+
if is_named && input.peek(Token![=]) {
199+
let eq_token: Token![=] = input.parse()?;
200+
default = Some((eq_token, input.parse()?));
201+
}
202+
197203
Ok(Field {
198204
attrs,
199205
vis,
200206
mutability: FieldMutability::None,
201207
ident,
202208
colon_token,
203209
ty,
210+
default,
204211
})
205212
}
206213
}

syn.json

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/debug/gen.rs

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/test_item.rs

+108
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,114 @@ fn test_impl_visibility() {
274274
snapshot!(tokens as Item, @"Item::Verbatim(`pub default unsafe impl union { }`)");
275275
}
276276

277+
#[test]
278+
fn test_default_field_values() {
279+
let tokens = quote! {
280+
struct Foo {
281+
field_int: i32 = 42,
282+
field_const: i32 = const { 42 },
283+
}
284+
};
285+
snapshot!(tokens as Item, @r#"
286+
Item::Struct {
287+
vis: Visibility::Inherited,
288+
ident: "Foo",
289+
generics: Generics,
290+
fields: Fields::Named {
291+
named: [
292+
Field {
293+
vis: Visibility::Inherited,
294+
ident: Some("field_int"),
295+
colon_token: Some,
296+
ty: Type::Path {
297+
path: Path {
298+
segments: [
299+
PathSegment {
300+
ident: "i32",
301+
},
302+
],
303+
},
304+
},
305+
default: Expr::Lit {
306+
lit: 42,
307+
},
308+
},
309+
Token![,],
310+
Field {
311+
vis: Visibility::Inherited,
312+
ident: Some("field_const"),
313+
colon_token: Some,
314+
ty: Type::Path {
315+
path: Path {
316+
segments: [
317+
PathSegment {
318+
ident: "i32",
319+
},
320+
],
321+
},
322+
},
323+
default: Expr::Const {
324+
block: Block {
325+
stmts: [
326+
Stmt::Expr(
327+
Expr::Lit {
328+
lit: 42,
329+
},
330+
None,
331+
),
332+
],
333+
},
334+
},
335+
},
336+
Token![,],
337+
],
338+
},
339+
}
340+
"#);
341+
342+
let tokens = quote! {
343+
enum Foo {
344+
Bar {
345+
field: i32 = 42,
346+
}
347+
}
348+
};
349+
snapshot!(tokens as Item, @r#"
350+
Item::Enum {
351+
vis: Visibility::Inherited,
352+
ident: "Foo",
353+
generics: Generics,
354+
variants: [
355+
Variant {
356+
ident: "Bar",
357+
fields: Fields::Named {
358+
named: [
359+
Field {
360+
vis: Visibility::Inherited,
361+
ident: Some("field"),
362+
colon_token: Some,
363+
ty: Type::Path {
364+
path: Path {
365+
segments: [
366+
PathSegment {
367+
ident: "i32",
368+
},
369+
],
370+
},
371+
},
372+
default: Expr::Lit {
373+
lit: 42,
374+
},
375+
},
376+
Token![,],
377+
],
378+
},
379+
},
380+
],
381+
}
382+
"#);
383+
}
384+
277385
#[test]
278386
fn test_impl_type_parameter_defaults() {
279387
#[cfg(any())]

0 commit comments

Comments
 (0)