]> git.lizzy.rs Git - rust.git/blob - src/unimpl.rs
Use anonymous lifetimes where possible
[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 #[doc(hidden)]
18 pub struct NonFatal(pub String);
19
20 /// Use when something in the current function is unimplemented.
21 ///
22 /// This will emit an error and continue codegen at a different function.
23 pub macro unimpl($($tt:tt)*) {
24     panic!(NonFatal(format!($($tt)*)));
25 }
26
27 pub fn try_unimpl(tcx: TyCtxt, log: &mut Option<File>, f: impl FnOnce()) {
28     let res = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| f()));
29
30     if let Err(err) = res {
31         SPAN_STACK.with(|span_stack| {
32             match err.downcast::<NonFatal>() {
33                 Ok(non_fatal) => {
34                     if cfg!(debug_assertions) {
35                         writeln!(
36                             log.as_mut().unwrap(),
37                             "{} at {:?}",
38                             &non_fatal.0,
39                             span_stack.borrow()
40                         )
41                         .unwrap();
42                     }
43                     tcx.sess.err(&non_fatal.0)
44                 }
45                 Err(err) => ::std::panic::resume_unwind(err),
46             }
47             span_stack.borrow_mut().clear();
48         });
49     }
50 }
51
52 pub fn with_unimpl_span(span: Span, f: impl FnOnce()) {
53     SPAN_STACK.with(|span_stack| {
54         span_stack.borrow_mut().push(span);
55         f();
56         span_stack.borrow_mut().pop();
57     });
58 }