diff --git a/charon-ml/src/generated/Generated_GAst.ml b/charon-ml/src/generated/Generated_GAst.ml index 7187865e6..49c3a11ed 100644 --- a/charon-ml/src/generated/Generated_GAst.ml +++ b/charon-ml/src/generated/Generated_GAst.ml @@ -431,15 +431,21 @@ type cli_options = { break this mutual recursion. *) precise_drops : bool; (** Whether to precisely translate drops and drop-related code. For this, - we add explicit [Destruct] bounds to all generic parameters, and set - the MIR level to at least [elaborated]. + we add explicit [Destruct] bounds to all generic parameters, set the + MIR level to at least [elaborated], and attempt to retrieve drop glue + for all types. + + This option is known to cause panics inside rustc, because their drop + handling is not design to work on polymorphic types. To silence the + warning, pass appropriate + [--opaque '{impl core::marker::Destruct for some::Type}'] options. Without this option, drops may be "conditional" and we may lack information about what code is run on drop in a given polymorphic function body. *) desugar_drops : bool; - (** If activated, transform [Drop(p)] to [Call drop_in_place(&raw mut p)]. - *) + (** Transform precise drops to the equivalent [drop_in_place(&raw mut p)] + call. *) start_from : string list; (** A list of item paths to use as starting points for the translation. We will translate these items and any items they refer to, according to diff --git a/charon/Cargo.lock b/charon/Cargo.lock index 0af7f2054..17940dbad 100644 --- a/charon/Cargo.lock +++ b/charon/Cargo.lock @@ -836,7 +836,7 @@ dependencies = [ [[package]] name = "hax-adt-into" version = "0.3.5" -source = "git+https://github.com/AeneasVerif/hax?branch=main#665a80bc5ad21cafb5081df336192ec0de62b9f5" +source = "git+https://github.com/AeneasVerif/hax?branch=main#5f86b92040418d3f025c2c274ecaf8f4a66016b5" dependencies = [ "itertools 0.11.0", "proc-macro2", @@ -847,7 +847,7 @@ dependencies = [ [[package]] name = "hax-frontend-exporter" version = "0.3.5" -source = "git+https://github.com/AeneasVerif/hax?branch=main#665a80bc5ad21cafb5081df336192ec0de62b9f5" +source = "git+https://github.com/AeneasVerif/hax?branch=main#5f86b92040418d3f025c2c274ecaf8f4a66016b5" dependencies = [ "extension-traits", "hax-adt-into", @@ -864,7 +864,7 @@ dependencies = [ [[package]] name = "hax-frontend-exporter-options" version = "0.3.5" -source = "git+https://github.com/AeneasVerif/hax?branch=main#665a80bc5ad21cafb5081df336192ec0de62b9f5" +source = "git+https://github.com/AeneasVerif/hax?branch=main#5f86b92040418d3f025c2c274ecaf8f4a66016b5" dependencies = [ "hax-adt-into", "schemars", diff --git a/charon/src/bin/charon-driver/translate/translate_drops.rs b/charon/src/bin/charon-driver/translate/translate_drops.rs index b014511ac..2b3ae6e45 100644 --- a/charon/src/bin/charon-driver/translate/translate_drops.rs +++ b/charon/src/bin/charon-driver/translate/translate_drops.rs @@ -1,7 +1,7 @@ use crate::translate::translate_crate::TransItemSourceKind; use super::translate_ctx::*; -use charon_lib::ast::*; +use charon_lib::{ast::*, formatter::IntoFormatter, pretty::FmtWithCtx}; use hax::FullDefKind; impl ItemTransCtx<'_, '_> { @@ -9,14 +9,46 @@ impl ItemTransCtx<'_, '_> { &mut self, span: Span, def: &hax::FullDef, + self_ty: &Ty, ) -> Result
{ let (hax::FullDefKind::Adt { drop_glue, .. } | hax::FullDefKind::Closure { drop_glue, .. }) = def.kind() else { - return Ok(Body::Opaque); + return Ok(Body::Missing); }; - let Some(body) = drop_glue else { - return Ok(Body::Opaque); + + let tmp_body; + let body = match drop_glue { + Some(body) => body, + None if self.options.translate_poly_drop_glue => { + let ctx = std::panic::AssertUnwindSafe(&mut *self); + // This is likely to panic, see the docs of `--precise-drops`. + let Ok(body) = + std::panic::catch_unwind(move || def.this().drop_glue_shim(ctx.hax_state())) + else { + let self_ty_name = if let TyKind::Adt(TypeDeclRef { + id: TypeId::Adt(type_id), + .. + }) = self_ty.kind() + && let Some(name) = self.translated.item_name(*type_id) + { + name.to_string_with_ctx(&self.into_fmt()) + } else { + "crate::the::Type".to_string() + }; + raise_error!( + self, + span, + "rustc panicked while retrieving drop glue. \ + This is known to happen with `--precise-drops`; to silence this warning, \ + pass `--opaque '{{impl core::marker::Destruct for {}}}'` to charon", + self_ty_name + ) + }; + tmp_body = body; + &tmp_body + } + None => return Ok(Body::Missing), }; Ok(self.translate_body(span, body, &def.source_text)) @@ -82,7 +114,7 @@ impl ItemTransCtx<'_, '_> { let body = if item_meta.opacity.with_private_contents().is_opaque() { Body::Opaque } else { - self.translate_drop_in_place_method_body(span, def)? + self.translate_drop_in_place_method_body(span, def, &self_ty)? }; let input = TyKind::RawPtr(self_ty, RefKind::Mut).into_ty(); diff --git a/charon/src/options.rs b/charon/src/options.rs index 3998fad2e..137a30398 100644 --- a/charon/src/options.rs +++ b/charon/src/options.rs @@ -180,15 +180,19 @@ pub struct CliOpts { #[serde(default)] pub remove_unused_self_clauses: bool, /// Whether to precisely translate drops and drop-related code. For this, we add explicit - /// `Destruct` bounds to all generic parameters, and set the MIR level to at least - /// `elaborated`. + /// `Destruct` bounds to all generic parameters, set the MIR level to at least `elaborated`, + /// and attempt to retrieve drop glue for all types. + /// + /// This option is known to cause panics inside rustc, because their drop handling is not + /// design to work on polymorphic types. To silence the warning, pass appropriate `--opaque + /// '{impl core::marker::Destruct for some::Type}'` options. /// /// Without this option, drops may be "conditional" and we may lack information about what code /// is run on drop in a given polymorphic function body. #[clap(long)] #[serde(default)] pub precise_drops: bool, - /// If activated, transform `Drop(p)` to `Call drop_in_place(&raw mut p)`. + /// Transform precise drops to the equivalent `drop_in_place(&raw mut p)` call. #[clap(long)] #[serde(default)] pub desugar_drops: bool, @@ -490,7 +494,10 @@ pub struct TranslateOptions { pub remove_associated_types: Vec