]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #94391 - light4:issue-90319, r=estebank
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>
Fri, 25 Mar 2022 00:34:28 +0000 (01:34 +0100)
committerGitHub <noreply@github.com>
Fri, 25 Mar 2022 00:34:28 +0000 (01:34 +0100)
Fix ice when error reporting recursion errors

Fixes: #90319, #92148, #93955
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/traits/select.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/project.rs
compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
src/test/ui/typeck/issue-90319.rs [new file with mode: 0644]
src/test/ui/typeck/issue-90319.stderr [new file with mode: 0644]

index 3ed7836074b258b8d038d4f13c1d33b3266c84c2..d852531bc68672075ce0453ec1ca75e4f2a3984e 100644 (file)
@@ -491,7 +491,7 @@ pub enum SelectionError<'tcx> {
     /// A given constant couldn't be evaluated.
     NotConstEvaluatable(NotConstEvaluatable),
     /// Exceeded the recursion depth during type projection.
-    Overflow,
+    Overflow(OverflowError),
     /// Signaling that an error has already been emitted, to avoid
     /// multiple errors being shown.
     ErrorReporting,
index 56d42706f6778c90a119e57a3edb4a653070529c..5297825a92fcc225d78905463dea68a09421b9c9 100644 (file)
@@ -5,6 +5,7 @@
 use self::EvaluationResult::*;
 
 use super::{SelectionError, SelectionResult};
+use rustc_errors::ErrorGuaranteed;
 
 use crate::ty;
 
@@ -264,14 +265,26 @@ pub fn is_stack_dependent(self) -> bool {
 /// Indicates that trait evaluation caused overflow and in which pass.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub enum OverflowError {
+    Error(ErrorGuaranteed),
     Canonical,
     ErrorReporting,
 }
 
+impl From<ErrorGuaranteed> for OverflowError {
+    fn from(e: ErrorGuaranteed) -> OverflowError {
+        OverflowError::Error(e)
+    }
+}
+
+TrivialTypeFoldableAndLiftImpls! {
+    OverflowError,
+}
+
 impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
     fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
         match overflow_error {
-            OverflowError::Canonical => SelectionError::Overflow,
+            OverflowError::Error(e) => SelectionError::Overflow(OverflowError::Error(e)),
+            OverflowError::Canonical => SelectionError::Overflow(OverflowError::Canonical),
             OverflowError::ErrorReporting => SelectionError::ErrorReporting,
         }
     }
index 229e108d5d64070322005adec4cd33e4962119ba..5e220173caeeac0cf5f191a9b15f33d1d425f625 100644 (file)
@@ -22,6 +22,7 @@
 use rustc_hir::Item;
 use rustc_hir::Node;
 use rustc_middle::thir::abstract_const::NotConstEvaluatable;
+use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::error::ExpectedFound;
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::{
@@ -928,8 +929,12 @@ fn report_selection_error(
                 self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error");
                 return;
             }
-
-            Overflow => {
+            // Already reported.
+            Overflow(OverflowError::Error(_)) => {
+                self.tcx.sess.delay_span_bug(span, "`OverflowError` has been reported");
+                return;
+            }
+            Overflow(_) => {
                 bug!("overflow should be handled before the `report_selection_error` path");
             }
             SelectionError::ErrorReporting => {
index 390381752f95df54eeaa343ec3555d0e62e2016d..b61e68735712bee38fae0cf0a226dc9b1e279089 100644 (file)
@@ -27,6 +27,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
+use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
@@ -1139,7 +1140,9 @@ fn project<'cx, 'tcx>(
     if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
         // This should really be an immediate error, but some existing code
         // relies on being able to recover from this.
-        return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow));
+        return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow(
+            OverflowError::Canonical,
+        )));
     }
 
     if obligation.predicate.references_error() {
index 4874ba6f58cac5138dce636f32f856180b9a5f6b..db45ee3fed7db17fb2a0842e3685631dd2d225c8 100644 (file)
@@ -108,9 +108,11 @@ fn evaluate_obligation_no_overflow(
                         )
                     }
                     OverflowError::ErrorReporting => EvaluationResult::EvaluatedToErr,
+                    OverflowError::Error(_) => EvaluationResult::EvaluatedToErr,
                 })
             }
             Err(OverflowError::ErrorReporting) => EvaluationResult::EvaluatedToErr,
+            Err(OverflowError::Error(_)) => EvaluationResult::EvaluatedToErr,
         }
     }
 }
