Closed EdJoPaTo closed 2 weeks ago
I agree, must_use
should be the on the build()
method. It's an oversight that it isn't there.
If you want, you can make a PR with this change, or I can do it myself a bit later anyway. There change should go into the FinishFunc
struct config of the builder_gen
module (the shared module that is used to generate the builder for both struct and function inputs):
https://github.com/elastio/bon/blob/d49a3b56790768daafb4b0e869f0b5e2dd722d29/bon-macros/src/builder/builder_gen/mod.rs#L45-L52
We should configure it to enable must_use
for struct inputs only. I believe must_use
doesn't make sense for functions by default (only for structs). Additionally, maybe the code could also search for a must_use
attribute on the function (if the input is an fn
), and if it's present, then forward that attribute to the FinishFunc
.
I'd be happy to add that as it would be a learning for me to tinker with proc macros. So I'd like to provide a PR later.
For now: adding must_use
is considered a breaking change. For this case I would say its rather fixing a bug as it restores the intended behaviour. When there is no must_use
it's likely a bug. So such a PR should not require a new major release in my opinion.
For this case I would say its rather fixing a bug as it restores the intended behaviour.
This is my thinking as well. I think this kind of breakage is the one people would like to see.
But.. I'd like to argue that adding #[must_use]
is not a breaking change by itself. It's breaking if and only if you deny warnings on CI. The violation of #[must_use]
is a warning, not a compile error.
According to the cargo book "introducing new lints" such as #[deprecated]
, #[must_use]
, or any other change to the crate API that doesn't physically produce a compile error can be regarded as a minor change.
Once this change lands in master a minor version of bon
will be bumped.
Just noticed I remembered this wrongly, cargo-semver-checks
also sees must_use
as a minor change.
$ cargo semver-checks --list | rg must_use
enum_must_use_added minor An enum has been marked with #[must_use].
function_must_use_added minor A function has been marked with #[must_use].
inherent_method_must_use_added minor An inherent method or associated fn has been marked #[must_use].
struct_must_use_added minor A struct has been marked with #[must_use].
trait_must_use_added minor A trait has been marked with #[must_use].
union_must_use_added minor A union has been marked with #[must_use].
While I like seeing the
struct FooBuilder<…>
having amust_use
(#26) I'm not sure why thebuild()
method does not have one. SomeInto
implementations could have side effects but other than that it should just create an object which hasn't been used so far. So its likely wrong when thebuild()
output isn't used?