Skip to content

Commit 010be99

Browse files
committed
[derive] Add unsafe attribute to skip generating destructor
This is useful if you want to avoid drop glue, `mem::needs_drop` or want to implement your own custom destructor that you know is `GcSafe`.
1 parent 2ae31ff commit 010be99

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

libs/derive/src/lib.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,10 @@ struct TypeAttrs {
139139
gc_lifetime: Option<Lifetime>,
140140
collector_id: Option<Ident>,
141141
ignore_params: HashSet<Ident>,
142-
ignored_lifetimes: HashSet<Lifetime>
142+
ignored_lifetimes: HashSet<Lifetime>,
143+
/// Unsafely assume the type is safe to [drop]
144+
/// from a GC, as consistent with the requirements of [GcSafe]
145+
unsafe_drop_safe: bool
143146
}
144147
impl TypeAttrs {
145148
fn gc_lifetime(&self) -> Lifetime {
@@ -205,6 +208,20 @@ impl Parse for TypeAttrs {
205208
))
206209
}
207210
result.is_copy = true;
211+
} else if meta.path().is_ident("unsafe_drop_safe") {
212+
if !matches!(meta, Meta::Path(_)) {
213+
return Err(Error::new(
214+
meta.span(),
215+
"Malformed attribute for #[zerogc(unsafe_drop_safe)]"
216+
))
217+
}
218+
if result.unsafe_drop_safe {
219+
return Err(Error::new(
220+
meta.span(),
221+
"Duplicate flags: #[zerogc(unsafe_drop_safe)]"
222+
))
223+
}
224+
result.unsafe_drop_safe = true;
208225
} else if meta.path().is_ident("nop_trace") {
209226
if !matches!(meta, Meta::Path(_)) {
210227
return Err(Error::new(
@@ -973,7 +990,7 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
973990
* in the first place.
974991
*/
975992
quote!()
976-
} else {
993+
} else if !info.config.unsafe_drop_safe {
977994
quote!(impl #impl_generics Drop for #name #ty_generics #where_clause {
978995
#[inline]
979996
fn drop(&mut self) {

0 commit comments

Comments
 (0)