]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-macros/src/lib.rs
New upstream version 1.42.0+dfsg1
[rustc.git] / vendor / chalk-macros / src / lib.rs
1 #![feature(crate_visibility_modifier)]
2 #![feature(macro_vis_matcher)]
3
4 use std::cell::RefCell;
5
6 #[macro_use]
7 extern crate lazy_static;
8
9 #[macro_use]
10 mod index;
11
12 lazy_static! {
13 pub static ref DEBUG_ENABLED: bool = {
14 use std::env;
15 env::var("CHALK_DEBUG")
16 .ok()
17 .and_then(|s| s.parse::<u32>().ok())
18 .map(|x| x >= 2)
19 .unwrap_or(false)
20 };
21
22 pub static ref INFO_ENABLED: bool = {
23 use std::env;
24 env::var("CHALK_DEBUG")
25 .ok()
26 .and_then(|s| s.parse::<u32>().ok())
27 .map(|x| x >= 1)
28 .unwrap_or(false)
29 };
30 }
31
32 thread_local! {
33 crate static INDENT: RefCell<Vec<String>> = RefCell::new(vec![]);
34 }
35
36 // When CHALK_DEBUG is enabled, we only allow this many frames of
37 // nested processing, at which point we assume something has gone
38 // awry.
39 const OVERFLOW_DEPTH: usize = 100;
40
41 #[macro_export]
42 macro_rules! debug {
43 ($($t:tt)*) => {
44 if *$crate::DEBUG_ENABLED {
45 $crate::dump(&format!($($t)*), "");
46 }
47 }
48 }
49
50 #[macro_export]
51 macro_rules! debug_heading {
52 ($($t:tt)*) => {
53 let _ = &if *$crate::DEBUG_ENABLED {
54 let string = format!($($t)*);
55 $crate::dump(&string, " {");
56 $crate::Indent::new(true, string)
57 } else {
58 $crate::Indent::new(false, String::new())
59 };
60 }
61 }
62
63 #[macro_export]
64 macro_rules! info {
65 ($($t:tt)*) => {
66 if *$crate::INFO_ENABLED {
67 $crate::dump(&format!($($t)*), "");
68 }
69 }
70 }
71
72 #[macro_export]
73 macro_rules! info_heading {
74 ($($t:tt)*) => {
75 let _ = &if *$crate::INFO_ENABLED {
76 let string = format!($($t)*);
77 $crate::dump(&string, " {");
78 $crate::Indent::new(true, string)
79 } else {
80 $crate::Indent::new(false, String::new())
81 };
82 }
83 }
84
85 pub fn dump(string: &str, suffix: &str) {
86 let indent = INDENT.with(|i| i.borrow().len());
87 let mut first = true;
88 for line in string.lines() {
89 if first {
90 for _ in 0..indent {
91 eprint!(": ");
92 }
93 eprint!("| ");
94 } else {
95 eprintln!();
96 for _ in 0..indent {
97 eprint!(": ");
98 }
99 eprint!(": ");
100 }
101 eprint!("{}", line);
102 first = false;
103 }
104
105 eprintln!("{}", suffix);
106 }
107
108 pub struct Indent {
109 enabled: bool,
110 }
111
112 impl Indent {
113 pub fn new(enabled: bool, value: String) -> Self {
114 if enabled {
115 INDENT.with(|i| {
116 i.borrow_mut().push(value);
117 if i.borrow().len() > OVERFLOW_DEPTH {
118 eprintln!("CHALK_DEBUG OVERFLOW:");
119 for v in i.borrow().iter().rev() {
120 eprintln!("- {}", v);
121 }
122 panic!("CHALK_DEBUG OVERFLOW")
123 }
124 });
125 }
126 Indent { enabled }
127 }
128 }
129
130 impl Drop for Indent {
131 fn drop(&mut self) {
132 if self.enabled {
133 INDENT.with(|i| i.borrow_mut().pop().unwrap());
134 dump("}", "");
135 }
136 }
137 }