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 precise_drops: bool,
47 #[arg(long)]
50 pub mir: Option<MirLevel>,
51 #[clap(long = "rustc-arg")]
53 #[serde(default)]
54 pub rustc_args: Vec<String>,
55 #[clap(long, value_delimiter = ',')]
60 #[serde(default)]
61 pub targets: Vec<String>,
62 #[clap(long)]
67 #[serde(default)]
68 pub sysroot: Option<String>,
69
70 #[clap(long, visible_alias = "mono")]
74 #[serde(default)]
75 pub monomorphize: bool,
76 #[clap(
80 long,
81 value_name("INCLUDE_TYPES"),
82 num_args(0..=1),
83 require_equals(true),
84 default_missing_value("all"),
85 )]
86 #[serde(default)]
87 pub monomorphize_mut: Option<MonomorphizeMut>,
88
89 #[clap(long, value_delimiter = ',')]
93 #[serde(default)]
94 pub start_from: Vec<String>,
95 #[clap(long, value_delimiter = ',')]
98 #[serde(default)]
99 pub start_from_if_exists: Vec<String>,
100 #[clap(
104 long,
105 value_name("ATTRIBUTE"),
106 num_args(0..),
107 require_equals(true),
108 value_delimiter = ',',
109 default_missing_value("verify::start_from"),
110 )]
111 #[serde(default)]
112 pub start_from_attribute: Vec<String>,
113 #[clap(long)]
115 #[serde(default)]
116 pub start_from_pub: bool,
117
118 #[clap(
120 long,
121 help = indoc!("
122 Whitelist of items to translate. These use the name-matcher syntax (note: this differs
123 a bit from the ocaml NameMatcher).
124
125 Note: This is very rough at the moment. E.g. this parses `u64` as a path instead of the
126 built-in type. It is also not possible to filter a trait impl (this will only filter
127 its methods). Please report bugs or missing features.
128
129 Examples:
130 - `crate::module1::module2::item`: refers to this item and all its subitems (e.g.
131 submodules or trait methods);
132 - `crate::module1::module2::item::_`: refers only to the subitems of this item;
133 - `core::convert::{impl core::convert::Into<_> for _}`: retrieve the body of this
134 very useful impl;
135
136 When multiple patterns in the `--include` and `--opaque` options match the same item,
137 the most precise pattern wins. E.g.: `charon --opaque crate::module --include
138 crate::module::_` makes the `module` opaque (we won't explore its contents), but the
139 items in it transparent (we will translate them if we encounter them.)
140 "))]
141 #[serde(default)]
142 #[cfg_attr(feature = "charon_on_charon", charon::rename("included"))]
143 pub include: Vec<String>,
144 #[clap(long)]
146 #[serde(default)]
147 pub opaque: Vec<String>,
148 #[clap(long)]
150 #[serde(default)]
151 pub exclude: Vec<String>,
152 #[clap(long)]
155 #[serde(default)]
156 pub extract_opaque_bodies: bool,
157 #[clap(long)]
160 #[serde(default)]
161 pub translate_all_methods: bool,
162 #[clap(long)]
166 #[serde(default)]
167 pub eager_vtables: bool,
168 #[clap(long)]
172 #[serde(default)]
173 pub duplicate_defaulted_methods: bool,
174
175 #[clap(long, alias = "remove-associated-types")]
178 #[serde(default)]
179 pub lift_associated_types: Vec<String>,
180 #[clap(long)]
183 #[serde(default)]
184 pub hide_marker_traits: bool,
185 #[clap(long)]
187 #[serde(default)]
188 pub hide_allocator: bool,
189 #[clap(long)]
191 #[serde(default)]
192 pub no_doc_comments: bool,
193
194 #[clap(long)]
198 #[serde(default)]
199 pub remove_unused_clauses: bool,
200 #[clap(long)]
205 #[serde(default)]
206 pub remove_unused_self_clauses: bool,
207 #[clap(long)]
210 #[serde(default)]
211 pub remove_adt_clauses: bool,
212
213 #[clap(long)]
215 #[serde(default)]
216 pub desugar_drops: bool,
217 #[clap(long)]
221 #[serde(default)]
222 pub resugar_drops: bool,
223 #[clap(long)]
225 #[serde(default)]
226 pub detect_drop_flags: bool,
227 #[clap(long)]
230 #[serde(default)]
231 pub ops_to_function_calls: bool,
232 #[clap(long)]
236 #[serde(default)]
237 pub index_to_function_calls: bool,
238 #[clap(long)]
240 #[serde(default)]
241 pub treat_box_as_builtin: bool,
242 #[clap(long)]
248 #[serde(default)]
249 pub no_gen_tuple_structs: bool,
250 #[clap(long)]
252 #[serde(default)]
253 pub raw_consts: bool,
254 #[clap(long)]
258 #[serde(default)]
259 pub inline_anon_consts: bool,
260 #[clap(long)]
264 #[serde(default)]
265 pub consts: Option<ConstHandling>,
266 #[clap(long)]
269 #[serde(default)]
270 pub unsized_strings: bool,
271 #[clap(long)]
274 #[serde(default)]
275 pub reconstruct_fallible_operations: bool,
276 #[clap(long)]
278 #[serde(default)]
279 pub reconstruct_panic_calls: bool,
280 #[clap(long)]
282 #[serde(default)]
283 pub reconstruct_asserts: bool,
284 #[clap(long)]
287 #[serde(default)]
288 pub reconstruct_matches: bool,
289 #[clap(long)]
293 #[serde(default)]
294 pub deallocate_all_locals: bool,
295 #[clap(long)]
299 #[serde(default)]
300 pub unbind_item_vars: bool,
301
302 #[clap(long)]
304 #[serde(default)]
305 pub print_original_ullbc: bool,
306 #[clap(long)]
308 #[serde(default)]
309 pub print_ullbc: bool,
310 #[clap(long)]
312 #[serde(default)]
313 pub print_built_llbc: bool,
314 #[clap(long)]
316 #[serde(default)]
317 pub print_llbc: bool,
318 #[clap(long)]
320 #[serde(default)]
321 pub print_layouts: bool,
322 #[clap(long)]
324 #[serde(default)]
325 pub print_safety: bool,
326 #[clap(long = "dest", value_parser)]
330 #[serde(default)]
331 pub dest_dir: Option<PathBuf>,
332 #[clap(long, value_parser)]
336 #[serde(default)]
337 pub dest_file: Option<PathBuf>,
338 #[clap(long)]
340 #[serde(default)]
341 pub no_dedup_serialized_ast: bool,
342 #[clap(long, value_enum)]
344 #[serde(default)]
345 pub format: Option<SerializationFormatArg>,
346 #[clap(long)]
348 #[serde(default)]
349 pub run_with_minirust: bool,
350 #[clap(long)]
352 #[serde(default)]
353 pub no_serialize: bool,
354 #[clap(
356 long = "skip-borrow-check",
357 alias = "skip-borrowck",
358 visible_alias = "no-borrow-check",
359 alias = "no-borrowck"
360 )]
361 #[serde(default)]
362 pub skip_borrowck: bool,
363 #[clap(long)]
365 #[serde(default)]
366 pub erase_body_lifetimes: bool,
367 #[clap(long)]
369 #[serde(default)]
370 pub no_typecheck: bool,
371 #[clap(long)]
373 #[serde(default)]
374 pub no_normalize: bool,
375 #[clap(long)]
377 #[serde(default)]
378 pub no_reorder_decls: bool,
379 #[clap(long)]
381 #[serde(default)]
382 pub no_compute_layout_guarantees: bool,
383 #[clap(long)]
385 #[serde(default)]
386 pub abort_on_error: bool,
387 #[clap(long)]
389 #[serde(default)]
390 pub error_on_warnings: bool,
391
392 #[clap(long)]
394 #[arg(value_enum)]
395 pub preset: Option<Preset>,
396}
397
398#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
401#[derive(ValueEnum)]
402#[derive(Serialize, Deserialize)]
403pub enum MirLevel {
404 Built,
406 Promoted,
408 Elaborated,
411 Optimized,
414}
415
416#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
419#[derive(ValueEnum)]
420#[derive(Serialize, Deserialize)]
421#[non_exhaustive]
422pub enum Preset {
423 OldDefaults,
426 RawMir,
429 Fast,
431 Aeneas,
432 Eurydice,
433 Soteria,
434 Tests,
435}
436
437#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
439#[derive(ValueEnum)]
440#[derive(Serialize, Deserialize)]
441pub enum ConstHandling {
442 #[default]
445 Initializers,
446 Values,
449 Bytes,
452}
453
454#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
455#[derive(ValueEnum)]
456#[derive(Serialize, Deserialize)]
457pub enum MonomorphizeMut {
458 #[default]
460 All,
461 ExceptTypes,
463}
464
465#[derive(Debug, Copy, Clone, PartialEq, Eq)]
466#[derive(ValueEnum)]
467#[derive(Serialize, Deserialize)]
468pub enum SerializationFormatArg {
469 Json,
470 Postcard,
471 #[value(name = "minirust")]
472 MiniRust,
473 #[cfg_attr(feature = "charon_on_charon", charon::rename("AllFormats"))]
474 All,
475}
476
477#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
478#[derive(ValueEnum)]
479#[derive(Serialize, Deserialize)]
480pub enum SerializationFormat {
481 #[default]
482 Json,
483 Postcard,
484 #[value(name = "minirust")]
485 MiniRust,
486}
487
488impl SerializationFormatArg {
489 pub fn as_format(self) -> Option<SerializationFormat> {
490 match self {
491 SerializationFormatArg::Json => Some(SerializationFormat::Json),
492 SerializationFormatArg::Postcard => Some(SerializationFormat::Postcard),
493 SerializationFormatArg::MiniRust => Some(SerializationFormat::MiniRust),
494 SerializationFormatArg::All => None,
495 }
496 }
497}
498
499impl From<SerializationFormat> for SerializationFormatArg {
500 fn from(format: SerializationFormat) -> SerializationFormatArg {
501 match format {
502 SerializationFormat::Json => SerializationFormatArg::Json,
503 SerializationFormat::Postcard => SerializationFormatArg::Postcard,
504 SerializationFormat::MiniRust => SerializationFormatArg::MiniRust,
505 }
506 }
507}
508
509impl SerializationFormat {
510 pub fn output_extension(self, ullbc: bool) -> &'static str {
511 match (ullbc, self) {
512 (true, SerializationFormat::Json) => "ullbc",
513 (false, SerializationFormat::Json) => "llbc",
514 (true, SerializationFormat::Postcard) => "ullbc.postcard",
515 (false, SerializationFormat::Postcard) => "llbc.postcard",
516 (_, SerializationFormat::MiniRust) => "minirust.json",
517 }
518 }
519}
520
521impl CliOpts {
522 pub fn apply_preset(&mut self) {
523 if let Some(preset) = self.preset {
524 match preset {
525 Preset::OldDefaults => {
526 self.inline_anon_consts = true;
527 self.treat_box_as_builtin = true;
528 self.hide_allocator = true;
529 self.ops_to_function_calls = true;
530 self.index_to_function_calls = true;
531 self.reconstruct_fallible_operations = true;
532 self.reconstruct_asserts = true;
533 self.reconstruct_panic_calls = true;
534 self.reconstruct_matches = true;
535 self.unbind_item_vars = true;
536 self.duplicate_defaulted_methods = true;
537 }
538 Preset::RawMir => {
539 self.extract_opaque_bodies = true;
540 self.raw_consts = true;
541 self.ullbc = true;
542 }
543 Preset::Fast => {
544 self.ullbc = true;
545 self.no_typecheck = true;
546 self.no_normalize = true;
547 self.no_reorder_decls = true;
548 self.no_compute_layout_guarantees = true;
549 self.hide_marker_traits = true;
550 self.raw_consts = true;
551 }
552 Preset::Aeneas => {
553 self.inline_anon_consts = true;
554 self.lift_associated_types.push("*".to_owned());
555 self.treat_box_as_builtin = true;
556 self.ops_to_function_calls = true;
557 self.index_to_function_calls = true;
558 self.reconstruct_fallible_operations = true;
559 self.reconstruct_panic_calls = true;
560 self.reconstruct_asserts = true;
561 self.reconstruct_matches = true;
562 self.hide_marker_traits = true;
563 self.hide_allocator = true;
564 self.remove_unused_self_clauses = true;
565 self.remove_adt_clauses = true;
566 self.unbind_item_vars = true;
567 self.deallocate_all_locals = true;
568 self.no_gen_tuple_structs = true;
569 }
570 Preset::Eurydice => {
571 self.inline_anon_consts = true;
572 self.hide_allocator = true;
573 self.treat_box_as_builtin = true;
574 self.reconstruct_fallible_operations = true;
575 self.reconstruct_panic_calls = true;
576 self.reconstruct_asserts = true;
577 self.reconstruct_matches = true;
578 self.lift_associated_types.push("*".to_owned());
579 self.unbind_item_vars = true;
580 self.duplicate_defaulted_methods = true;
581 self.include.push("core::marker::MetaSized".to_owned());
583 }
584 Preset::Soteria => {
585 self.desugar_drops = true;
586 self.extract_opaque_bodies = true;
587 self.mir = Some(MirLevel::Elaborated);
588 self.reconstruct_fallible_operations = true;
589 self.reconstruct_asserts = true;
590 self.monomorphize = true;
591 self.no_normalize = true;
592 self.no_typecheck = true;
593 self.no_reorder_decls = true;
594 self.no_compute_layout_guarantees = true;
595 self.erase_body_lifetimes = true;
596 self.no_doc_comments = true;
597 self.precise_drops = true;
598 self.consts = Some(ConstHandling::Values);
599 self.ullbc = true;
600 }
601 Preset::Tests => {
602 self.inline_anon_consts = true;
603 self.no_dedup_serialized_ast = true; self.treat_box_as_builtin = true;
605 self.hide_allocator = true;
606 self.reconstruct_fallible_operations = true;
607 self.reconstruct_panic_calls = true;
608 self.reconstruct_asserts = true;
609 self.reconstruct_matches = true;
610 self.resugar_drops = true;
611 if !self.monomorphize {
612 self.ops_to_function_calls = true;
613 self.index_to_function_calls = true;
614 }
615 self.duplicate_defaulted_methods = true;
616 self.deallocate_all_locals = true;
617 self.rustc_args.push("--edition=2021".to_owned());
618 self.rustc_args
619 .push("-Zcrate-attr=feature(register_tool)".to_owned());
620 self.rustc_args
621 .push("-Zcrate-attr=register_tool(charon)".to_owned());
622 self.exclude.push("core::fmt".to_owned());
623 if self.extract_opaque_bodies {
624 self.exclude
625 .extend(["core::array".to_owned(), "core::slice::index".to_owned()]);
626 }
627 }
628 }
629 }
630
631 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
632 self.monomorphize = true;
633 self.ullbc = true;
634 self.precise_drops = true;
635 self.desugar_drops = true;
636 self.deallocate_all_locals = true;
637 self.treat_box_as_builtin = true;
638 self.extract_opaque_bodies = true;
639 self.consts = Some(ConstHandling::Bytes);
640 self.mir = Some(
641 self.mir
642 .unwrap_or(MirLevel::Elaborated)
643 .max(MirLevel::Elaborated),
644 );
645 }
646 }
647
648 pub fn validate(&self) -> anyhow::Result<()> {
650 if self.dest_dir.is_some() {
651 display_unspanned_error(
652 Level::WARNING,
653 "`--dest` is deprecated, use `--dest-file` instead",
654 )
655 }
656
657 if self.remove_adt_clauses && self.lift_associated_types.is_empty() {
658 anyhow::bail!(
659 "`--remove-adt-clauses` should be used with `--lift-associated-types='*'` \
660 to avoid missing clause errors",
661 )
662 }
663 if matches!(self.monomorphize_mut, Some(MonomorphizeMut::ExceptTypes))
664 && !self.remove_adt_clauses
665 {
666 anyhow::bail!(
667 "`--monomorphize-mut=except-types` should be used with `--remove-adt-clauses` \
668 to avoid generics mismatches"
669 )
670 }
671 if self.no_gen_tuple_structs && self.monomorphize {
672 anyhow::bail!(
673 "`--no-gen-tuple-structs` is not compatible with `--monomorphize`, as \
674 monomorphization requires each tuple to have its own type declaration"
675 )
676 }
677 if self.monomorphize && (self.ops_to_function_calls || self.index_to_function_calls) {
678 anyhow::bail!(
679 "`--monomorphize` is not compatible with `--ops-to-function-calls` or \
680 `--index-to-function-calls`"
681 )
682 }
683 if self.no_serialize && self.format.is_some() {
684 anyhow::bail!(
685 "`--no-serialize` is not compatible with `--format`, the format is only relevant if we serialize"
686 );
687 }
688 if self.run_with_minirust || matches!(self.format, Some(SerializationFormatArg::MiniRust)) {
689 if !cfg!(feature = "minirust") {
690 anyhow::bail!(
691 "MiniRust output is unavailable because Charon was built without the `minirust` feature"
692 );
693 }
694 if !self.targets.is_empty() {
695 anyhow::bail!("MiniRust output does not support multi-target translation");
696 }
697 }
698 if self.resugar_drops && self.desugar_drops {
699 anyhow::bail!("`--desugar-drops` and `--resugar-drops` are mutually incompatible")
700 }
701 Ok(())
702 }
703
704 fn target_filename(
705 &self,
706 path_base: PathBuf,
707 format: SerializationFormat,
708 ) -> (PathBuf, SerializationFormat) {
709 let extension = format.output_extension(self.ullbc);
710 let target_filename = path_base.with_added_extension(extension);
711 (target_filename, format)
712 }
713
714 pub fn targets(&self, crate_name: &str) -> Vec<(PathBuf, SerializationFormat)> {
715 if self.no_serialize {
716 return vec![];
717 }
718
719 let format = self.format.unwrap_or(SerializationFormatArg::Json);
720 let mut path_base = self.dest_dir.clone().unwrap_or_default();
721 path_base.push(crate_name);
722
723 match format.as_format() {
724 Some(format) => match self.dest_file.clone() {
725 Some(dest) => vec![(dest, format)],
726 None => vec![self.target_filename(path_base, format)],
727 },
728 None => {
729 let path_base = self.dest_file.clone().unwrap_or(path_base);
730 vec![
731 self.target_filename(path_base.clone(), SerializationFormat::Json),
732 self.target_filename(path_base, SerializationFormat::Postcard),
733 ]
734 }
735 }
736 }
737}
738
739#[derive(Debug, Clone, EnumAsGetters)]
741pub enum StartFrom {
742 Pattern { pattern: NamePattern, strict: bool },
745 Attribute(String),
747 Pub,
750}
751
752pub struct TranslateOptions {
754 pub start_from: Vec<StartFrom>,
756 pub mir_level: MirLevel,
758 pub translate_all_methods: bool,
761 pub eager_vtables: bool,
763 pub duplicate_defaulted_methods: bool,
765 pub monomorphize_mut: Option<MonomorphizeMut>,
768 pub hide_marker_traits: bool,
771 pub hide_allocator: bool,
773 pub no_doc_comments: bool,
775 pub hide_traits: Vec<NamePattern>,
778 pub remove_unused_clauses: bool,
782 pub remove_unused_self_clauses: bool,
784 pub remove_adt_clauses: bool,
786 pub monomorphize_with_hax: bool,
788 pub ullbc: bool,
790 pub ops_to_function_calls: bool,
793 pub index_to_function_calls: bool,
795 pub print_built_llbc: bool,
797 pub treat_box_as_builtin: bool,
799 pub no_gen_tuple_structs: bool,
802 pub raw_consts: bool,
804 pub inline_anon_consts: bool,
806 pub consts: ConstHandling,
808 pub unsized_strings: bool,
811 pub reconstruct_fallible_operations: bool,
814 pub reconstruct_panic_calls: bool,
816 pub reconstruct_asserts: bool,
818 pub reconstruct_matches: bool,
820 pub deallocate_all_locals: bool,
822 pub unbind_item_vars: bool,
824 pub item_opacities: Vec<(NamePattern, ItemOpacity)>,
827 pub lift_associated_types: Vec<NamePattern>,
829 pub erase_body_lifetimes: bool,
831 pub no_typecheck: bool,
833 pub no_normalize: bool,
835 pub no_reorder_decls: bool,
837 pub no_compute_layout_guarantees: bool,
839 pub desugar_drops: bool,
841 pub resugar_drops: bool,
843 pub detect_drop_flags: bool,
845 pub add_destruct_bounds: bool,
847}
848
849impl TranslateOptions {
850 pub fn new(error_ctx: &mut ErrorCtx, options: &CliOpts) -> Self {
851 let mut parse_pattern = |s: &str| -> Result<_, Error> {
852 match NamePattern::parse(s) {
853 Ok(p) => Ok(p),
854 Err(e) => raise_error!(error_ctx, no_crate, "failed to parse pattern `{s}` ({e})"),
855 }
856 };
857
858 let mut mir_level = options.mir.unwrap_or(MirLevel::Promoted);
859 if options.precise_drops {
860 mir_level = std::cmp::max(mir_level, MirLevel::Elaborated);
861 }
862
863 let mut start_from = options
864 .start_from
865 .iter()
866 .filter_map(|path| parse_pattern(path).ok())
867 .map(|p| StartFrom::Pattern {
868 pattern: p,
869 strict: true,
870 })
871 .collect_vec();
872 start_from.extend(
873 options
874 .start_from_if_exists
875 .iter()
876 .filter_map(|path| parse_pattern(path).ok())
877 .map(|p| StartFrom::Pattern {
878 pattern: p,
879 strict: false,
880 }),
881 );
882 for attr in options.start_from_attribute.iter().cloned() {
883 start_from.push(StartFrom::Attribute(attr));
884 }
885 if options.start_from_pub {
886 start_from.push(StartFrom::Pub);
887 }
888 if start_from.is_empty() {
889 start_from.push(StartFrom::Pattern {
890 pattern: parse_pattern("crate").unwrap(),
891 strict: true,
892 });
893 }
894
895 let hide_traits = options
896 .hide_marker_traits
897 .then_some([
898 "core::marker::Sized",
899 "core::marker::MetaSized",
900 "core::marker::PointeeSized",
901 "core::marker::Tuple",
902 "core::clone::TrivialClone",
903 ])
904 .into_iter()
905 .flatten()
906 .chain(options.hide_allocator.then_some("core::alloc::Allocator"))
907 .filter_map(|s| parse_pattern(s).ok())
908 .collect_vec();
909
910 let item_opacities = {
911 use ItemOpacity::*;
912 let mut opacities = vec![];
913
914 if options.extract_opaque_bodies {
916 opacities.push(("_".to_string(), Transparent));
917 } else {
918 opacities.push(("_".to_string(), Foreign));
919 }
920
921 if options.treat_box_as_builtin {
922 opacities.push((
924 "alloc::boxed::box_assume_init_into_vec_unsafe".to_string(),
925 Transparent,
926 ));
927 }
928
929 opacities.push(("crate".to_owned(), Transparent));
931
932 for pat in options.include.iter() {
933 opacities.push((pat.to_string(), Transparent));
934 }
935 for pat in options.opaque.iter() {
936 opacities.push((pat.to_string(), Opaque));
937 }
938 if options.run_with_minirust
939 || matches!(options.format, Some(SerializationFormatArg::MiniRust))
940 {
941 opacities.push(("intrinsics".to_owned(), Opaque));
945 }
946 for pat in options.exclude.iter() {
947 opacities.push((pat.to_string(), Invisible));
948 }
949
950 for trait_name in &hide_traits {
951 opacities.push((trait_name.to_string(), Invisible));
952 }
953
954 let hide_traits = hide_traits
956 .iter()
957 .cloned()
958 .flat_map(|pat| [pat.clone(), NamePattern::impl_for(pat)])
959 .map(|pat| (pat, Invisible));
960 opacities
961 .into_iter()
962 .filter_map(|(s, opacity)| parse_pattern(&s).ok().map(|pat| (pat, opacity)))
963 .chain(hide_traits)
964 .collect()
965 };
966
967 let lift_associated_types = options
968 .lift_associated_types
969 .iter()
970 .filter_map(|s| parse_pattern(s).ok())
971 .collect();
972
973 TranslateOptions {
974 start_from,
975 mir_level,
976 monomorphize_mut: options.monomorphize_mut,
977 hide_marker_traits: options.hide_marker_traits,
978 hide_allocator: options.hide_allocator,
979 no_doc_comments: options.no_doc_comments,
980 hide_traits,
981 remove_unused_clauses: options.remove_unused_clauses,
982 remove_unused_self_clauses: options.remove_unused_self_clauses,
983 remove_adt_clauses: options.remove_adt_clauses,
984 monomorphize_with_hax: options.monomorphize,
985 ullbc: options.ullbc,
986 ops_to_function_calls: options.ops_to_function_calls,
987 index_to_function_calls: options.index_to_function_calls,
988 print_built_llbc: options.print_built_llbc,
989 item_opacities,
990 treat_box_as_builtin: options.treat_box_as_builtin,
991 no_gen_tuple_structs: options.no_gen_tuple_structs,
992 raw_consts: options.raw_consts,
993 inline_anon_consts: options.inline_anon_consts,
994 consts: options.consts.unwrap_or_default(),
995 unsized_strings: options.unsized_strings,
996 reconstruct_fallible_operations: options.reconstruct_fallible_operations,
997 reconstruct_panic_calls: options.reconstruct_panic_calls,
998 reconstruct_asserts: options.reconstruct_asserts,
999 reconstruct_matches: options.reconstruct_matches,
1000 deallocate_all_locals: options.deallocate_all_locals,
1001 lift_associated_types,
1002 unbind_item_vars: options.unbind_item_vars,
1003 translate_all_methods: options.translate_all_methods,
1004 eager_vtables: options.eager_vtables,
1005 duplicate_defaulted_methods: options.duplicate_defaulted_methods,
1006 erase_body_lifetimes: options.erase_body_lifetimes,
1007 no_typecheck: options.no_typecheck,
1008 no_normalize: options.no_normalize,
1009 no_reorder_decls: options.no_reorder_decls,
1010 no_compute_layout_guarantees: options.no_compute_layout_guarantees,
1011 desugar_drops: options.desugar_drops,
1012 resugar_drops: options.resugar_drops,
1013 detect_drop_flags: options.detect_drop_flags,
1014 add_destruct_bounds: options.precise_drops,
1015 }
1016 }
1017
1018 #[tracing::instrument(skip(self, krate), ret)]
1021 pub fn opacity_for_name(&self, krate: &TranslatedCrate, name: &Name) -> ItemOpacity {
1022 if name.is_builtin() {
1024 return ItemOpacity::Transparent;
1025 }
1026 let (_, opacity) = self
1030 .item_opacities
1031 .iter()
1032 .filter(|(pat, _)| pat.matches(krate, name))
1033 .max()
1034 .unwrap();
1035 *opacity
1036 }
1037}