1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#![doc(html_root_url = "https://calypso-lang.github.io/rustdoc/calypso/index.html")]
#![warn(clippy::pedantic)]
use std::panic;
use std::sync::Arc;
use clap::StructOpt;
use once_cell::sync::OnceCell;
use tracing_subscriber::EnvFilter;
use calypso_base::ui::Emitters;
use calypso_common::{gcx::GlobalCtxt, parking_lot::RwLock};
use calypso_diagnostic::prelude::*;
use calypso_diagnostic::{diagnostic::SourceMgr, report::GlobalReportingCtxt};
mod buildinfo;
mod cli;
mod commands;
use buildinfo::BUILD_INFO;
use cli::{Args, Command, LogFormat};
#[cfg(feature = "mimalloc")]
use mimalloc::MiMalloc;
#[cfg(feature = "mimalloc")]
#[cfg_attr(feature = "mimalloc", global_allocator)]
static GLOBAL: MiMalloc = MiMalloc;
static DEFAULT_HOOK: OnceCell<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
OnceCell::new();
const BUG_REPORT_URL: &str = "https://github.com/calypso-lang/calypso/issues/new\
?assignees=&labels=C-bug&template=bug-report.md&title=bug%3A+";
fn init_panic_hook(gcx: &Arc<GlobalCtxt>) {
let gcx = Arc::clone(gcx);
DEFAULT_HOOK.get_or_init(|| {
let gcx = Arc::clone(&gcx);
let hook = panic::take_hook();
panic::set_hook(Box::new(move |info| {
let gcx = Arc::clone(&gcx);
report_ice(&*gcx, info, BUG_REPORT_URL).unwrap();
}));
hook
});
}
fn report_ice(gcx: &GlobalCtxt, info: &panic::PanicInfo<'_>, report_url: &str) -> CalResult<()> {
DEFAULT_HOOK.get().unwrap()(info);
gcx.emit
.write()
.err
.newline()?
.error(
None,
"the compiler unexpectedly crashed. this is a bug.",
None,
)?
.note("we would appreciate a bug report at", Some(report_url))?
.note(
"build information",
Some(&format!(
"calypso {} ({}) running on {}",
BUILD_INFO.version, BUILD_INFO.git_commit, BUILD_INFO.cargo_target_triple
)),
)?
.note(
"for further information, run",
Some("`calypso internal build-info`"),
)?
.flush()?;
Ok(())
}
fn main() {
let args = Args::parse();
let gcx = Arc::new(GlobalCtxt {
emit: RwLock::new(Emitters::new(args.color.0, args.color.1)),
grcx: RwLock::new(GlobalReportingCtxt::new()),
sourcemgr: RwLock::new(SourceMgr::new()),
});
init_panic_hook(&gcx);
let mut trace = tracing_subscriber::fmt::fmt().with_env_filter(EnvFilter::default());
if let Some(log) = args.log {
trace = trace.with_env_filter(EnvFilter::new(log));
}
match args.log_format {
LogFormat::Pretty => {
trace.pretty().init();
}
LogFormat::Compat => {
trace.compact().init();
}
LogFormat::Json => {
trace.json().init();
}
}
let res = match args.cmd {
Command::Explain { ecode } => commands::explain(&gcx, &ecode),
Command::Internal { cmd } => commands::internal(&gcx, &cmd),
};
if let Err(e) = res {
gcx.emit
.write()
.err
.error(None, &e.to_string(), None)
.unwrap()
.flush()
.unwrap();
}
}