From: Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> Date: Fri, 25 Mar 2022 00:34:28 +0000 (+0100) Subject: Rollup merge of #94391 - light4:issue-90319, r=estebank X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=d1d4613ead1896eff612903edb5da42630821b29;hp=63b8f01bb5ca277e7df8d7efe094ed4244c1790c;p=rust.git Rollup merge of #94391 - light4:issue-90319, r=estebank Fix ice when error reporting recursion errors Fixes: #90319, #92148, #93955 --- diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 3ed7836074b..d852531bc68 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -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, diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 56d42706f67..5297825a92f 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -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 for OverflowError { + fn from(e: ErrorGuaranteed) -> OverflowError { + OverflowError::Error(e) + } +} + +TrivialTypeFoldableAndLiftImpls! { + OverflowError, +} + impl<'tcx> From 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, } } 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 229e108d5d6..5e220173cae 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -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 => { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 390381752f9..b61e6873571 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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() { 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 4874ba6f58c..db45ee3fed7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -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, } } } 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 c0a283d2eda..3e7a2252318 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -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::, _>>()?; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 3a5bca49296..b7c2f0f4832 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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>( 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 index 00000000000..57e6ac7cf34 --- /dev/null +++ b/src/test/ui/typeck/issue-90319.rs @@ -0,0 +1,17 @@ +struct Wrapper(T); + +trait Trait { + fn method(&self) {} +} + +impl<'a, T> Trait for Wrapper<&'a T> where Wrapper: Trait {} + +fn get() -> T { + unimplemented!() +} + +fn main() { + let thing = get::();//~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 index 00000000000..61549dd701e --- /dev/null +++ b/src/test/ui/typeck/issue-90319.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Thing` in this scope + --> $DIR/issue-90319.rs:14:23 + | +LL | let thing = get::(); + | ^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`.