index c0a283d2edae4482222b0517269bf6a423a8a4e2..3e7a2252318be550f92a4f808e9b5c3ee300ed2c 100644 (file)
@@ -164,8 +164,9 @@ fn candidate_from_obligation_no_cache<'o>(
                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
                 }
                 Ok(_) => Ok(None),
-                Err(OverflowError::Canonical) => Err(Overflow),
+                Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
                 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
+                Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
             })
             .flat_map(Result::transpose)
             .collect::<Result<Vec<_>, _>>()?;
index 3a5bca492965e939110754549917a0af72d5c9a8..b7c2f0f4832c02ae1bb44886c6fee40375326038 100644 (file)
@@ -25,7 +25,7 @@
 use crate::traits::ProjectionCacheKey;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::Diagnostic;
+use rustc_errors::{Diagnostic, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::LateBoundRegionConversionTime;
@@ -316,11 +316,11 @@ pub fn select(
         obligation: &TraitObligation<'tcx>,
     ) -> SelectionResult<'tcx, Selection<'tcx>> {
         let candidate = match self.select_from_obligation(obligation) {
-            Err(SelectionError::Overflow) => {
+            Err(SelectionError::Overflow(OverflowError::Canonical)) => {
                 // In standard mode, overflow must have been caught and reported
                 // earlier.
                 assert!(self.query_mode == TraitQueryMode::Canonical);
-                return Err(SelectionError::Overflow);
+                return Err(SelectionError::Overflow(OverflowError::Canonical));
             }
             Err(SelectionError::Ambiguous(_)) => {
                 return Ok(None);
@@ -335,9 +335,9 @@ pub fn select(
         };
 
         match self.confirm_candidate(obligation, candidate) {
-            Err(SelectionError::Overflow) => {
+            Err(SelectionError::Overflow(OverflowError::Canonical)) => {
                 assert!(self.query_mode == TraitQueryMode::Canonical);
-                Err(SelectionError::Overflow)
+                Err(SelectionError::Overflow(OverflowError::Canonical))
             }
             Err(e) => Err(e),
             Ok(candidate) => {
@@ -954,7 +954,7 @@ fn evaluate_stack<'o>(
             Ok(Some(c)) => self.evaluate_candidate(stack, &c),
             Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig),
             Ok(None) => Ok(EvaluatedToAmbig),
-            Err(Overflow) => Err(OverflowError::Canonical),
+            Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
             Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
             Err(..) => Ok(EvaluatedToErr),
         }
@@ -1113,7 +1113,9 @@ fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
             match self.query_mode {
                 TraitQueryMode::Standard => {
                     if self.infcx.is_tainted_by_errors() {
-                        return Err(OverflowError::ErrorReporting);
+                        return Err(OverflowError::Error(
+                            ErrorGuaranteed::unchecked_claim_error_was_emitted(),
+                        ));
                     }
                     self.infcx.report_overflow_error(error_obligation, true);
                 }
@@ -1349,7 +1351,7 @@ fn insert_candidate_cache(
         }
 
         if self.can_use_global_caches(param_env) {
-            if let Err(Overflow) = candidate {
+            if let Err(Overflow(OverflowError::Canonical)) = candidate {
                 // Don't cache overflow globally; we only produce this in certain modes.
             } else if !pred.needs_infer() {
                 if !candidate.needs_infer() {
diff --git a/src/test/ui/typeck/issue-90319.rs b/src/test/ui/typeck/issue-90319.rs
new file mode 100644 (file)
index 0000000..57e6ac7
--- /dev/null
@@ -0,0 +1,17 @@
+struct Wrapper<T>(T);
+
+trait Trait {
+    fn method(&self) {}
+}
+
+impl<'a, T> Trait for Wrapper<&'a T> where Wrapper<T>: Trait {}
+
+fn get<T>() -> T {
+    unimplemented!()
+}
+
+fn main() {
+    let thing = get::<Thing>();//~ERROR cannot find type `Thing` in this scope [E0412]
+    let wrapper = Wrapper(thing);
+    Trait::method(&wrapper);
+}
diff --git a/src/test/ui/typeck/issue-90319.stderr b/src/test/ui/typeck/issue-90319.stderr
new file mode 100644 (file)
index 0000000..61549dd
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Thing` in this scope
+  --> $DIR/issue-90319.rs:14:23
+   |
+LL |     let thing = get::<Thing>();
+   |                       ^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.