1use annotate_snippets::Level;
3use clap::ValueEnum;
4use enum_as_inner::EnumAsInner;
5use indoc::indoc;
6use itertools::Itertools;
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
21pub fn selected_crate_var(crate_name: &str) -> String {
24 format!("CHARON_SELECTED_CRATE_{crate_name}")
25}
26
27#[derive(Debug, Default, Clone, PartialEq, Eq)]
36#[derive(clap::Args)]
37#[derive(Serialize, Deserialize)]
38#[clap(name = "Charon")]
39#[cfg_attr(feature = "charon_on_charon", charon::rename("cli_options"))]
40pub struct CliOpts {
41 #[clap(long)]
43 #[serde(default)]
44 pub ullbc: bool,
45 #[clap(long)]
51 #[serde(default)]
52 pub no_code_duplication: bool,
53 #[clap(long)]
59 #[serde(default)]
60 pub precise_drops: bool,
61 #[arg(long)]
64 pub mir: Option<MirLevel>,
65 #[clap(long = "rustc-arg")]
67 #[serde(default)]
68 pub rustc_args: Vec<String>,
69 #[clap(long, value_delimiter = ',')]
74 #[serde(default)]
75 pub targets: Vec<String>,
76 #[clap(long)]
81 #[serde(default)]
82 pub sysroot: Option<String>,
83
84 #[clap(long, visible_alias = "mono")]
88 #[serde(default)]
89 pub monomorphize: bool,
90 #[clap(
94 long,
95 value_name("INCLUDE_TYPES"),
96 num_args(0..=1),
97 require_equals(true),
98 default_missing_value("all"),
99 )]
100 #[serde(default)]
101 pub monomorphize_mut: Option<MonomorphizeMut>,
102
103 #[clap(long, value_delimiter = ',')]
107 #[serde(default)]
108 pub start_from: Vec<String>,
109 #[clap(long, value_delimiter = ',')]
112 #[serde(default)]
113 pub start_from_if_exists: Vec<String>,
114 #[clap(
118 long,
119 value_name("ATTRIBUTE"),
120 num_args(0..),
121 require_equals(true),
122 value_delimiter = ',',
123 default_missing_value("verify::start_from"),
124 )]
125 #[serde(default)]
126 pub start_from_attribute: Vec<String>,
127 #[clap(long)]
129 #[serde(default)]
130 pub start_from_pub: bool,
131 #[clap(long)]
134 #[serde(default)]
135 pub start_from_global_ctors: bool,
136
137 #[clap(
139 long,
140 help = indoc!("
141 Whitelist of items to translate. These use the name-matcher syntax (note: this differs
142 a bit from the ocaml NameMatcher).
143
144 Note: This is very rough at the moment. E.g. this parses `u64` as a path instead of the
145 built-in type. It is also not possible to filter a trait impl (this will only filter
146 its methods). Please report bugs or missing features.
147
148 Examples:
149 - `crate::module1::module2::item`: refers to this item and all its subitems (e.g.
150 submodules or trait methods);
151 - `crate::module1::module2::item::_`: refers only to the subitems of this item;
152 - `core::convert::{impl core::convert::Into<_> for _}`: retrieve the body of this
153 very useful impl;
154
155 When multiple patterns in the `--include` and `--opaque` options match the same item,
156 the most precise pattern wins. E.g.: `charon --opaque crate::module --include
157 crate::module::_` makes the `module` opaque (we won't explore its contents), but the
158 items in it transparent (we will translate them if we encounter them.)
159 "))]
160 #[serde(default)]
161 #[cfg_attr(feature = "charon_on_charon", charon::rename("included"))]
162 pub include: Vec<String>,
163 #[clap(long)]
165 #[serde(default)]
166 pub opaque: Vec<String>,
167 #[clap(long)]
169 #[serde(default)]
170 pub exclude: Vec<String>,
171 #[clap(long)]
174 #[serde(default)]
175 pub extract_opaque_bodies: bool,
176 #[clap(long)]
179 #[serde(default)]
180 pub translate_all_methods: bool,
181 #[clap(long)]
185 #[serde(default)]
186 pub eager_vtables: bool,
187 #[clap(long)]
191 #[serde(default)]
192 pub duplicate_defaulted_methods: bool,
193
194 #[clap(long, alias = "remove-associated-types")]
197 #[serde(default)]
198 pub lift_associated_types: Vec<String>,
199 #[clap(long)]
202 #[serde(default)]
203 pub hide_marker_traits: bool,
204 #[clap(long)]
206 #[serde(default)]
207 pub hide_allocator: bool,
208 #[clap(long)]
210 #[serde(default)]
211 pub no_doc_comments: bool,
212
213 #[clap(long)]
217 #[serde(default)]
218 pub remove_unused_clauses: bool,
219 #[clap(long)]
224 #[serde(default)]
225 pub remove_unused_self_clauses: bool,
226 #[clap(long)]
229 #[serde(default)]
230 pub remove_adt_clauses: bool,
231
232 #[clap(long)]
234 #[serde(default)]
235 pub desugar_drops: bool,
236 #[clap(long)]
240 #[serde(default)]
241 pub resugar_drops: bool,
242 #[clap(long)]
244 #[serde(default)]
245 pub detect_drop_flags: bool,
246 #[clap(long)]
249 #[serde(default)]
250 pub ops_to_function_calls: bool,
251 #[clap(long)]
255 #[serde(default)]
256 pub index_to_function_calls: bool,
257 #[clap(long)]
259 #[serde(default)]
260 pub treat_box_as_builtin: bool,
261 #[clap(long)]
267 #[serde(default)]
268 pub no_gen_tuple_structs: bool,
269 #[clap(long)]
271 #[serde(default)]
272 pub raw_consts: bool,
273 #[clap(long)]
277 #[serde(default)]
278 pub inline_anon_consts: bool,
279 #[clap(long)]
283 #[serde(default)]
284 pub consts: Option<ConstHandling>,
285 #[clap(long)]
288 #[serde(default)]
289 pub reconstruct_fallible_operations: bool,
290 #[clap(long)]
292 #[serde(default)]
293 pub reconstruct_panic_calls: bool,
294 #[clap(long)]
296 #[serde(default)]
297 pub reconstruct_asserts: bool,
298 #[clap(long)]
301 #[serde(default)]
302 pub reconstruct_matches: bool,
303 #[clap(long)]
307 #[serde(default)]
308 pub deallocate_all_locals: bool,
309 #[clap(long)]
313 #[serde(default)]
314 pub unbind_item_vars: bool,
315
316 #[clap(long)]
318 #[serde(default)]
319 pub print_original_ullbc: bool,
320 #[clap(long)]
322 #[serde(default)]
323 pub print_ullbc: bool,
324 #[clap(long)]
326 #[serde(default)]
327 pub print_built_llbc: bool,
328 #[clap(long)]
330 #[serde(default)]
331 pub print_llbc: bool,
332 #[clap(long)]
334 #[serde(default)]
335 pub print_layouts: bool,
336 #[clap(long)]
338 #[serde(default)]
339 pub print_safety: bool,
340 #[clap(long = "dest", value_parser)]
344 #[serde(default)]
345 pub dest_dir: Option<PathBuf>,
346 #[clap(long, value_parser)]
350 #[serde(default)]
351 pub dest_file: Option<PathBuf>,
352 #[clap(long)]
354 #[serde(default)]
355 pub no_dedup_serialized_ast: bool,
356 #[clap(long, value_enum)]
358 #[serde(default)]
359 pub format: Option<SerializationFormatArg>,
360 #[clap(long)]
362 #[serde(default)]
363 pub run_with_minirust: bool,
364 #[clap(long)]
366 #[serde(default)]
367 pub no_serialize: bool,
368 #[clap(
370 long = "skip-borrow-check",
371 alias = "skip-borrowck",
372 visible_alias = "no-borrow-check",
373 alias = "no-borrowck"
374 )]
375 #[serde(default)]
376 pub skip_borrowck: bool,
377 #[clap(long)]
379 #[serde(default)]
380 pub erase_body_lifetimes: bool,
381 #[clap(long)]
383 #[serde(default)]
384 pub no_typecheck: bool,
385 #[clap(long)]
387 #[serde(default)]
388 pub no_normalize: bool,
389 #[clap(long)]
391 #[serde(default)]
392 pub no_reorder_decls: bool,
393 #[clap(long)]
395 #[serde(default)]
396 pub no_compute_layout_guarantees: bool,
397 #[clap(long)]
399 #[serde(default)]
400 pub abort_on_error: bool,
401 #[clap(long)]
403 #[serde(default)]
404 pub error_on_warnings: bool,
405
406 #[clap(long)]
408 #[arg(value_enum)]
409 pub preset: Option<Preset>,
410}
411
412#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
415#[derive(ValueEnum)]
416#[derive(Serialize, Deserialize)]
417pub enum MirLevel {
418 Built,
420 Promoted,
422 Elaborated,
425 Optimized,
428}
429
430#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
433#[derive(ValueEnum)]
434#[derive(Serialize, Deserialize)]
435#[non_exhaustive]
436pub enum Preset {
437 OldDefaults,
440 RawMir,
443 Fast,
445 Aeneas,
446 Eurydice,
447 Soteria,
448 Tests,
449}
450
451#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
453#[derive(ValueEnum)]
454#[derive(Serialize, Deserialize)]
455pub enum ConstHandling {
456 #[default]
459 Initializers,
460 Values,
463 Bytes,
466}
467
468#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
469#[derive(ValueEnum)]
470#[derive(Serialize, Deserialize)]
471pub enum MonomorphizeMut {
472 #[default]
474 All,
475 ExceptTypes,
477}
478
479#[derive(Debug, Copy, Clone, PartialEq, Eq)]
480#[derive(ValueEnum)]
481#[derive(Serialize, Deserialize)]
482pub enum SerializationFormatArg {
483 Json,
484 Postcard,
485 #[value(name = "minirust")]
486 MiniRust,
487 #[cfg_attr(feature = "charon_on_charon", charon::rename("AllFormats"))]
488 All,
489}
490
491#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
492#[derive(ValueEnum)]
493#[derive(Serialize, Deserialize)]
494pub enum SerializationFormat {
495 #[default]
496 Json,
497 Postcard,
498 #[value(name = "minirust")]
499 MiniRust,
500}
501
502impl SerializationFormatArg {
503 pub fn as_format(self) -> Option<SerializationFormat> {
504 match self {
505 SerializationFormatArg::Json => Some(SerializationFormat::Json),
506 SerializationFormatArg::Postcard => Some(SerializationFormat::Postcard),
507 SerializationFormatArg::MiniRust => Some(SerializationFormat::MiniRust),
508 SerializationFormatArg::All => None,
509 }
510 }
511}
512
513impl From<SerializationFormat> for SerializationFormatArg {
514 fn from(format: SerializationFormat) -> SerializationFormatArg {
515 match format {
516 SerializationFormat::Json => SerializationFormatArg::Json,
517 SerializationFormat::Postcard => SerializationFormatArg::Postcard,
518 SerializationFormat::MiniRust => SerializationFormatArg::MiniRust,
519 }
520 }
521}
522
523impl SerializationFormat {
524 pub fn output_extension(self, ullbc: bool) -> &'static str {
525 match (ullbc, self) {
526 (true, SerializationFormat::Json) => "ullbc",
527 (false, SerializationFormat::Json) => "llbc",
528 (true, SerializationFormat::Postcard) => "ullbc.postcard",
529 (false, SerializationFormat::Postcard) => "llbc.postcard",
530 (_, SerializationFormat::MiniRust) => "minirust.json",
531 }
532 }
533}
534
535impl CliOpts {
536 pub fn apply_preset(&mut self) {
537 if let Some(preset) = self.preset {
538 match preset {
539 Preset::OldDefaults => {
540 self.inline_anon_consts = true;
541 self.treat_box_as_builtin = true;
542 self.hide_allocator = true;
543 self.ops_to_function_calls = true;
544 self.index_to_function_calls = true;
545 self.reconstruct_fallible_operations = true;
546 self.reconstruct_asserts = true;
547 self.reconstruct_panic_calls = true;
548 self.reconstruct_matches = true;
549 self.unbind_item_vars = true;
550 self.duplicate_defaulted_methods = true;
551 }
552 Preset::RawMir => {
553 self.extract_opaque_bodies = true;
554 self.raw_consts = true;
555 self.ullbc = true;
556 }
557 Preset::Fast => {
558 self.ullbc = true;
559 self.no_typecheck = true;
560 self.no_normalize = true;
561 self.no_reorder_decls = true;
562 self.no_compute_layout_guarantees = true;
563 self.hide_marker_traits = true;
564 self.raw_consts = true;
565 }
566 Preset::Aeneas => {
567 self.lift_associated_types.push("*".to_owned());
568 self.treat_box_as_builtin = true;
569 self.ops_to_function_calls = true;
570 self.index_to_function_calls = true;
571 self.reconstruct_fallible_operations = true;
572 self.reconstruct_panic_calls = true;
573 self.reconstruct_asserts = true;
574 self.reconstruct_matches = true;
575 self.hide_marker_traits = true;
576 self.hide_allocator = true;
577 self.remove_unused_self_clauses = true;
578 self.remove_adt_clauses = true;
579 self.unbind_item_vars = true;
580 self.deallocate_all_locals = true;
581 self.no_gen_tuple_structs = true;
582 }
583 Preset::Eurydice => {
584 self.inline_anon_consts = true;
585 self.hide_allocator = true;
586 self.treat_box_as_builtin = true;
587 self.reconstruct_fallible_operations = true;
588 self.reconstruct_panic_calls = true;
589 self.reconstruct_asserts = true;
590 self.reconstruct_matches = true;
591 self.lift_associated_types.push("*".to_owned());
592 self.unbind_item_vars = true;
593 self.duplicate_defaulted_methods = true;
594 self.include.push("core::marker::MetaSized".to_owned());
596 }
597 Preset::Soteria => {
598 self.desugar_drops = true;
599 self.extract_opaque_bodies = true;
600 self.mir = Some(MirLevel::Elaborated);
601 self.reconstruct_fallible_operations = true;
602 self.reconstruct_asserts = true;
603 self.monomorphize = true;
604 self.no_normalize = true;
605 self.no_typecheck = true;
606 self.no_reorder_decls = true;
607 self.no_compute_layout_guarantees = true;
608 self.erase_body_lifetimes = true;
609 self.no_doc_comments = true;
610 self.precise_drops = true;
611 self.consts = Some(ConstHandling::Values);
612 self.ullbc = true;
613 }
614 Preset::Tests => {
615 self.inline_anon_consts = true;
616 self.no_dedup_serialized_ast = true; self.treat_box_as_builtin = true;
618 self.hide_allocator = true;
619 self.reconstruct_fallible_operations = true;
620 self.reconstruct_panic_calls = true;
621 self.reconstruct_asserts = true;
622 self.reconstruct_matches = true;
623 if !self.desugar_drops {
624 self.resugar_drops = true;
625 }
626 if !self.monomorphize {
627 self.ops_to_function_calls = true;
628 self.index_to_function_calls = true;
629 }
630 self.duplicate_defaulted_methods = true;
631 self.deallocate_all_locals = true;
632 self.rustc_args.push("--edition=2021".to_owned());
633 self.rustc_args
634 .push("-Zcrate-attr=feature(register_tool)".to_owned());
635 self.rustc_args
636 .push("-Zcrate-attr=register_tool(charon)".to_owned());
637 self.exclude.push("core::fmt".to_owned());
638 if self.extract_opaque_bodies {
639 self.exclude
640 .extend(["core::array".to_owned(), "core::slice::index".to_owned()]);
641 }
642 }
643 }
644 }
645
646 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
647 self.monomorphize = true;
648 self.ullbc = true;
649 self.precise_drops = true;
650 self.desugar_drops = true;
651 self.deallocate_all_locals = true;
652 self.treat_box_as_builtin = true;
653 self.extract_opaque_bodies = true;
654 self.consts = Some(ConstHandling::Bytes);
655 self.mir = Some(
656 self.mir
657 .unwrap_or(MirLevel::Elaborated)
658 .max(MirLevel::Elaborated),
659 );
660 }
661 }
662
663 pub fn validate(&self) -> anyhow::Result<()> {
665 if self.dest_dir.is_some() {
666 display_unspanned_error(
667 Level::WARNING,
668 "`--dest` is deprecated, use `--dest-file` instead",
669 )
670 }
671
672 if self.remove_adt_clauses && self.lift_associated_types.is_empty() {
673 anyhow::bail!(
674 "`--remove-adt-clauses` should be used with `--lift-associated-types='*'` \
675 to avoid missing clause errors",
676 )
677 }
678 if matches!(self.monomorphize_mut, Some(MonomorphizeMut::ExceptTypes))
679 && !self.remove_adt_clauses
680 {
681 anyhow::bail!(
682 "`--monomorphize-mut=except-types` should be used with `--remove-adt-clauses` \
683 to avoid generics mismatches"
684 )
685 }
686 if self.no_gen_tuple_structs && self.monomorphize {
687 anyhow::bail!(
688 "`--no-gen-tuple-structs` is not compatible with `--monomorphize`, as \
689 monomorphization requires each tuple to have its own type declaration"
690 )
691 }
692 if self.monomorphize && (self.ops_to_function_calls || self.index_to_function_calls) {
693 anyhow::bail!(
694 "`--monomorphize` is not compatible with `--ops-to-function-calls` or \
695 `--index-to-function-calls`"
696 )
697 }
698 if self.no_serialize && self.format.is_some() {
699 anyhow::bail!(
700 "`--no-serialize` is not compatible with `--format`, the format is only relevant if we serialize"
701 );
702 }
703 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
704 if !cfg!(feature = "minirust") {
705 anyhow::bail!(
706 "MiniRust output is unavailable because Charon was built without the `minirust` feature"
707 );
708 }
709 if !self.targets.is_empty() {
710 anyhow::bail!("MiniRust output does not support multi-target translation");
711 }
712 }
713 if self.resugar_drops && self.desugar_drops {
714 anyhow::bail!("`--desugar-drops` and `--resugar-drops` are mutually incompatible")
715 }
716 Ok(())
717 }
718
719 fn target_filename(
720 &self,
721 path_base: PathBuf,
722 format: SerializationFormat,
723 ) -> (PathBuf, SerializationFormat) {
724 let extension = format.output_extension(self.ullbc);
725 let target_filename = path_base.with_added_extension(extension);
726 (target_filename, format)
727 }
728
729 pub fn targets(&self, crate_name: &str) -> Vec<(PathBuf, SerializationFormat)> {
730 if self.no_serialize {
731 return vec![];
732 }
733
734 let format = self.format.unwrap_or(SerializationFormatArg::Json);
735 let mut path_base = self.dest_dir.clone().unwrap_or_default();
736 path_base.push(crate_name);
737
738 match format.as_format() {
739 Some(format) => match self.dest_file.clone() {
740 Some(dest) => vec![(dest, format)],
741 None => vec![self.target_filename(path_base, format)],
742 },
743 None => {
744 let path_base = self.dest_file.clone().unwrap_or(path_base);
745 vec![
746 self.target_filename(path_base.clone(), SerializationFormat::Json),
747 self.target_filename(path_base, SerializationFormat::Postcard),
748 ]
749 }
750 }
751 }
752}
753
754#[derive(Debug, Clone, EnumAsInner)]
756pub enum StartFrom {
757 Pattern { pattern: NamePattern, strict: bool },
760 Attribute(String),
762 Pub,
765 GlobalCtors,
767}
768
769pub struct TranslateOptions {
771 pub start_from: Vec<StartFrom>,
773 pub mir_level: MirLevel,
775 pub translate_all_methods: bool,
778 pub eager_vtables: bool,
780 pub duplicate_defaulted_methods: bool,
782 pub monomorphize_mut: Option<MonomorphizeMut>,
785 pub hide_marker_traits: bool,
788 pub hide_allocator: bool,
790 pub no_doc_comments: bool,
792 pub hide_traits: Vec<NamePattern>,
795 pub remove_unused_clauses: bool,
799 pub remove_unused_self_clauses: bool,
801 pub remove_adt_clauses: bool,
803 pub monomorphize_with_hax: bool,
805 pub ullbc: bool,
807 pub no_code_duplication: bool,
810 pub ops_to_function_calls: bool,
813 pub index_to_function_calls: bool,
815 pub print_built_llbc: bool,
817 pub treat_box_as_builtin: bool,
819 pub no_gen_tuple_structs: bool,
822 pub raw_consts: bool,
824 pub inline_anon_consts: bool,
826 pub consts: ConstHandling,
828 pub reconstruct_fallible_operations: bool,
831 pub reconstruct_panic_calls: bool,
833 pub reconstruct_asserts: bool,
835 pub reconstruct_matches: bool,
837 pub deallocate_all_locals: bool,
839 pub unbind_item_vars: bool,
841 pub item_opacities: Vec<(NamePattern, ItemOpacity)>,
844 pub lift_associated_types: Vec<NamePattern>,
846 pub erase_body_lifetimes: bool,
848 pub no_typecheck: bool,
850 pub no_normalize: bool,
852 pub no_reorder_decls: bool,
854 pub no_compute_layout_guarantees: bool,
856 pub desugar_drops: bool,
858 pub resugar_drops: bool,
860 pub detect_drop_flags: bool,
862 pub add_destruct_bounds: bool,
864}
865
866impl TranslateOptions {
867 pub fn new(error_ctx: &mut ErrorCtx, options: &CliOpts) -> Self {
868 let mut parse_pattern = |s: &str| -> Result<_, Error> {
869 match NamePattern::parse(s) {
870 Ok(p) => Ok(p),
871 Err(e) => raise_error!(error_ctx, no_crate, "failed to parse pattern `{s}` ({e})"),
872 }
873 };
874
875 let mut mir_level = options.mir.unwrap_or(MirLevel::Promoted);
876 if options.precise_drops {
877 mir_level = std::cmp::max(mir_level, MirLevel::Elaborated);
878 }
879
880 let mut start_from = options
881 .start_from
882 .iter()
883 .filter_map(|path| parse_pattern(path).ok())
884 .map(|p| StartFrom::Pattern {
885 pattern: p,
886 strict: true,
887 })
888 .collect_vec();
889 start_from.extend(
890 options
891 .start_from_if_exists
892 .iter()
893 .filter_map(|path| parse_pattern(path).ok())
894 .map(|p| StartFrom::Pattern {
895 pattern: p,
896 strict: false,
897 }),
898 );
899 for attr in options.start_from_attribute.iter().cloned() {
900 start_from.push(StartFrom::Attribute(attr));
901 }
902 if options.start_from_pub {
903 start_from.push(StartFrom::Pub);
904 }
905 if options.start_from_global_ctors {
906 start_from.push(StartFrom::GlobalCtors);
907 }
908 if start_from.is_empty() {
909 start_from.push(StartFrom::Pattern {
910 pattern: parse_pattern("crate").unwrap(),
911 strict: true,
912 });
913 }
914
915 let hide_traits = options
916 .hide_marker_traits
917 .then_some([
918 "core::marker::Sized",
919 "core::marker::MetaSized",
920 "core::marker::PointeeSized",
921 "core::marker::Tuple",
922 "core::clone::TrivialClone",
923 ])
924 .into_iter()
925 .flatten()
926 .chain(options.hide_allocator.then_some("core::alloc::Allocator"))
927 .filter_map(|s| parse_pattern(s).ok())
928 .collect_vec();
929
930 let item_opacities = {
931 use ItemOpacity::*;
932 let mut opacities = vec![];
933
934 if options.extract_opaque_bodies {
936 opacities.push(("_".to_string(), Transparent));
937 } else {
938 opacities.push(("_".to_string(), Foreign));
939 }
940
941 if options.treat_box_as_builtin {
942 opacities.push((
944 "alloc::boxed::box_assume_init_into_vec_unsafe".to_string(),
945 Transparent,
946 ));
947 }
948
949 opacities.push(("crate".to_owned(), Transparent));
951
952 for pat in options.include.iter() {
953 opacities.push((pat.to_string(), Transparent));
954 }
955 for pat in options.opaque.iter() {
956 opacities.push((pat.to_string(), Opaque));
957 }
958 if options.run_with_minirust
959 || matches!(options.format, Some(SerializationFormatArg::MiniRust))
960 {
961 opacities.push(("intrinsics".to_owned(), Opaque));
965 opacities.push(("core::panicking::panic_fmt".to_owned(), Opaque));
967 }
968 for pat in options.exclude.iter() {
969 opacities.push((pat.to_string(), Invisible));
970 }
971
972 for trait_name in &hide_traits {
973 opacities.push((trait_name.to_string(), Invisible));
974 }
975
976 let hide_traits = hide_traits
978 .iter()
979 .cloned()
980 .flat_map(|pat| [pat.clone(), NamePattern::impl_for(pat)])
981 .map(|pat| (pat, Invisible));
982 opacities
983 .into_iter()
984 .filter_map(|(s, opacity)| parse_pattern(&s).ok().map(|pat| (pat, opacity)))
985 .chain(hide_traits)
986 .collect()
987 };
988
989 let lift_associated_types = options
990 .lift_associated_types
991 .iter()
992 .filter_map(|s| parse_pattern(s).ok())
993 .collect();
994
995 TranslateOptions {
996 start_from,
997 mir_level,
998 monomorphize_mut: options.monomorphize_mut,
999 hide_marker_traits: options.hide_marker_traits,
1000 hide_allocator: options.hide_allocator,
1001 no_doc_comments: options.no_doc_comments,
1002 hide_traits,
1003 remove_unused_clauses: options.remove_unused_clauses,
1004 remove_unused_self_clauses: options.remove_unused_self_clauses,
1005 remove_adt_clauses: options.remove_adt_clauses,
1006 monomorphize_with_hax: options.monomorphize,
1007 ullbc: options.ullbc,
1008 no_code_duplication: options.no_code_duplication,
1009 ops_to_function_calls: options.ops_to_function_calls,
1010 index_to_function_calls: options.index_to_function_calls,
1011 print_built_llbc: options.print_built_llbc,
1012 item_opacities,
1013 treat_box_as_builtin: options.treat_box_as_builtin,
1014 no_gen_tuple_structs: options.no_gen_tuple_structs,
1015 raw_consts: options.raw_consts,
1016 inline_anon_consts: options.inline_anon_consts,
1017 consts: options.consts.unwrap_or_default(),
1018 reconstruct_fallible_operations: options.reconstruct_fallible_operations,
1019 reconstruct_panic_calls: options.reconstruct_panic_calls,
1020 reconstruct_asserts: options.reconstruct_asserts,
1021 reconstruct_matches: options.reconstruct_matches,
1022 deallocate_all_locals: options.deallocate_all_locals,
1023 lift_associated_types,
1024 unbind_item_vars: options.unbind_item_vars,
1025 translate_all_methods: options.translate_all_methods,
1026 eager_vtables: options.eager_vtables,
1027 duplicate_defaulted_methods: options.duplicate_defaulted_methods,
1028 erase_body_lifetimes: options.erase_body_lifetimes,
1029 no_typecheck: options.no_typecheck,
1030 no_normalize: options.no_normalize,
1031 no_reorder_decls: options.no_reorder_decls,
1032 no_compute_layout_guarantees: options.no_compute_layout_guarantees,
1033 desugar_drops: options.desugar_drops,
1034 resugar_drops: options.resugar_drops,
1035 detect_drop_flags: options.detect_drop_flags,
1036 add_destruct_bounds: options.precise_drops,
1037 }
1038 }
1039
1040 #[tracing::instrument(skip(self, krate), ret)]
1043 pub fn opacity_for_name(&self, krate: &TranslatedCrate, name: &Name) -> ItemOpacity {
1044 if name.is_builtin() {
1046 return ItemOpacity::Transparent;
1047 }
1048 let (_, opacity) = self
1052 .item_opacities
1053 .iter()
1054 .filter(|(pat, _)| pat.matches(krate, name))
1055 .max()
1056 .unwrap();
1057 *opacity
1058 }
1059}