Skip to content

Commit 43cb451

Browse files
committed
Add derive_unsafe feature flag
1 parent c9c6eec commit 43cb451

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

nutype/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ regex = ["nutype_macros/regex"]
3131
schemars08 = ["nutype_macros/schemars08"]
3232
new_unchecked = ["nutype_macros/new_unchecked"]
3333
arbitrary = ["nutype_macros/arbitrary"]
34+
derive_unsafe = ["nutype_macros/derive_unsafe"]

nutype_macros/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ serde = []
4141
schemars08 = []
4242
new_unchecked = []
4343
arbitrary = []
44+
derive_unsafe = []

nutype_macros/src/common/parse/mod.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,31 @@ where
314314
}
315315
}
316316
} else if ident == "derive_unsafe" {
317-
if input.peek(Paren) {
318-
let content;
319-
parenthesized!(content in input);
320-
let items =
321-
content.parse_terminated(SpannedDeriveUnsafeTrait::parse, Token![,])?;
322-
attrs.derive_unsafe_traits = items.into_iter().collect();
323-
} else {
324-
let msg = "`derive_unsafe(...)` must be used with parenthesis.";
325-
return Err(syn::Error::new(ident.span(), msg));
317+
cfg_if! {
318+
if #[cfg(feature = "derive_unsafe")] {
319+
if input.peek(Paren) {
320+
let content;
321+
parenthesized!(content in input);
322+
let items =
323+
content.parse_terminated(SpannedDeriveUnsafeTrait::parse, Token![,])?;
324+
attrs.derive_unsafe_traits = items.into_iter().collect();
325+
} else {
326+
let msg = "`derive_unsafe(...)` must be used with parenthesis.";
327+
return Err(syn::Error::new(ident.span(), msg));
328+
}
329+
} else {
330+
// The feature is not enabled, so we return an error
331+
let msg = concat!(
332+
"To use derive_unsafe() function, the feature `derive_unsafe` of crate `nutype` needs to be enabled.\n\n",
333+
"DID YOU KNOW?\n",
334+
"It's called `derive_unsafe` because it enables to derive any traits that nutype is not aware of.\n",
335+
"So it is developer's responsibility to ensure that the derived traits do not create a loophole to bypass the constraints.\n",
336+
"As the rule of thumb avoid using `derive_unsafe` with traits that:\n",
337+
"- Create a new instance of the type\n",
338+
"- Mutate the value\n\n",
339+
);
340+
return Err(syn::Error::new(ident.span(), msg));
341+
}
326342
}
327343
} else {
328344
let msg = format!("Unknown attribute `{ident}`");

0 commit comments

Comments
 (0)