1use annotate_snippets::Level;
3use clap::ValueEnum;
4use indoc::indoc;
5use itertools::Itertools;
6use macros::EnumAsGetters;
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10use crate::{
11 ast::*,
12 errors::{ErrorCtx, display_unspanned_error},
13 name_matcher::NamePattern,
14 raise_error, register_error,
15};
16
17pub const CHARON_ARGS: &str = "CHARON_ARGS";
20
21#[derive(Debug, Default, Clone, PartialEq, Eq)]
30#[derive(clap::Args)]
31#[derive(Serialize, Deserialize)]
32#[clap(name = "Charon")]
33#[cfg_attr(feature = "charon_on_charon", charon::rename("cli_options"))]
34pub struct CliOpts {
35 #[clap(long)]
37 #[serde(default)]
38 pub ullbc: bool,
39 #[clap(long)]
45 #[serde(default)]
46 pub no_code_duplication: bool,
47 #[clap(long)]
53 #[serde(default)]
54 pub precise_drops: bool,
55 #[arg(long)]
58 pub mir: Option<MirLevel>,
59 #[clap(long = "rustc-arg")]
61 #[serde(default)]
62 pub rustc_args: Vec<String>,
63 #[clap(long, value_delimiter = ',')]
68 #[serde(default)]
69 pub targets: Vec<String>,
70 #[clap(long)]
75 #[serde(default)]
76 pub sysroot: Option<String>,
77
78 #[clap(long, visible_alias = "mono")]
82 #[serde(default)]
83 pub monomorphize: bool,
84 #[clap(
88 long,
89 value_name("INCLUDE_TYPES"),
90 num_args(0..=1),
91 require_equals(true),
92 default_missing_value("all"),
93 )]
94 #[serde(default)]
95 pub monomorphize_mut: Option<MonomorphizeMut>,
96
97 #[clap(long, value_delimiter = ',')]
101 #[serde(default)]
102 pub start_from: Vec<String>,
103 #[clap(long, value_delimiter = ',')]
106 #[serde(default)]
107 pub start_from_if_exists: Vec<String>,
108 #[clap(
112 long,
113 value_name("ATTRIBUTE"),
114 num_args(0..),
115 require_equals(true),
116 value_delimiter = ',',
117 default_missing_value("verify::start_from"),
118 )]
119 #[serde(default)]
120 pub start_from_attribute: Vec<String>,
121 #[clap(long)]
123 #[serde(default)]
124 pub start_from_pub: bool,
125
126 #[clap(
128 long,
129 help = indoc!("
130 Whitelist of items to translate. These use the name-matcher syntax (note: this differs
131 a bit from the ocaml NameMatcher).
132
133 Note: This is very rough at the moment. E.g. this parses `u64` as a path instead of the
134 built-in type. It is also not possible to filter a trait impl (this will only filter
135 its methods). Please report bugs or missing features.
136
137 Examples:
138 - `crate::module1::module2::item`: refers to this item and all its subitems (e.g.
139 submodules or trait methods);
140 - `crate::module1::module2::item::_`: refers only to the subitems of this item;
141 - `core::convert::{impl core::convert::Into<_> for _}`: retrieve the body of this
142 very useful impl;
143
144 When multiple patterns in the `--include` and `--opaque` options match the same item,
145 the most precise pattern wins. E.g.: `charon --opaque crate::module --include
146 crate::module::_` makes the `module` opaque (we won't explore its contents), but the
147 items in it transparent (we will translate them if we encounter them.)
148 "))]
149 #[serde(default)]
150 #[cfg_attr(feature = "charon_on_charon", charon::rename("included"))]
151 pub include: Vec<String>,
152 #[clap(long)]
154 #[serde(default)]
155 pub opaque: Vec<String>,
156 #[clap(long)]
158 #[serde(default)]
159 pub exclude: Vec<String>,
160 #[clap(long)]
163 #[serde(default)]
164 pub extract_opaque_bodies: bool,
165 #[clap(long)]
168 #[serde(default)]
169 pub translate_all_methods: bool,
170 #[clap(long)]
174 #[serde(default)]
175 pub eager_vtables: bool,
176 #[clap(long)]
180 #[serde(default)]
181 pub duplicate_defaulted_methods: bool,
182
183 #[clap(long, alias = "remove-associated-types")]
186 #[serde(default)]
187 pub lift_associated_types: Vec<String>,
188 #[clap(long)]
191 #[serde(default)]
192 pub hide_marker_traits: bool,
193 #[clap(long)]
195 #[serde(default)]
196 pub hide_allocator: bool,
197 #[clap(long)]
199 #[serde(default)]
200 pub no_doc_comments: bool,
201
202 #[clap(long)]
206 #[serde(default)]
207 pub remove_unused_clauses: bool,
208 #[clap(long)]
213 #[serde(default)]
214 pub remove_unused_self_clauses: bool,
215 #[clap(long)]
218 #[serde(default)]
219 pub remove_adt_clauses: bool,
220
221 #[clap(long)]
223 #[serde(default)]
224 pub desugar_drops: bool,
225 #[clap(long)]
229 #[serde(default)]
230 pub resugar_drops: bool,
231 #[clap(long)]
233 #[serde(default)]
234 pub detect_drop_flags: bool,
235 #[clap(long)]
238 #[serde(default)]
239 pub ops_to_function_calls: bool,
240 #[clap(long)]
244 #[serde(default)]
245 pub index_to_function_calls: bool,
246 #[clap(long)]
248 #[serde(default)]
249 pub treat_box_as_builtin: bool,
250 #[clap(long)]
256 #[serde(default)]
257 pub no_gen_tuple_structs: bool,
258 #[clap(long)]
260 #[serde(default)]
261 pub raw_consts: bool,
262 #[clap(long)]
266 #[serde(default)]
267 pub inline_anon_consts: bool,
268 #[clap(long)]
272 #[serde(default)]
273 pub consts: Option<ConstHandling>,
274 #[clap(long)]
277 #[serde(default)]
278 pub unsized_strings: bool,
279 #[clap(long)]
282 #[serde(default)]
283 pub reconstruct_fallible_operations: bool,
284 #[clap(long)]
286 #[serde(default)]
287 pub reconstruct_panic_calls: bool,
288 #[clap(long)]
290 #[serde(default)]
291 pub reconstruct_asserts: bool,
292 #[clap(long)]
295 #[serde(default)]
296 pub reconstruct_matches: bool,
297 #[clap(long)]
301 #[serde(default)]
302 pub deallocate_all_locals: bool,
303 #[clap(long)]
307 #[serde(default)]
308 pub unbind_item_vars: bool,
309
310 #[clap(long)]
312 #[serde(default)]
313 pub print_original_ullbc: bool,
314 #[clap(long)]
316 #[serde(default)]
317 pub print_ullbc: bool,
318 #[clap(long)]
320 #[serde(default)]
321 pub print_built_llbc: bool,
322 #[clap(long)]
324 #[serde(default)]
325 pub print_llbc: bool,
326 #[clap(long)]
328 #[serde(default)]
329 pub print_layouts: bool,
330 #[clap(long)]
332 #[serde(default)]
333 pub print_safety: bool,
334 #[clap(long = "dest", value_parser)]
338 #[serde(default)]
339 pub dest_dir: Option<PathBuf>,
340 #[clap(long, value_parser)]
344 #[serde(default)]
345 pub dest_file: Option<PathBuf>,
346 #[clap(long)]
348 #[serde(default)]
349 pub no_dedup_serialized_ast: bool,
350 #[clap(long, value_enum)]
352 #[serde(default)]
353 pub format: Option<SerializationFormatArg>,
354 #[clap(long)]
356 #[serde(default)]
357 pub run_with_minirust: bool,
358 #[clap(long)]
360 #[serde(default)]
361 pub no_serialize: bool,
362 #[clap(
364 long = "skip-borrow-check",
365 alias = "skip-borrowck",
366 visible_alias = "no-borrow-check",
367 alias = "no-borrowck"
368 )]
369 #[serde(default)]
370 pub skip_borrowck: bool,
371 #[clap(long)]
373 #[serde(default)]
374 pub erase_body_lifetimes: bool,
375 #[clap(long)]
377 #[serde(default)]
378 pub no_typecheck: bool,
379 #[clap(long)]
381 #[serde(default)]
382 pub no_normalize: bool,
383 #[clap(long)]
385 #[serde(default)]
386 pub no_reorder_decls: bool,
387 #[clap(long)]
389 #[serde(default)]
390 pub no_compute_layout_guarantees: bool,
391 #[clap(long)]
393 #[serde(default)]
394 pub abort_on_error: bool,
395 #[clap(long)]
397 #[serde(default)]
398 pub error_on_warnings: bool,
399
400 #[clap(long)]
402 #[arg(value_enum)]
403 pub preset: Option<Preset>,
404}
405
406#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
409#[derive(ValueEnum)]
410#[derive(Serialize, Deserialize)]
411pub enum MirLevel {
412 Built,
414 Promoted,
416 Elaborated,
419 Optimized,
422}
423
424#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
427#[derive(ValueEnum)]
428#[derive(Serialize, Deserialize)]
429#[non_exhaustive]
430pub enum Preset {
431 OldDefaults,
434 RawMir,
437 Fast,
439 Aeneas,
440 Eurydice,
441 Soteria,
442 Tests,
443}
444
445#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
447#[derive(ValueEnum)]
448#[derive(Serialize, Deserialize)]
449pub enum ConstHandling {
450 #[default]
453 Initializers,
454 Values,
457 Bytes,
460}
461
462#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
463#[derive(ValueEnum)]
464#[derive(Serialize, Deserialize)]
465pub enum MonomorphizeMut {
466 #[default]
468 All,
469 ExceptTypes,
471}
472
473#[derive(Debug, Copy, Clone, PartialEq, Eq)]
474#[derive(ValueEnum)]
475#[derive(Serialize, Deserialize)]
476pub enum SerializationFormatArg {
477 Json,
478 Postcard,
479 #[value(name = "minirust")]
480 MiniRust,
481 #[cfg_attr(feature = "charon_on_charon", charon::rename("AllFormats"))]
482 All,
483}
484
485#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
486#[derive(ValueEnum)]
487#[derive(Serialize, Deserialize)]
488pub enum SerializationFormat {
489 #[default]
490 Json,
491 Postcard,
492 #[value(name = "minirust")]
493 MiniRust,
494}
495
496impl SerializationFormatArg {
497 pub fn as_format(self) -> Option<SerializationFormat> {
498 match self {
499 SerializationFormatArg::Json => Some(SerializationFormat::Json),
500 SerializationFormatArg::Postcard => Some(SerializationFormat::Postcard),
501 SerializationFormatArg::MiniRust => Some(SerializationFormat::MiniRust),
502 SerializationFormatArg::All => None,
503 }
504 }
505}
506
507impl From<SerializationFormat> for SerializationFormatArg {
508 fn from(format: SerializationFormat) -> SerializationFormatArg {
509 match format {
510 SerializationFormat::Json => SerializationFormatArg::Json,
511 SerializationFormat::Postcard => SerializationFormatArg::Postcard,
512 SerializationFormat::MiniRust => SerializationFormatArg::MiniRust,
513 }
514 }
515}
516
517impl SerializationFormat {
518 pub fn output_extension(self, ullbc: bool) -> &'static str {
519 match (ullbc, self) {
520 (true, SerializationFormat::Json) => "ullbc",
521 (false, SerializationFormat::Json) => "llbc",
522 (true, SerializationFormat::Postcard) => "ullbc.postcard",
523 (false, SerializationFormat::Postcard) => "llbc.postcard",
524 (_, SerializationFormat::MiniRust) => "minirust.json",
525 }
526 }
527}
528
529impl CliOpts {
530 pub fn apply_preset(&mut self) {
531 if let Some(preset) = self.preset {
532 match preset {
533 Preset::OldDefaults => {
534 self.inline_anon_consts = true;
535 self.treat_box_as_builtin = true;
536 self.hide_allocator = true;
537 self.ops_to_function_calls = true;
538 self.index_to_function_calls = true;
539 self.reconstruct_fallible_operations = true;
540 self.reconstruct_asserts = true;
541 self.reconstruct_panic_calls = true;
542 self.reconstruct_matches = true;
543 self.unbind_item_vars = true;
544 self.duplicate_defaulted_methods = true;
545 }
546 Preset::RawMir => {
547 self.extract_opaque_bodies = true;
548 self.raw_consts = true;
549 self.ullbc = true;
550 }
551 Preset::Fast => {
552 self.ullbc = true;
553 self.no_typecheck = true;
554 self.no_normalize = true;
555 self.no_reorder_decls = true;
556 self.no_compute_layout_guarantees = true;
557 self.hide_marker_traits = true;
558 self.raw_consts = true;
559 }
560 Preset::Aeneas => {
561 self.lift_associated_types.push("*".to_owned());
562 self.treat_box_as_builtin = true;
563 self.ops_to_function_calls = true;
564 self.index_to_function_calls = true;
565 self.reconstruct_fallible_operations = true;
566 self.reconstruct_panic_calls = true;
567 self.reconstruct_asserts = true;
568 self.reconstruct_matches = true;
569 self.hide_marker_traits = true;
570 self.hide_allocator = true;
571 self.remove_unused_self_clauses = true;
572 self.remove_adt_clauses = true;
573 self.unbind_item_vars = true;
574 self.deallocate_all_locals = true;
575 self.no_gen_tuple_structs = true;
576 }
577 Preset::Eurydice => {
578 self.inline_anon_consts = true;
579 self.hide_allocator = true;
580 self.treat_box_as_builtin = true;
581 self.reconstruct_fallible_operations = true;
582 self.reconstruct_panic_calls = true;
583 self.reconstruct_asserts = true;
584 self.reconstruct_matches = true;
585 self.lift_associated_types.push("*".to_owned());
586 self.unbind_item_vars = true;
587 self.duplicate_defaulted_methods = true;
588 self.include.push("core::marker::MetaSized".to_owned());
590 }
591 Preset::Soteria => {
592 self.desugar_drops = true;
593 self.extract_opaque_bodies = true;
594 self.mir = Some(MirLevel::Elaborated);
595 self.reconstruct_fallible_operations = true;
596 self.reconstruct_asserts = true;
597 self.monomorphize = true;
598 self.no_normalize = true;
599 self.no_typecheck = true;
600 self.no_reorder_decls = true;
601 self.no_compute_layout_guarantees = true;
602 self.erase_body_lifetimes = true;
603 self.no_doc_comments = true;
604 self.precise_drops = true;
605 self.consts = Some(ConstHandling::Values);
606 self.ullbc = true;
607 }
608 Preset::Tests => {
609 self.inline_anon_consts = true;
610 self.no_dedup_serialized_ast = true; self.treat_box_as_builtin = true;
612 self.hide_allocator = true;
613 self.reconstruct_fallible_operations = true;
614 self.reconstruct_panic_calls = true;
615 self.reconstruct_asserts = true;
616 self.reconstruct_matches = true;
617 if !self.desugar_drops {
618 self.resugar_drops = true;
619 }
620 if !self.monomorphize {
621 self.ops_to_function_calls = true;
622 self.index_to_function_calls = true;
623 }
624 self.duplicate_defaulted_methods = true;
625 self.deallocate_all_locals = true;
626 self.rustc_args.push("--edition=2021".to_owned());
627 self.rustc_args
628 .push("-Zcrate-attr=feature(register_tool)".to_owned());
629 self.rustc_args
630 .push("-Zcrate-attr=register_tool(charon)".to_owned());
631 self.exclude.push("core::fmt".to_owned());
632 if self.extract_opaque_bodies {
633 self.exclude
634 .extend(["core::array".to_owned(), "core::slice::index".to_owned()]);
635 }
636 }
637 }
638 }
639
640 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
641 self.monomorphize = true;
642 self.ullbc = true;
643 self.precise_drops = true;
644 self.desugar_drops = true;
645 self.deallocate_all_locals = true;
646 self.treat_box_as_builtin = true;
647 self.extract_opaque_bodies = true;
648 self.consts = Some(ConstHandling::Bytes);
649 self.mir = Some(
650 self.mir
651 .unwrap_or(MirLevel::Elaborated)
652 .max(MirLevel::Elaborated),
653 );
654 }
655 }
656
657 pub fn validate(&self) -> anyhow::Result<()> {
659 if self.dest_dir.is_some() {
660 display_unspanned_error(
661 Level::WARNING,
662 "`--dest` is deprecated, use `--dest-file` instead",
663 )
664 }
665
666 if self.remove_adt_clauses && self.lift_associated_types.is_empty() {
667 anyhow::bail!(
668 "`--remove-adt-clauses` should be used with `--lift-associated-types='*'` \
669 to avoid missing clause errors",
670 )
671 }
672 if matches!(self.monomorphize_mut, Some(MonomorphizeMut::ExceptTypes))
673 && !self.remove_adt_clauses
674 {
675 anyhow::bail!(
676 "`--monomorphize-mut=except-types` should be used with `--remove-adt-clauses` \
677 to avoid generics mismatches"
678 )
679 }
680 if self.no_gen_tuple_structs && self.monomorphize {
681 anyhow::bail!(
682 "`--no-gen-tuple-structs` is not compatible with `--monomorphize`, as \
683 monomorphization requires each tuple to have its own type declaration"
684 )
685 }
686 if self.monomorphize && (self.ops_to_function_calls || self.index_to_function_calls) {
687 anyhow::bail!(
688 "`--monomorphize` is not compatible with `--ops-to-function-calls` or \
689 `--index-to-function-calls`"
690 )
691 }
692 if self.no_serialize && self.format.is_some() {
693 anyhow::bail!(
694 "`--no-serialize` is not compatible with `--format`, the format is only relevant if we serialize"
695 );
696 }
697 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
698 if !cfg!(feature = "minirust") {
699 anyhow::bail!(
700 "MiniRust output is unavailable because Charon was built without the `minirust` feature"
701 );
702 }
703 if !self.targets.is_empty() {
704 anyhow::bail!("MiniRust output does not support multi-target translation");
705 }
706 }
707 if self.resugar_drops && self.desugar_drops {
708 anyhow::bail!("`--desugar-drops` and `--resugar-drops` are mutually incompatible")
709 }
710 Ok(())
711 }
712
713 fn target_filename(
714 &self,
715 path_base: PathBuf,
716 format: SerializationFormat,
717 ) -> (PathBuf, SerializationFormat) {
718 let extension = format.output_extension(self.ullbc);
719 let target_filename = path_base.with_added_extension(extension);
720 (target_filename, format)
721 }
722
723 pub fn targets(&self, crate_name: &str) -> Vec<(PathBuf, SerializationFormat)> {
724 if self.no_serialize {
725 return vec![];
726 }
727
728 let format = self.format.unwrap_or(SerializationFormatArg::Json);
729 let mut path_base = self.dest_dir.clone().unwrap_or_default();
730 path_base.push(crate_name);
731
732 match format.as_format() {
733 Some(format) => match self.dest_file.clone() {
734 Some(dest) => vec![(dest, format)],
735 None => vec![self.target_filename(path_base, format)],
736 },
737 None => {
738 let path_base = self.dest_file.clone().unwrap_or(path_base);
739 vec![
740 self.target_filename(path_base.clone(), SerializationFormat::Json),
741 self.target_filename(path_base, SerializationFormat::Postcard),
742 ]
743 }
744 }
745 }
746}
747
748#[derive(Debug, Clone, EnumAsGetters)]
750pub enum StartFrom {
751 Pattern { pattern: NamePattern, strict: bool },
754 Attribute(String),
756 Pub,
759}
760
761pub struct TranslateOptions {
763 pub start_from: Vec<StartFrom>,
765 pub mir_level: MirLevel,
767 pub translate_all_methods: bool,
770 pub eager_vtables: bool,
772 pub duplicate_defaulted_methods: bool,
774 pub monomorphize_mut: Option<MonomorphizeMut>,
777 pub hide_marker_traits: bool,
780 pub hide_allocator: bool,
782 pub no_doc_comments: bool,
784 pub hide_traits: Vec<NamePattern>,
787 pub remove_unused_clauses: bool,
791 pub remove_unused_self_clauses: bool,
793 pub remove_adt_clauses: bool,
795 pub monomorphize_with_hax: bool,
797 pub ullbc: bool,
799 pub no_code_duplication: bool,
802 pub ops_to_function_calls: bool,
805 pub index_to_function_calls: bool,
807 pub print_built_llbc: bool,
809 pub treat_box_as_builtin: bool,
811 pub no_gen_tuple_structs: bool,
814 pub raw_consts: bool,
816 pub inline_anon_consts: bool,
818 pub consts: ConstHandling,
820 pub unsized_strings: bool,
823 pub reconstruct_fallible_operations: bool,
826 pub reconstruct_panic_calls: bool,
828 pub reconstruct_asserts: bool,
830 pub reconstruct_matches: bool,
832 pub deallocate_all_locals: bool,
834 pub unbind_item_vars: bool,
836 pub item_opacities: Vec<(NamePattern, ItemOpacity)>,
839 pub lift_associated_types: Vec<NamePattern>,
841 pub erase_body_lifetimes: bool,
843 pub no_typecheck: bool,
845 pub no_normalize: bool,
847 pub no_reorder_decls: bool,
849 pub no_compute_layout_guarantees: bool,
851 pub desugar_drops: bool,
853 pub resugar_drops: bool,
855 pub detect_drop_flags: bool,
857 pub add_destruct_bounds: bool,
859}
860
861impl TranslateOptions {
862 pub fn new(error_ctx: &mut ErrorCtx, options: &CliOpts) -> Self {
863 let mut parse_pattern = |s: &str| -> Result<_, Error> {
864 match NamePattern::parse(s) {
865 Ok(p) => Ok(p),
866 Err(e) => raise_error!(error_ctx, no_crate, "failed to parse pattern `{s}` ({e})"),
867 }
868 };
869
870 let mut mir_level = options.mir.unwrap_or(MirLevel::Promoted);
871 if options.precise_drops {
872 mir_level = std::cmp::max(mir_level, MirLevel::Elaborated);
873 }
874
875 let mut start_from = options
876 .start_from
877 .iter()
878 .filter_map(|path| parse_pattern(path).ok())
879 .map(|p| StartFrom::Pattern {
880 pattern: p,
881 strict: true,
882 })
883 .collect_vec();
884 start_from.extend(
885 options
886 .start_from_if_exists
887 .iter()
888 .filter_map(|path| parse_pattern(path).ok())
889 .map(|p| StartFrom::Pattern {
890 pattern: p,
891 strict: false,
892 }),
893 );
894 for attr in options.start_from_attribute.iter().cloned() {
895 start_from.push(StartFrom::Attribute(attr));
896 }
897 if options.start_from_pub {
898 start_from.push(StartFrom::Pub);
899 }
900 if start_from.is_empty() {
901 start_from.push(StartFrom::Pattern {
902 pattern: parse_pattern("crate").unwrap(),
903 strict: true,
904 });
905 }
906
907 let hide_traits = options
908 .hide_marker_traits
909 .then_some([
910 "core::marker::Sized",
911 "core::marker::MetaSized",
912 "core::marker::PointeeSized",
913 "core::marker::Tuple",
914 "core::clone::TrivialClone",
915 ])
916 .into_iter()
917 .flatten()
918 .chain(options.hide_allocator.then_some("core::alloc::Allocator"))
919 .filter_map(|s| parse_pattern(s).ok())
920 .collect_vec();
921
922 let item_opacities = {
923 use ItemOpacity::*;
924 let mut opacities = vec![];
925
926 if options.extract_opaque_bodies {
928 opacities.push(("_".to_string(), Transparent));
929 } else {
930 opacities.push(("_".to_string(), Foreign));
931 }
932
933 if options.treat_box_as_builtin {
934 opacities.push((
936 "alloc::boxed::box_assume_init_into_vec_unsafe".to_string(),
937 Transparent,
938 ));
939 }
940
941 opacities.push(("crate".to_owned(), Transparent));
943
944 for pat in options.include.iter() {
945 opacities.push((pat.to_string(), Transparent));
946 }
947 for pat in options.opaque.iter() {
948 opacities.push((pat.to_string(), Opaque));
949 }
950 if options.run_with_minirust
951 || matches!(options.format, Some(SerializationFormatArg::MiniRust))
952 {
953 opacities.push(("intrinsics".to_owned(), Opaque));
957 opacities.push(("core::panicking::panic_fmt".to_owned(), Opaque));
959 }
960 for pat in options.exclude.iter() {
961 opacities.push((pat.to_string(), Invisible));
962 }
963
964 for trait_name in &hide_traits {
965 opacities.push((trait_name.to_string(), Invisible));
966 }
967
968 let hide_traits = hide_traits
970 .iter()
971 .cloned()
972 .flat_map(|pat| [pat.clone(), NamePattern::impl_for(pat)])
973 .map(|pat| (pat, Invisible));
974 opacities
975 .into_iter()
976 .filter_map(|(s, opacity)| parse_pattern(&s).ok().map(|pat| (pat, opacity)))
977 .chain(hide_traits)
978 .collect()
979 };
980
981 let lift_associated_types = options
982 .lift_associated_types
983 .iter()
984 .filter_map(|s| parse_pattern(s).ok())
985 .collect();
986
987 TranslateOptions {
988 start_from,
989 mir_level,
990 monomorphize_mut: options.monomorphize_mut,
991 hide_marker_traits: options.hide_marker_traits,
992 hide_allocator: options.hide_allocator,
993 no_doc_comments: options.no_doc_comments,
994 hide_traits,
995 remove_unused_clauses: options.remove_unused_clauses,
996 remove_unused_self_clauses: options.remove_unused_self_clauses,
997 remove_adt_clauses: options.remove_adt_clauses,
998 monomorphize_with_hax: options.monomorphize,
999 ullbc: options.ullbc,
1000 no_code_duplication: options.no_code_duplication,
1001 ops_to_function_calls: options.ops_to_function_calls,
1002 index_to_function_calls: options.index_to_function_calls,
1003 print_built_llbc: options.print_built_llbc,
1004 item_opacities,
1005 treat_box_as_builtin: options.treat_box_as_builtin,
1006 no_gen_tuple_structs: options.no_gen_tuple_structs,
1007 raw_consts: options.raw_consts,
1008 inline_anon_consts: options.inline_anon_consts,
1009 consts: options.consts.unwrap_or_default(),
1010 unsized_strings: options.unsized_strings,
1011 reconstruct_fallible_operations: options.reconstruct_fallible_operations,
1012 reconstruct_panic_calls: options.reconstruct_panic_calls,
1013 reconstruct_asserts: options.reconstruct_asserts,
1014 reconstruct_matches: options.reconstruct_matches,
1015 deallocate_all_locals: options.deallocate_all_locals,
1016 lift_associated_types,
1017 unbind_item_vars: options.unbind_item_vars,
1018 translate_all_methods: options.translate_all_methods,
1019 eager_vtables: options.eager_vtables,
1020 duplicate_defaulted_methods: options.duplicate_defaulted_methods,
1021 erase_body_lifetimes: options.erase_body_lifetimes,
1022 no_typecheck: options.no_typecheck,
1023 no_normalize: options.no_normalize,
1024 no_reorder_decls: options.no_reorder_decls,
1025 no_compute_layout_guarantees: options.no_compute_layout_guarantees,
1026 desugar_drops: options.desugar_drops,
1027 resugar_drops: options.resugar_drops,
1028 detect_drop_flags: options.detect_drop_flags,
1029 add_destruct_bounds: options.precise_drops,
1030 }
1031 }
1032
1033 #[tracing::instrument(skip(self, krate), ret)]
1036 pub fn opacity_for_name(&self, krate: &TranslatedCrate, name: &Name) -> ItemOpacity {
1037 if name.is_builtin() {
1039 return ItemOpacity::Transparent;
1040 }
1041 let (_, opacity) = self
1045 .item_opacities
1046 .iter()
1047 .filter(|(pat, _)| pat.matches(krate, name))
1048 .max()
1049 .unwrap();
1050 *opacity
1051 }
1052}