From 0276e41e94a4b83a23bda5ab05d18cda7a588d53 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 7 Jan 2026 13:15:00 +0000 Subject: [PATCH 1/5] Don't attempt to compile big default value showcases as ignored rust doctest --- .../src/builder/builder_gen/setters/mod.rs | 67 ++++++++++--------- bon-sandbox/src/attr_default.rs | 6 ++ 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/bon-macros/src/builder/builder_gen/setters/mod.rs b/bon-macros/src/builder/builder_gen/setters/mod.rs index 9ecc7e72..46a76789 100644 --- a/bon-macros/src/builder/builder_gen/setters/mod.rs +++ b/bon-macros/src/builder/builder_gen/setters/mod.rs @@ -600,24 +600,16 @@ impl SettersItems { .or(common_docs) .unwrap_or(&member.docs); - let setter_names = (&some_fn_name, &option_fn_name); - - let some_fn_docs = { - let header = optional_setter_docs(default, setter_names); - - doc(&header).chain(some_fn_docs.iter().cloned()).collect() - }; + let some_fn_docs = + optional_setter_docs(default, &some_fn_name, &option_fn_name, some_fn_docs); let option_fn_docs = option_fn .and_then(ItemSigConfig::docs) .or(common_docs) .unwrap_or(&member.docs); - let option_fn_docs = { - let header = optional_setter_docs(default, setter_names); - - doc(&header).chain(option_fn_docs.iter().cloned()).collect() - }; + let option_fn_docs = + optional_setter_docs(default, &some_fn_name, &option_fn_name, option_fn_docs); let some_fn = SetterItem { name: some_fn_name, @@ -649,24 +641,39 @@ impl SettersItems { fn optional_setter_docs( default: Option<&str>, - (some_fn, option_fn): (&syn::Ident, &syn::Ident), -) -> String { - let default = default - .map(|default| { - if default.contains('\n') || default.len() > 80 { - format!(" _**Default:**_\n````rust,ignore\n{default}\n````\n\n") - } else { - format!(" _**Default:**_ ```{default}```.\n\n") - } - }) - .unwrap_or_default(); - - format!( - "_**Optional** \ - ([Some](Self::{some_fn}()) / [Option](Self::{option_fn}()) setters).\ - _{default}\ - \n\n" - ) + some_fn: &syn::Ident, + option_fn: &syn::Ident, + doc_comments: &[syn::Attribute], +) -> Vec { + let header = format!( + "_**Optional** ([Some](Self::{some_fn}()) / [Option](Self::{option_fn}()) setters)._" + ); + + let mut attrs = vec![syn::parse_quote!(#[doc = #header])]; + + if let Some(default) = default { + let sep = if doc_comments.is_empty() { "" } else { "\n\n" }; + + if default.contains('\n') || default.len() > 80 { + // `no_doctest` helps to avoid interpreting the code block as + // an "ignored but still runnable" doc test. See details: + // - bon issue: https://github.com/elastio/bon/issues/359 + // - rust issue: https://github.com/rust-lang/rust/issues/63193 + let tail = format!("\n{default}\n````{sep}"); + attrs.extend([ + syn::parse_quote!(#[doc = " _**Default:**_\n"]), + syn::parse_quote!(#[cfg_attr(doctest, doc = "````no_doctest")]), + syn::parse_quote!(#[cfg_attr(not(doctest), doc = "````")]), + syn::parse_quote!(#[doc = #tail]), + ]); + } else { + let doc = format!(" _**Default:**_ ```{default}```.{sep}"); + attrs.push(syn::parse_quote!(#[doc = #doc])); + } + } + + attrs.extend(doc_comments.iter().cloned()); + attrs } fn well_known_default(ty: &syn::Type) -> Option { diff --git a/bon-sandbox/src/attr_default.rs b/bon-sandbox/src/attr_default.rs index 9b0bf078..2718f048 100644 --- a/bon-sandbox/src/attr_default.rs +++ b/bon-sandbox/src/attr_default.rs @@ -10,9 +10,15 @@ reason = "Common `_default` suffix is for better readability" )] pub struct Example { + /// More docs + /// + /// even more! #[builder(default = (2 + 2) * 10)] small_custom_default: u32, + /// More docs + /// + /// even more! #[builder(default = Vec::from([ Point { x: 1, y: 2 }, Point { x: 3, y: 4 }, From dc9e1eecccbe93c0b60f7e8509e1a6236620526d Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 7 Jan 2026 13:16:43 +0000 Subject: [PATCH 2/5] Prettier --- bon-sandbox/src/attr_default.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bon-sandbox/src/attr_default.rs b/bon-sandbox/src/attr_default.rs index 2718f048..8f6e20a5 100644 --- a/bon-sandbox/src/attr_default.rs +++ b/bon-sandbox/src/attr_default.rs @@ -10,15 +10,13 @@ reason = "Common `_default` suffix is for better readability" )] pub struct Example { - /// More docs - /// - /// even more! + /// Custom doc comment. + /// Multiline. #[builder(default = (2 + 2) * 10)] small_custom_default: u32, - /// More docs - /// - /// even more! + /// Custom doc comment. + /// Multiline. #[builder(default = Vec::from([ Point { x: 1, y: 2 }, Point { x: 3, y: 4 }, From e09de42c3ed2a8a806899ac96a790add90704abf Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 7 Jan 2026 13:18:55 +0000 Subject: [PATCH 3/5] Update test snapshots --- .../tests/snapshots/setters_docs_and_vis.rs | 78 ++++++------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/bon-macros/tests/snapshots/setters_docs_and_vis.rs b/bon-macros/tests/snapshots/setters_docs_and_vis.rs index 465820de..b55bd9e9 100644 --- a/bon-macros/tests/snapshots/setters_docs_and_vis.rs +++ b/bon-macros/tests/snapshots/setters_docs_and_vis.rs @@ -15,9 +15,7 @@ impl SutBuilder { where S::RequiredField: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field()) / [Option](Self::maybe_optional_field()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field()) / [Option](Self::maybe_optional_field()) setters)._ /// Docs on the optional field setters. /// Multiline. pub(in overridden) fn optional_field( @@ -27,9 +25,7 @@ impl SutBuilder { where S::OptionalField: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field()) / [Option](Self::maybe_optional_field()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field()) / [Option](Self::maybe_optional_field()) setters)._ /// Docs on the optional field setters. /// Multiline. pub(in overridden) fn maybe_optional_field( @@ -39,9 +35,8 @@ impl SutBuilder { where S::OptionalField: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field()) / [Option](Self::maybe_default_field()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field()) / [Option](Self::maybe_default_field()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Docs on the default field setters. @@ -53,9 +48,8 @@ impl SutBuilder { where S::DefaultField: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field()) / [Option](Self::maybe_default_field()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field()) / [Option](Self::maybe_default_field()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Docs on the default field setters. @@ -67,9 +61,7 @@ impl SutBuilder { where S::DefaultField: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field_with_specific_overrides()) / [Option](Self::maybe_optional_field_with_specific_overrides()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field_with_specific_overrides()) / [Option](Self::maybe_optional_field_with_specific_overrides()) setters)._ /// Docs on some_fn /// Multiline. pub(in some_fn_overridden) fn optional_field_with_specific_overrides( @@ -79,9 +71,7 @@ impl SutBuilder { where S::OptionalFieldWithSpecificOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field_with_specific_overrides()) / [Option](Self::maybe_optional_field_with_specific_overrides()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field_with_specific_overrides()) / [Option](Self::maybe_optional_field_with_specific_overrides()) setters)._ /// Docs on option_fn /// Multiline. pub(in option_fn_overridden) fn maybe_optional_field_with_specific_overrides( @@ -91,9 +81,8 @@ impl SutBuilder { where S::OptionalFieldWithSpecificOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field_with_specific_overrides()) / [Option](Self::maybe_default_field_with_specific_overrides()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field_with_specific_overrides()) / [Option](Self::maybe_default_field_with_specific_overrides()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Docs on some_fn @@ -105,9 +94,8 @@ impl SutBuilder { where S::DefaultFieldWithSpecificOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field_with_specific_overrides()) / [Option](Self::maybe_default_field_with_specific_overrides()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field_with_specific_overrides()) / [Option](Self::maybe_default_field_with_specific_overrides()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Docs on option_fn @@ -119,9 +107,7 @@ impl SutBuilder { where S::DefaultFieldWithSpecificOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field_with_inherited_overrides()) / [Option](Self::maybe_optional_field_with_inherited_overrides()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field_with_inherited_overrides()) / [Option](Self::maybe_optional_field_with_inherited_overrides()) setters)._ /// Common docs /// Multiline. pub(in overridden) fn optional_field_with_inherited_overrides( @@ -131,9 +117,7 @@ impl SutBuilder { where S::OptionalFieldWithInheritedOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::optional_field_with_inherited_overrides()) / [Option](Self::maybe_optional_field_with_inherited_overrides()) setters)._ - -*/ + ///_**Optional** ([Some](Self::optional_field_with_inherited_overrides()) / [Option](Self::maybe_optional_field_with_inherited_overrides()) setters)._ /// Docs on option_fn /// Multiline. pub(in option_fn_overridden) fn maybe_optional_field_with_inherited_overrides( @@ -143,9 +127,8 @@ impl SutBuilder { where S::OptionalFieldWithInheritedOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field_with_inherited_overrides()) / [Option](Self::maybe_default_field_with_inherited_overrides()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field_with_inherited_overrides()) / [Option](Self::maybe_default_field_with_inherited_overrides()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Common docs @@ -157,9 +140,8 @@ impl SutBuilder { where S::DefaultFieldWithInheritedOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::default_field_with_inherited_overrides()) / [Option](Self::maybe_default_field_with_inherited_overrides()) setters)._ _**Default:**_ ```2 + 2 * 3```. - - + ///_**Optional** ([Some](Self::default_field_with_inherited_overrides()) / [Option](Self::maybe_default_field_with_inherited_overrides()) setters)._ + /** _**Default:**_ ```2 + 2 * 3```. */ /// Docs on option_fn @@ -171,9 +153,7 @@ impl SutBuilder { where S::DefaultFieldWithInheritedOverrides: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip()) / [Option](Self::maybe_setters_doc_default_skip()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip()) / [Option](Self::maybe_setters_doc_default_skip()) setters)._ fn setters_doc_default_skip( self, value: u32, @@ -181,9 +161,7 @@ impl SutBuilder { where S::SettersDocDefaultSkip: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip()) / [Option](Self::maybe_setters_doc_default_skip()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip()) / [Option](Self::maybe_setters_doc_default_skip()) setters)._ fn maybe_setters_doc_default_skip( mut self, value: Option, @@ -191,9 +169,7 @@ impl SutBuilder { where S::SettersDocDefaultSkip: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip_and_custom_docs_block()) / [Option](Self::maybe_setters_doc_default_skip_and_custom_docs_block()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip_and_custom_docs_block()) / [Option](Self::maybe_setters_doc_default_skip_and_custom_docs_block()) setters)._ /// Custom docs /// Multiline. fn setters_doc_default_skip_and_custom_docs_block( @@ -203,9 +179,7 @@ impl SutBuilder { where S::SettersDocDefaultSkipAndCustomDocsBlock: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip_and_custom_docs_block()) / [Option](Self::maybe_setters_doc_default_skip_and_custom_docs_block()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip_and_custom_docs_block()) / [Option](Self::maybe_setters_doc_default_skip_and_custom_docs_block()) setters)._ /// Custom docs /// Multiline. fn maybe_setters_doc_default_skip_and_custom_docs_block( @@ -215,9 +189,7 @@ impl SutBuilder { where S::SettersDocDefaultSkipAndCustomDocsBlock: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip_from_top_level_on()) / [Option](Self::maybe_setters_doc_default_skip_from_top_level_on()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip_from_top_level_on()) / [Option](Self::maybe_setters_doc_default_skip_from_top_level_on()) setters)._ fn setters_doc_default_skip_from_top_level_on( self, value: u8, @@ -225,9 +197,7 @@ impl SutBuilder { where S::SettersDocDefaultSkipFromTopLevelOn: sut_builder::IsUnset, {} - /**_**Optional** ([Some](Self::setters_doc_default_skip_from_top_level_on()) / [Option](Self::maybe_setters_doc_default_skip_from_top_level_on()) setters)._ - -*/ + ///_**Optional** ([Some](Self::setters_doc_default_skip_from_top_level_on()) / [Option](Self::maybe_setters_doc_default_skip_from_top_level_on()) setters)._ fn maybe_setters_doc_default_skip_from_top_level_on( mut self, value: Option, From 02a9b8694722c09b6c0c7bebd3656e9ff7b1fe69 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 7 Jan 2026 14:02:53 +0000 Subject: [PATCH 4/5] Fix MSRV tests --- scripts/test-msrv.sh | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/scripts/test-msrv.sh b/scripts/test-msrv.sh index a82b8ca4..6f7c1188 100755 --- a/scripts/test-msrv.sh +++ b/scripts/test-msrv.sh @@ -34,19 +34,21 @@ with_log cd bon step echo '[workspace]' >> Cargo.toml -step cargo update -p proc-macro2 --precise 1.0.101 -step cargo update -p quote --precise 1.0.40 -step cargo update -p once_cell --precise 1.17.2 -step cargo update -p trybuild --precise 1.0.89 -step cargo update -p serde_json --precise 1.0.143 -step cargo update -p serde --precise 1.0.194 -step cargo update -p prettyplease --precise 0.2.17 -step cargo update -p syn --precise 2.0.56 -step cargo update -p tokio --precise 1.29.1 -step cargo update -p expect-test --precise 1.4.1 -step cargo update -p windows-sys --precise 0.52.0 -step cargo update -p libc --precise 0.2.163 -step cargo update -p glob --precise 0.3.2 +step cargo update --precise 1.0.15 -p itoa +step cargo update --precise 1.0.20 -p ryu +step cargo update --precise 1.0.101 -p proc-macro2 +step cargo update --precise 1.0.40 -p quote +step cargo update --precise 1.17.2 -p once_cell +step cargo update --precise 1.0.89 -p trybuild +step cargo update --precise 1.0.143 -p serde_json +step cargo update --precise 1.0.194 -p serde +step cargo update --precise 0.2.17 -p prettyplease +step cargo update --precise 2.0.56 -p syn +step cargo update --precise 1.29.1 -p tokio +step cargo update --precise 1.4.1 -p expect-test +step cargo update --precise 0.52.0 -p windows-sys +step cargo update --precise 0.2.163 -p libc +step cargo update --precise 0.3.2 -p glob export RUSTFLAGS="${RUSTFLAGS:-} --allow unknown-lints" From 4ead943dc0ddfb6bfedfc3ffb2295926f4802bfb Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 7 Jan 2026 14:16:17 +0000 Subject: [PATCH 5/5] Fix msrv tests --- scripts/test-msrv.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test-msrv.sh b/scripts/test-msrv.sh index 6f7c1188..05a42e0c 100755 --- a/scripts/test-msrv.sh +++ b/scripts/test-msrv.sh @@ -35,12 +35,12 @@ with_log cd bon step echo '[workspace]' >> Cargo.toml step cargo update --precise 1.0.15 -p itoa -step cargo update --precise 1.0.20 -p ryu step cargo update --precise 1.0.101 -p proc-macro2 step cargo update --precise 1.0.40 -p quote step cargo update --precise 1.17.2 -p once_cell step cargo update --precise 1.0.89 -p trybuild step cargo update --precise 1.0.143 -p serde_json +step cargo update --precise 1.0.20 -p ryu step cargo update --precise 1.0.194 -p serde step cargo update --precise 0.2.17 -p prettyplease step cargo update --precise 2.0.56 -p syn