Skip to content

Commit 930df17

Browse files
committed
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
1 parent ff2439b commit 930df17

File tree

6 files changed

+79
-4
lines changed

6 files changed

+79
-4
lines changed

compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs

+3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
8585
Ok(result) => result,
8686
Err(OverflowError::Canonical) => {
8787
let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
88+
if self.is_tainted_by_errors() {
89+
selcx.is_suggestion(true)
90+
}
8891
selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
8992
OverflowError::Canonical => {
9093
span_bug!(

compiler/rustc_trait_selection/src/traits/select/mod.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ pub struct SelectionContext<'cx, 'tcx> {
135135
/// policy. In essence, canonicalized queries need their errors propagated
136136
/// rather than immediately reported because we do not have accurate spans.
137137
query_mode: TraitQueryMode,
138+
139+
/// Are we in a selection context to try to make a suggestion for error reporting
140+
/// and we don't want to emit errors until we are complete (Overflow)
141+
is_suggestion: bool,
138142
}
139143

140144
// A stack that walks back up the stack frame.
@@ -224,6 +228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
224228
allow_negative_impls: false,
225229
is_in_const_context: false,
226230
query_mode: TraitQueryMode::Standard,
231+
is_suggestion: false,
227232
}
228233
}
229234

@@ -236,6 +241,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
236241
allow_negative_impls: false,
237242
is_in_const_context: false,
238243
query_mode: TraitQueryMode::Standard,
244+
is_suggestion: false,
239245
}
240246
}
241247

@@ -252,6 +258,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
252258
allow_negative_impls,
253259
is_in_const_context: false,
254260
query_mode: TraitQueryMode::Standard,
261+
is_suggestion: false,
255262
}
256263
}
257264

@@ -268,6 +275,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
268275
allow_negative_impls: false,
269276
is_in_const_context: false,
270277
query_mode,
278+
is_suggestion: false,
271279
}
272280
}
273281

@@ -283,9 +291,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
283291
allow_negative_impls: false,
284292
is_in_const_context: matches!(constness, hir::Constness::Const),
285293
query_mode: TraitQueryMode::Standard,
294+
is_suggestion: false,
286295
}
287296
}
288297

298+
pub fn with_suggestion(
299+
infcx: &'cx InferCtxt<'cx, 'tcx>,
300+
suggestion: bool,
301+
) -> SelectionContext<'cx, 'tcx> {
302+
SelectionContext {
303+
infcx,
304+
freshener: infcx.freshener_keep_static(),
305+
intercrate: false,
306+
intercrate_ambiguity_causes: None,
307+
allow_negative_impls: false,
308+
is_in_const_context: false,
309+
query_mode: TraitQueryMode::Standard,
310+
is_suggestion: suggestion,
311+
}
312+
}
313+
314+
/// Enable suggestion mode for use during error reporting selection contexts
315+
/// to prevent reporting overflow errors during method suggestions
316+
pub fn is_suggestion(&mut self, suggestion: bool) {
317+
self.is_suggestion = suggestion;
318+
}
289319
/// Enables tracking of intercrate ambiguity causes. These are
290320
/// used in coherence to give improved diagnostics. We don't do
291321
/// this until we detect a coherence error because it can lead to
@@ -1093,7 +1123,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10931123
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
10941124
match self.query_mode {
10951125
TraitQueryMode::Standard => {
1096-
if self.infcx.is_tainted_by_errors() {
1126+
if self.is_suggestion {
10971127
return Err(OverflowError::ErrorReporting);
10981128
}
10991129
self.infcx.report_overflow_error(error_obligation, true);

compiler/rustc_typeck/src/check/demand.rs

-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
143143
Err(e) => e,
144144
};
145145

146-
self.set_tainted_by_errors();
147146
let expr = expr.peel_drop_temps();
148147
let cause = self.misc(expr.span);
149148
let expr_ty = self.resolve_vars_with_obligations(checked_ty);

compiler/rustc_typeck/src/check/method/probe.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
262262
"probe(self_ty={:?}, return_type={}, scope_expr_id={})",
263263
self_ty, return_type, scope_expr_id
264264
);
265+
self.set_tainted_by_errors();
265266
let method_names = self
266267
.probe_op(
267268
span,
@@ -1469,7 +1470,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14691470
let cause = traits::ObligationCause::misc(self.span, self.body_id);
14701471
let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate();
14711472
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
1472-
traits::SelectionContext::new(self).select(&obligation)
1473+
traits::SelectionContext::with_suggestion(self, self.is_suggestion.0).select(&obligation)
14731474
}
14741475

14751476
fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource {
@@ -1521,7 +1522,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15211522
let mut xform_ret_ty = probe.xform_ret_ty;
15221523
debug!(?xform_ret_ty);
15231524

1524-
let selcx = &mut traits::SelectionContext::new(self);
1525+
let selcx = &mut traits::SelectionContext::with_suggestion(self, self.is_suggestion.0);
15251526
let cause = traits::ObligationCause::misc(self.span, self.body_id);
15261527

15271528
// If so, impls may carry other conditions (e.g., where

src/test/ui/typeck/issue-90319.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
struct Wrapper<T>(T);
2+
3+
trait Trait {
4+
fn method(&self) {}
5+
}
6+
7+
impl<'a, T> Trait for Wrapper<&'a T> where Wrapper<T>: Trait {}
8+
9+
fn get<T>() -> T {
10+
unimplemented!()
11+
}
12+
13+
fn main() {
14+
let thing = get::<Thing>();//~ERROR 14:23: 14:28: cannot find type `Thing` in this scope [E0412]
15+
let wrapper = Wrapper(thing);
16+
Trait::method(&wrapper);//~ERROR 16:5: 16:18: overflow evaluating the requirement `_: Sized` [E0275]
17+
}

src/test/ui/typeck/issue-90319.stderr

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0412]: cannot find type `Thing` in this scope
2+
--> $DIR/issue-90319.rs:14:23
3+
|
4+
LL | let thing = get::<Thing>();
5+
| ^^^^^ not found in this scope
6+
7+
error[E0275]: overflow evaluating the requirement `_: Sized`
8+
--> $DIR/issue-90319.rs:16:5
9+
|
10+
LL | Trait::method(&wrapper);
11+
| ^^^^^^^^^^^^^
12+
|
13+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_90319`)
14+
note: required because of the requirements on the impl of `Trait` for `Wrapper<&_>`
15+
--> $DIR/issue-90319.rs:7:13
16+
|
17+
LL | impl<'a, T> Trait for Wrapper<&'a T> where Wrapper<T>: Trait {}
18+
| ^^^^^ ^^^^^^^^^^^^^^
19+
= note: 128 redundant requirements hidden
20+
= note: required because of the requirements on the impl of `Trait` for `Wrapper<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&_>`
21+
22+
error: aborting due to 2 previous errors
23+
24+
Some errors have detailed explanations: E0275, E0412.
25+
For more information about an error, try `rustc --explain E0275`.

0 commit comments

Comments
 (0)