Skip to main content

const_builder/
lib.rs

1//! Provides a [`ConstBuilder`] derive macro that generates a `*Builder` type
2//! that can be used to create a value with the builder pattern, even in a const
3//! context.
4//!
5//! The attributed type will gain an associated `builder` method, which can then
6//! be chained with function calls until all required fields are set, at which
7//! point you can call `build` to get the final value.
8//!
9//! Compile-time checks prevent setting the same field twice or calling `build`
10//! before all required fields are set.
11//!
12//! By default, the `*Builder` type and `*::builder` method have the same
13//! visibility as the type, and every field setter is `pub`, regardless of field
14//! visibility.
15//!
16//! The builder isn't clonable and its methods are called by-value, returning
17//! the updated builder value.
18//!
19//! The generated code is supported in `#![no_std]` crates.
20//!
21//! # Unsafety
22//!
23//! This derive macro generates `unsafe` code using
24//! [`MaybeUninit`](std::mem::MaybeUninit) to facilitate field-wise
25//! initialization of a struct, tracking initialized fields via const-generics.
26//! This broadly follows the guidance in the [nomicon section on unchecked
27//! uninitialized memory], and is, for now, required to get const-compatible
28//! builders for arbitrary types.
29//!
30//! # Struct Requirements
31//!
32//! All struct fields must be [`Sized`]. Fields using generic parameters may be
33//! [`?Sized`](Sized) for some parameters, as long as the actual instantiation
34//! of the builder only has [`Sized`] fields.
35//!
36//! When the struct is `#[repr(packed)]` and the last field may be
37//! [`?Sized`](Sized), the field must be attributed with
38//! `#[builder(unsized_tail)]` to replace the field drop code with an assert
39//! that the field cannot be dropped. Functionally, this combination of packed,
40//! unsized tails, and with the builder requirements means that this field has
41//! to be [`ManuallyDrop<T: ?Sized>`](std::mem::ManuallyDrop) or a wrapper
42//! around it.
43//!
44//! `enum` and `union` types are unsupported.
45//!
46//! # Default Values
47//!
48//! Fields can be attributed with `#[builder(default = None)]` or similar to
49//! be made optional by providing a default value.
50//!
51//! This default value will _not_ be dropped if it is overridden or the builder
52//! is dropped. Consequently, the value should be something that does not need
53//! to be dropped, such as a primitive, [`None`], [`String::new()`],
54//! [`Vec::new()`], [`Cow::Borrowed`](std::borrow::Cow), or similar.
55//!
56//! While this accepts any Rust expression, when a string literal is provided,
57//! it is parsed again. To specify defaults for `&str` fields, wrap them in
58//! parenthesis, f.e. `#[builder(default = ("default value"))]`. The re-parsing
59//! behavior may be removed in a future version.
60//!
61//! # API Stability
62//!
63//! The API of the emitted builder is considered forward-compatible as long as
64//! care is taken to ensure the surface area to consumers stays the same and the
65//! changes don't already constitute as breaking to consumers of the original
66//! struct.
67//!
68//! Because each field gets an associated const-generic parameter on the builder
69//! struct, even private fields with private setters will show up in the public
70//! API of the builder. To avoid exposing a field in the public API, use the
71//! `skip` attribute.
72//!
73//! Adding the `default` attribute to the struct or a field is
74//! forward-compatible. Removing the attribute is a breaking change.
75//!
76//! Additionally, changes to builder attributes that lead to reduction in
77//! visibility, renames, removal, or changes in signature of functions in the
78//! emitted code are also breaking changes. This includes attributes such `vis`,
79//! `rename`, `rename_fn`, `setter`, and `skip`.
80//!
81//! Major versions of this crate may also introduce breaking changes to the
82//! emitted structs. Minor versions will ensure to emit forward-compatible code.
83//!
84//! # Unchecked Builder
85//!
86//! There is also an `*UncheckedBuilder` without safety checks, which is private
87//! by default. While similar to the checked builder at a glance, not every
88//! attribute applies to it in the same way (f.e. the `setter` attribute has no
89//! effect), and its API isn't considered stable across source struct
90//! modifications, so it should not be exposed in stable public interfaces.
91//!
92//! This struct is used to simplify the implementation of the checked builder
93//! and it is exposed for users that want additional control.
94//!
95//! This builder works broadly in the same way as the checked builder, however:
96//!
97//! - initialized fields aren't tracked,
98//! - setting fields that were already set will forget the old value,
99//! - calling `build` is unsafe due to the lack of tracking, and
100//! - dropping it will forget all field values that were already set.
101//!
102//! You can convert between the checked and unchecked builder with
103//! `*Builder::into_unchecked` and `*UncheckedBuilder::assert_init`.
104//!
105//! # Example
106//!
107//! ```
108//! use const_builder::ConstBuilder;
109//!
110//! #[derive(ConstBuilder)]
111//! # #[derive(Debug, PartialEq)]
112//! pub struct Person<'a> {
113//!     // fields are required by default
114//!     pub name: &'a str,
115//!     // optional fields have a default specified
116//!     // the value is required even when the type implements `Default`!
117//!     #[builder(default = 0)]
118//!     pub age: u32,
119//! }
120//!
121//! let steve = const {
122//!     Person::builder()
123//!         .name("steve smith")
124//!         .build()
125//! };
126//! # assert_eq!(
127//! #     steve,
128//! #     Person {
129//! #         name: "steve smith",
130//! #         age: 0,
131//! #     }
132//! # );
133//! ```
134//!
135//! # Generated Interface
136//!
137//! The example above would generate an interface similar to the following. The
138//! actual generated code is more complex because it includes bounds to ensure
139//! fields are only written once and that the struct is fully initialized when
140//! calling `build`.
141//!
142//! ```
143//! # // This isn't an example to run, just an example "shape".
144//! # _ = stringify!(
145//! /// A builder type for [`Person`].
146//! pub struct PersonBuilder<'a, const _NAME: bool = false, const _AGE: bool = false> { ... }
147//!
148//! impl<'a, ...> PersonBuilder<'a, ...> {
149//!     /// Creates a new builder.
150//!     pub const fn new() -> Self;
151//!
152//!     /// Returns the finished value.
153//!     ///
154//!     /// This function can only be called when all required fields have been set.
155//!     pub const fn build(self) -> Person<'a>;
156//!
157//!     // one setter function per field
158//!     pub const fn name(self, value: &'a str) -> PersonBuilder<'a, ...>;
159//!     pub const fn age(self, value: u32) -> PersonBuilder<'a, ...>;
160//!
161//!     /// Unwraps this builder into its unsafe counterpart.
162//!     ///
163//!     /// This isn't unsafe in itself, however using it carelessly may lead to
164//!     /// leaking objects and not dropping initialized values.
165//!     const fn into_unchecked(self) -> PersonUncheckedBuilder<'a>;
166//! }
167//!
168//! impl<'a> Person<'a> {
169//!     /// Creates a new builder for this type.
170//!     pub const fn builder() -> PersonBuilder<'a>;
171//! }
172//!
173//! /// An _unchecked_ builder type for [`Person`].
174//! ///
175//! /// This version being _unchecked_ means it has less safety guarantees:
176//! /// - No tracking is done whether fields are initialized, so [`Self::build`] is `unsafe`.
177//! /// - If dropped, already initialized fields will be leaked.
178//! /// - The same field can be set multiple times. If done, the old value will be leaked.
179//! struct PersonUncheckedBuilder<'a> { ... }
180//!
181//! impl<'a> PersonUncheckedBuilder<'a> {
182//!    /// Creates a new unchecked builder.
183//!    pub const fn new() -> Self;
184//!
185//!    /// Asserts that the fields specified by the const generics as well as all optional
186//!    /// fields are initialized and promotes this value into a checked builder.
187//!    ///
188//!    /// # Safety
189//!    ///
190//!    /// The fields whose const generics are `true` and all optional (including skipped)
191//!    /// fields must be initialized.
192//!    ///
193//!    /// Optional fields are initialized by [`Self::new`] by default, however using
194//!    /// [`Self::as_uninit`] allows de-initializing them. This means that this function
195//!    /// isn't even necessarily safe to call if all const generics are `false`.
196//!    ///
197//!    /// If the struct has been fully deinitialized previously (f.e. via
198//!    /// `*this.as_uninit() = MaybeUninit::uninit()`) and private fields are inaccessible,
199//!    /// calling this function may always be unsound.
200//!    pub const unsafe fn assert_init<const _NAME: bool, const _AGE: bool>(self) -> PersonBuilder<'a, _NAME, _AGE>;
201//!
202//!    /// Returns the finished value.
203//!    ///
204//!    /// # Safety
205//!    ///
206//!    /// _All_ fields must be initialized.
207//!    ///
208//!    /// Optional (including skipped) fields also must be initialized. Optional fields
209//!    /// are initialized by [`Self::new`] by default, however using [`Self::as_uninit`]
210//!    /// allows de-initializing them.
211//!    ///
212//!    /// If the struct has been fully deinitialized previously (f.e. via
213//!    /// `*this.as_uninit() = MaybeUninit::uninit()`) and private fields are inaccessible,
214//!    /// calling this function may always be unsound.
215//!    pub const unsafe fn build(self) -> Person<'a>;
216//!
217//!    // one setter function per field
218//!    pub const fn name(self, value: &'a str) -> Self;
219//!    pub const fn age(self, value: u32) -> Self;
220//!
221//!    /// Gets a mutable reference to the partially initialized data.
222//!    pub const fn as_uninit(&mut self) -> &mut ::core::mem::MaybeUninit<Person<'a>>;
223//! }
224//! # );
225//! ```
226//!
227//! # Struct Attributes
228//!
229//! These attributes can be specified within `#[builder(...)]` on the struct
230//! level.
231//!
232//! | Attribute                   | Meaning |
233//! |:--------------------------- |:------- |
234//! | `default`                   | Generate a const-compatible `*::default()` function and a [`Default`] derive. Requires every field to have a default value. |
235//! | `vis = "$vis"`              | Change the visibility of the builder type. May be an empty string for private. Default is the same as the struct. |
236//! | `rename = $name`            | Renames the builder type. Defaults to "`<Type>Builder`". |
237//! | `rename_fn = $name`         | Renames the associated function that creates the builder. Defaults to `builder`. Set to `false` to disable. |
238//! | `unchecked(vis = "$vis")`   | Change the visibility of the unchecked builder type. Default is private. |
239//! | `unchecked(rename = $name)` | Renames the unchecked builder type. Defaults to "`<Type>UncheckedBuilder`". |
240//!
241//! # Field Attributes
242//!
243//! These attributes can be specified within `#[builder(...)]` on the struct's
244//! fields.
245//!
246//! | Attribute                      | Meaning |
247//! |:------------------------------ |:------- |
248//! | `vis = "$vis"`                 | Change the visibility of the builder's field setter. May be an empty string for private. Default is `pub`. If you intend to hide the field from the public API, prefer `skip`. |
249//! | `default = $value`             | Make the field optional by providing a default value. The value must be evaluatable in `const`. |
250//! | `rename = $name`               | Renames the setters for this field. Defaults to the field name. |
251//! | `rename_generic = $name`       | Renames the name of the associated const generic. Defaults to "`_{field:upper}`". |
252//! | `leak_on_drop`                 | Instead of dropping the field when dropping the builder, do nothing. |
253//! | `unsized_tail`                 | In a packed struct, marks the last field as potentially being unsized, replacing the drop code with an assert. No effect if the struct isn't packed. |
254//! | `setter(transform = $closure)` | Accepts closure syntax. The setter is changed to accept its inputs and set the corresponding value to its output. Parameter types are required. The closure body must be evaluatable in `const`. |
255//! | `setter(strip_option)`         | On an [`Option<T>`] field, change the setter to accept `T` and wrap it in [`Some`] itself. Equivalent to `setter(transform = \|value: T\| Some(value))`. |
256//! | `skip`                         | Must be combined with `default`. Hides the field from the builder's public API by omitting its generic parameter and setter, instead forcing the default value. The unchecked builder retains a setter with the field's visibility. |
257//!
258//! # Attributes Example
259//!
260//! ```
261//! use const_builder::ConstBuilder;
262//!
263//! #[derive(ConstBuilder)]
264//! // change the builder from pub (same as Person) to crate-internal
265//! // also override the name of the builder to `CreatePerson`
266//! #[builder(vis = "pub(crate)", rename = "CreatePerson")]
267//! // change the unchecked builder from priv also to crate-internal
268//! #[builder(unchecked(vis = "pub(crate)"))]
269//! # #[derive(Debug, PartialEq)]
270//! pub struct Person<'a> {
271//!     // required field with public setter
272//!     name: &'a str,
273//!     // optional field with public setter
274//!     #[builder(default = 0)]
275//!     age: u32,
276//!     // skipped field omitted from builder interface
277//!     #[builder(default = 1, skip)]
278//!     version: u32,
279//! }
280//!
281//! # assert_eq!(
282//! #     const {
283//! #         Person::builder()
284//! #             .name("smith")
285//! #             .build()
286//! #     },
287//! #     Person {
288//! #         name: "smith",
289//! #         age: 0,
290//! #         version: 1,
291//! #     }
292//! # );
293//! ```
294//!
295//! [nomicon section on unchecked uninitialized memory]: https://doc.rust-lang.org/nomicon/unchecked-uninit.html
296
297#![forbid(unsafe_code)]
298#![warn(clippy::doc_markdown)]
299
300use proc_macro::TokenStream;
301use syn::{DeriveInput, parse_macro_input};
302
303mod const_builder_impl;
304mod model;
305mod util;
306
307/// Generates the builder types for the attributed struct.
308///
309/// See the crate-level documentation for more details.
310#[proc_macro_derive(ConstBuilder, attributes(builder))]
311pub fn single_emit_default(input: TokenStream) -> TokenStream {
312    let input = parse_macro_input!(input as DeriveInput);
313    const_builder_impl::entry_point(input).into()
314}
315
316/// Not public API. This is an internal helper for compile-fail tests.
317///
318/// This fully discards the input token stream, allowing replacing the tested
319/// struct with an entirely different definition to test that safety-relevant
320/// mismatches lead to compilation errors.
321///
322/// Related rust issue: <https://github.com/rust-lang/rust/issues/148423>
323#[doc(hidden)]
324#[deprecated = "do not use, this is an internal test helper"]
325#[proc_macro_attribute]
326pub fn __discard_input_token_stream(_args: TokenStream, _input: TokenStream) -> TokenStream {
327    TokenStream::new()
328}
329
330/// I considered UI tests but since we still emit the code on almost all errors,
331/// there are a bunch of rustc diagnostics mixed in (when the compile error
332/// isn't literally just a rustc error). These aren't stable, so those tests
333/// would just break between language versions -- or even just stable and
334/// nightly.
335///
336/// ```compile_fail
337/// #[derive(const_builder::ConstBuilder)]
338/// struct TupleStruct(u32, u64);
339/// ```
340///
341/// ```compile_fail
342/// #[derive(const_builder::ConstBuilder)]
343/// struct UnitStruct;
344/// ```
345///
346/// ```compile_fail
347/// #[derive(const_builder::ConstBuilder)]
348/// enum Enum {
349///     B { a: u32, b: u64 },
350/// }
351/// ```
352///
353/// ```compile_fail
354/// #[derive(const_builder::ConstBuilder)]
355/// union Union {
356///     a: u32,
357///     b: u64,
358/// }
359/// ```
360///
361/// ```compile_fail
362/// #[derive(const_builder::ConstBuilder)]
363/// #[builder(default)]
364/// struct InvalidDefault {
365///     a: u32,
366///     #[builder(default = 0)]
367///     b: u32,
368/// }
369/// ```
370///
371/// ```compile_fail
372/// #[derive(const_builder::ConstBuilder)]
373/// struct DefaultNoValue {
374///     #[builder(default)]
375///     a: u32,
376/// }
377/// ```
378///
379/// ```compile_fail
380/// #[derive(const_builder::ConstBuilder)]
381/// struct WrongUnsizedTailPosition {
382///     #[builder(unsized_tail)]
383///     a: u32,
384///     b: u32,
385/// }
386/// ```
387///
388/// ```compile_fail
389/// // on stable, the macro code will not compile due to `UnsizedField: Sized`
390/// // bounds. however on nightly with `trivial_bounds`, the actual output of
391/// // the macro will compile, but the bounds will still prevent instantiating
392/// // or otherwise using the builder.
393/// // see also: https://github.com/rust-lang/rust/issues/48214
394/// #[derive(const_builder::ConstBuilder)]
395/// struct UnsizedField {
396///     a: [u32],
397/// }
398///
399/// // ensure instantiating fails anyways
400/// _ = UnsizedFieldBuilder::new();
401/// ```
402///
403/// ```compile_fail
404/// // this test actually fails for two reasons:
405/// // - rust disallowing possible-Drop unsized tails in packed structs
406/// // - static assert when a packed struct's `unsized_tail` field `needs_drop`
407/// #[derive(const_builder::ConstBuilder)]
408/// #[repr(Rust, packed)]
409/// struct PackedUnsizedDropTail<T: ?Sized> {
410///     #[builder(unsized_tail)]
411///     a: T,
412/// }
413///
414/// // ensure a variant with a `needs_drop` tail is instantiated
415/// _ = PackedUnsizedDropTail::<String>::builder();
416/// ```
417///
418/// ```compile_fail
419/// #[derive(const_builder::ConstBuilder)]
420/// struct SetterCastNoClosure {
421///     #[builder(setter(transform))]
422///     value: Option<u32>,
423/// }
424/// ```
425///
426/// ```compile_fail
427/// #[derive(const_builder::ConstBuilder)]
428/// struct SetterCastNotAClosure1 {
429///     #[builder(setter(transform = r#""hello""#))]
430///     value: Option<u32>,
431/// }
432/// ```
433///
434/// ```compile_fail
435/// #[derive(const_builder::ConstBuilder)]
436/// struct SetterCastNotAClosure2 {
437///     #[builder(setter(transform = 42))]
438///     value: Option<u32>,
439/// }
440/// ```
441///
442/// ```compile_fail
443/// #[derive(const_builder::ConstBuilder)]
444/// struct SetterCastNotAClosure3 {
445///     #[builder(setter(transform = Some(42)))]
446///     value: Option<u32>,
447/// }
448/// ```
449///
450/// ```compile_fail
451/// #[derive(const_builder::ConstBuilder)]
452/// struct SetterCastNoType {
453///     #[builder(setter(transform = |i| Some(i)))]
454///     value: Option<u32>,
455/// }
456/// ```
457///
458/// ```compile_fail
459/// #[derive(const_builder::ConstBuilder)]
460/// struct SetterCastNoTypePartial1 {
461///     #[builder(setter(transform = |a: u32, b| a + b))]
462///     value: u32,
463/// }
464/// ```
465///
466/// ```compile_fail
467/// #[derive(const_builder::ConstBuilder)]
468/// struct SetterCastNoTypePartial2 {
469///     #[builder(setter(transform = |a, b: u32| a + b))]
470///     value: u32,
471/// }
472/// ```
473///
474/// ```compile_fail
475/// // `works.rs` contains a similar case that compiles
476/// #[derive(ConstBuilder)]
477/// struct SetterCastPatNoType {
478///     #[builder(setter(transform = |Wrap(v)| v))]
479///     value: u32,
480/// }
481///
482/// struct Wrap<T>(T);
483/// ```
484///
485/// ```compile_fail
486/// #[derive(const_builder::ConstBuilder)]
487/// struct SetterCastAttrs {
488///     #[builder(setter(transform = (#[inline] |i: u32| Some(i))))]
489///     value: Option<u32>,
490/// }
491/// ```
492///
493/// ```compile_fail
494/// #[derive(const_builder::ConstBuilder)]
495/// struct SetterCastWrongLifetimes {
496///     #[builder(setter(transform = for<'b> |i: &'a u32| Some(*i)))]
497///     value: Option<u32>,
498/// }
499/// ```
500///
501/// ```compile_fail
502/// #[derive(const_builder::ConstBuilder)]
503/// struct SetterCastConst {
504///     #[builder(setter(transform = const |i: u32| Some(i)))]
505///     value: Option<u32>,
506/// }
507/// ```
508///
509/// ```compile_fail
510/// #[derive(const_builder::ConstBuilder)]
511/// struct SetterCastStatic {
512///     #[builder(setter(transform = static |i: u32| Some(i)))]
513///     value: Option<u32>,
514/// }
515/// ```
516///
517/// ```compile_fail
518/// #[derive(const_builder::ConstBuilder)]
519/// struct SetterCastAsync {
520///     #[builder(setter(transform = async |i: u32| Some(i)))]
521///     value: Option<u32>,
522/// }
523/// ```
524///
525/// ```compile_fail
526/// #[derive(const_builder::ConstBuilder)]
527/// struct SetterCastMove {
528///     #[builder(setter(transform = move |i: u32| Some(i)))]
529///     value: Option<u32>,
530/// }
531/// ```
532///
533/// ```compile_fail
534/// #[derive(const_builder::ConstBuilder)]
535/// struct SetterCastReturnType {
536///     #[builder(setter(transform = |i: u32| -> Option<u32> { Some(i) }))]
537///     value: Option<u32>,
538/// }
539/// ```
540///
541/// ```compile_fail
542/// #[derive(const_builder::ConstBuilder)]
543/// struct SetterCastAndStrip {
544///     #[builder(setter(strip_option, transform = |i: u32| Some(i)))]
545///     value: Option<u32>,
546/// }
547/// ```
548///
549/// ```compile_fail
550/// #[derive(const_builder::ConstBuilder)]
551/// struct SetterCastWrongType {
552///     #[builder(setter(transform = |v: u32| v))]
553///     value: i32,
554/// }
555/// ```
556///
557/// ```compile_fail
558/// #[derive(const_builder::ConstBuilder)]
559/// struct SetterUnknown {
560///     #[builder(setter(strip_result))]
561///     value: Result<u32, u32>,
562/// }
563/// ```
564///
565/// ```compile_fail
566/// #[derive(const_builder::ConstBuilder)]
567/// struct SetterStripOptionNotOption {
568///     #[builder(setter(strip_option))]
569///     value: Result<(), ()>,
570/// }
571/// ```
572///
573/// ```compile_fail
574/// #[derive(const_builder::ConstBuilder)]
575/// struct SetterStripOptionDefault {
576///     #[builder(default, setter(strip_option))]
577///     value: Option<u32>,
578/// }
579/// ```
580///
581/// ```compile_fail
582/// use core::marker::PhantomData;
583///
584/// #[derive(const_builder::ConstBuilder)]
585/// struct InvalidUse<T = u32> {
586///     #[builder(default = PhantomData)]
587///     marker: PhantomData<T>,
588/// }
589///
590/// // fails because it can't infer the generic type
591/// let value = InvalidUse::builder().build();
592/// ```
593///
594/// ```compile_fail
595/// #[derive(const_builder::ConstBuilder)]
596/// struct Incomplete1 {
597///     unset: bool,
598/// }
599///
600/// let value = Incomplete1::builder().build();
601/// ```
602///
603/// ```compile_fail
604/// #[derive(const_builder::ConstBuilder)]
605/// struct Incomplete2 {
606///     #[builder(default = false)]
607///     defaulted: bool,
608///     unset: bool,
609/// }
610///
611/// let value = Incomplete2::builder().build();
612/// ```
613///
614/// ```compile_fail
615/// #[derive(const_builder::ConstBuilder)]
616/// struct Incomplete3 {
617///     set: bool,
618///     unset: bool,
619/// }
620///
621/// let value = Incomplete3::builder().set(true).build();
622/// ```
623///
624/// ```compile_fail
625/// #[derive(const_builder::ConstBuilder)]
626/// struct DuplicateSet {
627///     field: bool,
628/// }
629///
630/// DuplicateSet::builder().field(true).field(true);
631/// ```
632///
633/// ```compile_fail
634/// #[derive(const_builder::ConstBuilder)]
635/// struct SkipNoDefault {
636///     #[builder(skip)]
637///     field: bool,
638/// }
639/// ```
640///
641/// ```compile_fail
642/// #[derive(const_builder::ConstBuilder)]
643/// struct SkipSetter {
644///     #[builder(skip, default = None, setter())]
645///     field: Option<u32>,
646/// }
647/// ```
648///
649/// ```compile_fail
650/// #[derive(const_builder::ConstBuilder)]
651/// struct SkipVis {
652///     #[builder(skip, default = None, vis = "pub")]
653///     field: Option<u32>,
654/// }
655/// ```
656///
657/// ```compile_fail
658/// #[derive(const_builder::ConstBuilder)]
659/// struct SkipRename {
660///     #[builder(skip, default = None, rename_generic = "_F")]
661///     field: Option<u32>,
662/// }
663/// ```
664///
665/// ```compile_fail
666/// #[derive(const_builder::ConstBuilder)]
667/// struct SkipNoSetter {
668///     #[builder(skip, default = None)]
669///     field: Option<u32>,
670/// }
671///
672/// // no setter
673/// _ = SkipNoSetter::builder().field(Some(0));
674/// ```
675///
676/// ```compile_fail
677/// mod inner {
678///     #[derive(const_builder::ConstBuilder)]
679///     #[builder(unchecked(vis = "pub"))]
680///     pub struct SkipPrivSetter {
681///         #[builder(skip, default = None)]
682///         field: Option<u32>,
683///     }
684/// }
685///
686/// // setter private
687/// _ = inner::SkipPrivSetterUncheckedBuilder::new().field(Some(0));
688/// ```
689///
690/// ```compile_fail
691/// // !! safety-relevant !!
692/// // a field not observed by the macro would allow
693/// // safe code to later read uninitialized memory.
694/// #[derive(const_builder::ConstBuilder)]
695/// #[const_builder::__discard_input_token_stream]
696/// struct AddsField {}
697/// struct AddsField {
698///     x: u32,
699/// }
700/// ```
701///
702/// ```compile_fail
703/// // this just fails because the builder tries to access
704/// // an unknown field.
705/// #[derive(const_builder::ConstBuilder)]
706/// #[const_builder::__discard_input_token_stream]
707/// struct RemovesField {
708///     x: u32,
709/// }
710/// struct RemovesField {}
711/// ```
712///
713/// ```compile_fail
714/// // !! safety-relevant !!
715/// // unaligned access requires a different emit because
716/// // writing to unaligned pointers is UB by default.
717/// // the inverse of this is fine, if not optimal.
718/// #[derive(const_builder::ConstBuilder)]
719/// #[const_builder::__discard_input_token_stream]
720/// struct ActuallyPacked {
721///     x: u32,
722/// }
723/// #[repr(C, packed)]
724/// struct ActuallyPacked {
725///     x: u32,
726/// }
727/// ```
728fn _compile_fail_test() {}