about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits
diff options
context:
space:
mode:
authorBoxy <supbscripter@gmail.com>2023-07-03 21:00:10 +0100
committerBoxy <supbscripter@gmail.com>2023-07-03 21:00:16 +0100
commit040aa58d0a5e35b73c487e395e3d59263de188ff (patch)
tree6ee545db70bac74a562b5bc6127c78d088238e70 /compiler/rustc_trait_selection/src/traits
parent8931edf746da6aa2d86412516d805f5680929a5e (diff)
downloadrust-040aa58d0a5e35b73c487e395e3d59263de188ff.tar.gz
rust-040aa58d0a5e35b73c487e395e3d59263de188ff.zip
add flag for disabling global cache and printing proof trees on error
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits')
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index f7670d51bdc..0b91a5fc70a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -10,6 +10,7 @@ use super::{
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
+use crate::solve::{DisableGlobalCache, GenerateProofTree, InferCtxtEvalExt};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::query::normalize::QueryNormalizeExt as _;
 use crate::traits::specialize::to_pretty_impl_header;
@@ -28,6 +29,7 @@ use rustc_hir::{GenericParam, Item, Node};
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_middle::traits::select::OverflowError;
+use rustc_middle::traits::solve::Goal;
 use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -37,13 +39,14 @@ use rustc_middle::ty::{
     self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
     TypeVisitable, TypeVisitableExt,
 };
-use rustc_session::config::TraitSolver;
+use rustc_session::config::{SolverProofTreeCondition, TraitSolver};
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::symbol::sym;
 use rustc_span::{ExpnKind, Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::fmt;
+use std::io::Write;
 use std::iter;
 use std::ops::ControlFlow;
 use suggestions::TypeErrCtxtExt as _;
@@ -630,6 +633,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         error: &SelectionError<'tcx>,
     ) {
         let tcx = self.tcx;
+
+        if tcx.sess.opts.unstable_opts.dump_solver_proof_tree == SolverProofTreeCondition::OnError {
+            dump_proof_tree(root_obligation, self.infcx);
+        }
+
         let mut span = obligation.cause.span;
         // FIXME: statically guarantee this by tainting after the diagnostic is emitted
         self.set_tainted_by_errors(
@@ -1529,6 +1537,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
+        if self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree
+            == SolverProofTreeCondition::OnError
+        {
+            dump_proof_tree(&error.root_obligation, self.infcx);
+        }
+
         match error.code {
             FulfillmentErrorCode::CodeSelectionError(ref selection_error) => {
                 self.report_selection_error(
@@ -3499,3 +3513,16 @@ pub enum DefIdOrName {
     DefId(DefId),
     Name(&'static str),
 }
+
+pub fn dump_proof_tree<'tcx>(o: &Obligation<'tcx, ty::Predicate<'tcx>>, infcx: &InferCtxt<'tcx>) {
+    infcx.probe(|_| {
+        let goal = Goal { predicate: o.predicate, param_env: o.param_env };
+        let tree = infcx
+            .evaluate_root_goal(goal, GenerateProofTree::Yes(DisableGlobalCache::Yes))
+            .1
+            .expect("proof tree should have been generated");
+        let mut lock = std::io::stdout().lock();
+        let _ = lock.write_fmt(format_args!("{tree:?}"));
+        let _ = lock.flush();
+    });
+}