Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/semantics.rs')
| -rw-r--r-- | crates/hir/src/semantics.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index fd08528e86..60418b1dad 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -8,6 +8,7 @@ use std::{ convert::Infallible, fmt, iter, mem, ops::{self, ControlFlow, Not}, + sync::Mutex, }; use base_db::FxIndexSet; @@ -32,11 +33,13 @@ use hir_expand::{ use hir_ty::{ InferenceResult, diagnostics::{unsafe_operations, unsafe_operations_for_body}, - next_solver::DbInterner, + infer_query_with_inspect, + next_solver::{DbInterner, Span, format_proof_tree::dump_proof_tree_structured}, }; use intern::{Interned, Symbol, sym}; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_type_ir::inherent::Span as _; use smallvec::{SmallVec, smallvec}; use span::{FileId, SyntaxContext}; use stdx::{TupleExt, always}; @@ -2310,6 +2313,35 @@ impl<'db> SemanticsImpl<'db> { Some(locals) } + + pub fn get_failed_obligations(&self, token: SyntaxToken) -> Option<String> { + let node = token.parent()?; + let node = self.find_file(&node); + + let container = self.with_ctx(|ctx| ctx.find_container(node))?; + + match container { + ChildContainer::DefWithBodyId(def) => { + static RESULT: Mutex<String> = Mutex::new(String::new()); + infer_query_with_inspect( + self.db, + def, + Some(|infer_ctxt, _obligation, result, proof_tree| { + if result.is_err() + && let Some(tree) = proof_tree + { + let data = dump_proof_tree_structured(tree, Span::dummy(), infer_ctxt); + let data = serde_json::to_string_pretty(&data) + .unwrap_or_else(|_| "{}".to_string()); + *RESULT.lock().unwrap() = data; + } + }), + ); + RESULT.lock().ok().map(|s| (*s).clone()) + } + _ => None, + } + } } // FIXME This can't be the best way to do this |