Skip to content

Commit 8303beb

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 dtolnay#1774.
1 parent aed58d1 commit 8303beb

12 files changed

+151
-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

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

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

0 commit comments

Comments
 (0)