]> git.lizzy.rs Git - rust.git/blob - src/unimpl.rs
Bump rand_pcg from 0.1.1 to 0.1.2
[rust.git] / src / unimpl.rs
1 //! The unimpl! macro is defined here. It is used to generate
2 //! a non-fatal error on not yet implemented things.
3
4 use std::cell::RefCell;
5 use std::fs::File;
6 use std::io::Write;
7
8 use syntax::source_map::Span;
9
10 use rustc::ty::TyCtxt;
11
12 thread_local! {
13     static SPAN_STACK: RefCell<Vec<Span>> = RefCell::new(vec![]);
14 }
15
16 // Just public, because of the unimpl macro
17 pub struct NonFatal(pub String);
18
19 pub macro unimpl($($tt:tt)*) {
20     panic!(NonFatal(format!($($tt)*)));
21 }
22
23 pub fn try_unimpl(tcx: TyCtxt, log: &mut Option<File>, f: impl FnOnce()) {
24     let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| f()));
25
26     if let Err(err) = res {
27         SPAN_STACK.with(|span_stack| {
28             match err.downcast::<NonFatal>() {
29                 Ok(non_fatal) => {
30                     if cfg!(debug_assertions) {
31                         writeln!(
32                             log.as_mut().unwrap(),
33                             "{} at {:?}",
34                             &non_fatal.0,
35                             span_stack.borrow()
36                         )
37                         .unwrap();
38                     }
39                     tcx.sess.err(&non_fatal.0)
40                 }
41                 Err(err) => ::std::panic::resume_unwind(err),
42             }
43             span_stack.borrow_mut().clear();
44         });
45     }
46 }
47
48 pub fn with_unimpl_span(span: Span, f: impl FnOnce()) {
49     SPAN_STACK.with(|span_stack| {
50         span_stack.borrow_mut().push(span);
51         f();
52         span_stack.borrow_mut().pop();
53     });
54 }