about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-08 11:44:45 +0000
committerbors <bors@rust-lang.org>2021-10-08 11:44:45 +0000
commite0aaffd8a45cd0e9f331ec7734713e9de11aa6c8 (patch)
tree11385f103f96e0bcc09ccf85b4b77e7351fd87d1 /compiler/rustc_trait_selection/src
parent44995f7afb18775913618ae50601be31b9f9dead (diff)
parent0950d5afe227c7097e59bf797a85267d3a659744 (diff)
downloadrust-e0aaffd8a45cd0e9f331ec7734713e9de11aa6c8.tar.gz
rust-e0aaffd8a45cd0e9f331ec7734713e9de11aa6c8.zip
Auto merge of #89576 - tom7980:issue-89275-fix, r=estebank
Prevent error reporting from outputting a recursion error if it finds an ambiguous trait impl during suggestions

Closes #89275

This fixes the compiler reporting a recursion error during another already in progress error by trying to make a conversion method suggestion and encounters ambiguous trait implementations that can convert a the original type into a type that can then be recursively converted into itself via another method in the trait.

Updated OverflowError struct to be an enum so I could differentiate between passes - it's no longer a ZST but I don't think that should be a problem as they only generate when there's an error in compiling code anyway
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
4 files changed, 25 insertions, 13 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 88e8df81488..225ff5e597e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -842,6 +842,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             Overflow => {
                 bug!("overflow should be handled before the `report_selection_error` path");
             }
+            SelectionError::ErrorReporting => {
+                bug!("ErrorReporting Overflow should not reach `report_selection_err` call")
+            }
         };
 
         self.note_obligation_cause(&mut err, &obligation);
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 032d402fec0..31254a0534d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -83,17 +83,21 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
     ) -> EvaluationResult {
         match self.evaluate_obligation(obligation) {
             Ok(result) => result,
-            Err(OverflowError) => {
+            Err(OverflowError::Cannonical) => {
                 let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
-                selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| {
-                    span_bug!(
-                        obligation.cause.span,
-                        "Overflow should be caught earlier in standard query mode: {:?}, {:?}",
-                        obligation,
-                        r,
-                    )
+                selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
+                    OverflowError::Cannonical => {
+                        span_bug!(
+                            obligation.cause.span,
+                            "Overflow should be caught earlier in standard query mode: {:?}, {:?}",
+                            obligation,
+                            r,
+                        )
+                    }
+                    OverflowError::ErrorReporting => EvaluationResult::EvaluatedToErr,
                 })
             }
+            Err(OverflowError::ErrorReporting) => EvaluationResult::EvaluatedToErr,
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index f3706aa6e71..d68ae079077 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -18,7 +18,7 @@ use crate::traits;
 use crate::traits::coherence::Conflict;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{util, SelectionResult};
-use crate::traits::{Overflow, Unimplemented};
+use crate::traits::{ErrorReporting, Overflow, Unimplemented};
 
 use super::BuiltinImplConditions;
 use super::IntercrateAmbiguityCause;
@@ -161,7 +161,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
                 }
                 Ok(_) => Ok(None),
-                Err(OverflowError) => Err(Overflow),
+                Err(OverflowError::Cannonical) => Err(Overflow),
+                Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
             })
             .flat_map(Result::transpose)
             .collect::<Result<Vec<_>, _>>()?;
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index e191654210a..3818e75a1de 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -20,8 +20,8 @@ use super::ObligationCauseCode;
 use super::Selection;
 use super::SelectionResult;
 use super::TraitQueryMode;
+use super::{ErrorReporting, Overflow, SelectionError, Unimplemented};
 use super::{ObligationCause, PredicateObligation, TraitObligation};
-use super::{Overflow, SelectionError, Unimplemented};
 
 use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::traits::error_reporting::InferCtxtExt;
@@ -900,7 +900,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match self.candidate_from_obligation(stack) {
             Ok(Some(c)) => self.evaluate_candidate(stack, &c),
             Ok(None) => Ok(EvaluatedToAmbig),
-            Err(Overflow) => Err(OverflowError),
+            Err(Overflow) => Err(OverflowError::Cannonical),
+            Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
             Err(..) => Ok(EvaluatedToErr),
         }
     }
@@ -1057,10 +1058,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
             match self.query_mode {
                 TraitQueryMode::Standard => {
+                    if self.infcx.is_tainted_by_errors() {
+                        return Err(OverflowError::ErrorReporting);
+                    }
                     self.infcx.report_overflow_error(error_obligation, true);
                 }
                 TraitQueryMode::Canonical => {
-                    return Err(OverflowError);
+                    return Err(OverflowError::Cannonical);
                 }
             }
         }