From 930df175f0d280d1284ff988f8aaf3b800813b90 Mon Sep 17 00:00:00 2001 From: Tom Farmer Date: Thu, 25 Nov 2021 23:06:22 +0000 Subject: [PATCH] Update to fix regression 90319 and correctly emit overflow errors when not in suggestion context Remove reintrod with_constness() selection context Update to fix regression 90319 and correctly emit overflow errors tidy run Update to fix regression 90319 and correctly emit overflow errors --- .../src/traits/query/evaluate_obligation.rs | 3 ++ .../src/traits/select/mod.rs | 32 ++++++++++++++++++- compiler/rustc_typeck/src/check/demand.rs | 1 - .../rustc_typeck/src/check/method/probe.rs | 5 +-- src/test/ui/typeck/issue-90319.rs | 17 ++++++++++ src/test/ui/typeck/issue-90319.stderr | 25 +++++++++++++++ 6 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/typeck/issue-90319.rs create mode 100644 src/test/ui/typeck/issue-90319.stderr 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 2fa6c0c02597b..134488151156a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -85,6 +85,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { Ok(result) => result, Err(OverflowError::Canonical) => { let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); + if self.is_tainted_by_errors() { + selcx.is_suggestion(true) + } selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r { OverflowError::Canonical => { span_bug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 32d04b55754fc..a126ca83b44f4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -135,6 +135,10 @@ pub struct SelectionContext<'cx, 'tcx> { /// policy. In essence, canonicalized queries need their errors propagated /// rather than immediately reported because we do not have accurate spans. query_mode: TraitQueryMode, + + /// Are we in a selection context to try to make a suggestion for error reporting + /// and we don't want to emit errors until we are complete (Overflow) + is_suggestion: bool, } // A stack that walks back up the stack frame. @@ -224,6 +228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { allow_negative_impls: false, is_in_const_context: false, query_mode: TraitQueryMode::Standard, + is_suggestion: false, } } @@ -236,6 +241,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { allow_negative_impls: false, is_in_const_context: false, query_mode: TraitQueryMode::Standard, + is_suggestion: false, } } @@ -252,6 +258,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { allow_negative_impls, is_in_const_context: false, query_mode: TraitQueryMode::Standard, + is_suggestion: false, } } @@ -268,6 +275,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { allow_negative_impls: false, is_in_const_context: false, query_mode, + is_suggestion: false, } } @@ -283,9 +291,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { allow_negative_impls: false, is_in_const_context: matches!(constness, hir::Constness::Const), query_mode: TraitQueryMode::Standard, + is_suggestion: false, } } + pub fn with_suggestion( + infcx: &'cx InferCtxt<'cx, 'tcx>, + suggestion: bool, + ) -> SelectionContext<'cx, 'tcx> { + SelectionContext { + infcx, + freshener: infcx.freshener_keep_static(), + intercrate: false, + intercrate_ambiguity_causes: None, + allow_negative_impls: false, + is_in_const_context: false, + query_mode: TraitQueryMode::Standard, + is_suggestion: suggestion, + } + } + + /// Enable suggestion mode for use during error reporting selection contexts + /// to prevent reporting overflow errors during method suggestions + pub fn is_suggestion(&mut self, suggestion: bool) { + self.is_suggestion = suggestion; + } /// Enables tracking of intercrate ambiguity causes. These are /// used in coherence to give improved diagnostics. We don't do /// this until we detect a coherence error because it can lead to @@ -1093,7 +1123,7 @@ 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() { + if self.is_suggestion { return Err(OverflowError::ErrorReporting); } self.infcx.report_overflow_error(error_obligation, true); diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 12cd7ad184892..26bbe1682bd5b 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(e) => e, }; - self.set_tainted_by_errors(); let expr = expr.peel_drop_temps(); let cause = self.misc(expr.span); let expr_ty = self.resolve_vars_with_obligations(checked_ty); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 9fd7e8c4daa20..229109d748bb6 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -262,6 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "probe(self_ty={:?}, return_type={}, scope_expr_id={})", self_ty, return_type, scope_expr_id ); + self.set_tainted_by_errors(); let method_names = self .probe_op( span, @@ -1469,7 +1470,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let cause = traits::ObligationCause::misc(self.span, self.body_id); let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate(); let obligation = traits::Obligation::new(cause, self.param_env, predicate); - traits::SelectionContext::new(self).select(&obligation) + traits::SelectionContext::with_suggestion(self, self.is_suggestion.0).select(&obligation) } fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource { @@ -1521,7 +1522,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let mut xform_ret_ty = probe.xform_ret_ty; debug!(?xform_ret_ty); - let selcx = &mut traits::SelectionContext::new(self); + let selcx = &mut traits::SelectionContext::with_suggestion(self, self.is_suggestion.0); let cause = traits::ObligationCause::misc(self.span, self.body_id); // If so, impls may carry other conditions (e.g., where diff --git a/src/test/ui/typeck/issue-90319.rs b/src/test/ui/typeck/issue-90319.rs new file mode 100644 index 0000000000000..a82b0010052de --- /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 14:23: 14:28: cannot find type `Thing` in this scope [E0412] + let wrapper = Wrapper(thing); + Trait::method(&wrapper);//~ERROR 16:5: 16:18: overflow evaluating the requirement `_: Sized` [E0275] +} diff --git a/src/test/ui/typeck/issue-90319.stderr b/src/test/ui/typeck/issue-90319.stderr new file mode 100644 index 0000000000000..55ebaeab6d714 --- /dev/null +++ b/src/test/ui/typeck/issue-90319.stderr @@ -0,0 +1,25 @@ +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[E0275]: overflow evaluating the requirement `_: Sized` + --> $DIR/issue-90319.rs:16:5 + | +LL | Trait::method(&wrapper); + | ^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_90319`) +note: required because of the requirements on the impl of `Trait` for `Wrapper<&_>` + --> $DIR/issue-90319.rs:7:13 + | +LL | impl<'a, T> Trait for Wrapper<&'a T> where Wrapper: Trait {} + | ^^^^^ ^^^^^^^^^^^^^^ + = note: 128 redundant requirements hidden + = note: required because of the requirements on the impl of `Trait` for `Wrapper<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0275, E0412. +For more information about an error, try `rustc --explain E0275`.