Skip to content

Commit 7c7941d

Browse files
Rollup merge of #50712 - leodasvacas:improve-eager-resolution-error-message, r=estebank
Improve eager type resolution error message This PR improves the span of eager resolution type errors referring to indexing and field access to use the base span rather than the whole expression. Also a "note: type must be known at this point" is added where in the past we emitted the "type must be known at this context" error, so that early failures can be differentiated and will hopefully be less surprising. Fixes #50692 (or at least does the best we can for the moment) r? @estebank
2 parents 6dc4971 + 8789056 commit 7c7941d

File tree

7 files changed

+70
-11
lines changed

7 files changed

+70
-11
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use infer::InferCtxt;
1414
use infer::type_variable::TypeVariableOrigin;
1515
use ty::{self, Ty, TyInfer, TyVar};
1616
use syntax_pos::Span;
17+
use errors::DiagnosticBuilder;
1718

1819
struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
1920
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
@@ -86,7 +87,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
8687
}
8788
}
8889

89-
pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) {
90+
pub fn need_type_info_err(&self,
91+
body_id: Option<hir::BodyId>,
92+
span: Span,
93+
ty: Ty<'tcx>)
94+
-> DiagnosticBuilder<'gcx> {
9095
let ty = self.resolve_type_vars_if_possible(&ty);
9196
let name = self.extract_type_name(&ty);
9297

@@ -142,6 +147,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
142147
err.span_label(target_span, label_message);
143148
}
144149

145-
err.emit();
150+
err
146151
}
147152
}

src/librustc/traits/error_reporting.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12341234
self.tcx.lang_items().sized_trait()
12351235
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
12361236
{
1237-
self.need_type_info(body_id, span, self_ty);
1237+
self.need_type_info_err(body_id, span, self_ty).emit();
12381238
} else {
12391239
let mut err = struct_span_err!(self.tcx.sess,
12401240
span, E0283,
@@ -1251,7 +1251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12511251
// Same hacky approach as above to avoid deluging user
12521252
// with error messages.
12531253
if !ty.references_error() && !self.tcx.sess.has_errors() {
1254-
self.need_type_info(body_id, span, ty);
1254+
self.need_type_info_err(body_id, span, ty).emit();
12551255
}
12561256
}
12571257

@@ -1262,9 +1262,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12621262
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
12631263
// both must be type variables, or the other would've been instantiated
12641264
assert!(a.is_ty_var() && b.is_ty_var());
1265-
self.need_type_info(body_id,
1266-
obligation.cause.span,
1267-
a);
1265+
self.need_type_info_err(body_id,
1266+
obligation.cause.span,
1267+
a).emit();
12681268
}
12691269
}
12701270

src/librustc_typeck/check/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30673067
base: &'gcx hir::Expr,
30683068
field: &Spanned<ast::Name>) -> Ty<'tcx> {
30693069
let expr_t = self.check_expr_with_needs(base, needs);
3070-
let expr_t = self.structurally_resolved_type(expr.span,
3070+
let expr_t = self.structurally_resolved_type(base.span,
30713071
expr_t);
30723072
let mut private_candidate = None;
30733073
let mut autoderef = self.autoderef(expr.span, expr_t);
@@ -4088,7 +4088,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
40884088
} else if idx_t.references_error() {
40894089
idx_t
40904090
} else {
4091-
let base_t = self.structurally_resolved_type(expr.span, base_t);
4091+
let base_t = self.structurally_resolved_type(base.span, base_t);
40924092
match self.lookup_indexing(expr, base, base_t, idx_t, needs) {
40934093
Some((index_ty, element_ty)) => {
40944094
// two-phase not needed because index_ty is never mutable
@@ -5061,7 +5061,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50615061
ty
50625062
} else {
50635063
if !self.is_tainted_by_errors() {
5064-
self.need_type_info((**self).body_id, sp, ty);
5064+
self.need_type_info_err((**self).body_id, sp, ty)
5065+
.note("type must be known at this point")
5066+
.emit();
50655067
}
50665068
self.demand_suptype(sp, self.tcx.types.err, ty);
50675069
self.tcx.types.err

src/librustc_typeck/check/writeback.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
593593
fn report_error(&self, t: Ty<'tcx>) {
594594
if !self.tcx.sess.has_errors() {
595595
self.infcx
596-
.need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
596+
.need_type_info_err(Some(self.body.id()), self.span.to_span(&self.tcx), t).emit();
597597
}
598598
}
599599
}

src/test/ui/span/issue-42234-unknown-receiver-type.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ LL | let x: Option<_> = None;
55
| - consider giving `x` a type
66
LL | x.unwrap().method_that_could_exist_on_some_type();
77
| ^^^^^^^^^^ cannot infer type for `T`
8+
|
9+
= note: type must be known at this point
810

911
error[E0282]: type annotations needed
1012
--> $DIR/issue-42234-unknown-receiver-type.rs:22:5
1113
|
1214
LL | / data.iter() //~ ERROR 22:5: 23:20: type annotations needed
1315
LL | | .sum::<_>()
1416
| |___________________^ cannot infer type for `_`
17+
|
18+
= note: type must be known at this point
1519

1620
error: aborting due to 2 previous errors
1721

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that spans get only base in eager type resolution (structurally_resolve_type).
12+
13+
fn main() {
14+
let mut x = Default::default();
15+
x.0;
16+
//~^ ERROR type annotations needed
17+
x = 1;
18+
}
19+
20+
fn foo() {
21+
let mut x = Default::default();
22+
x[0];
23+
//~^ ERROR type annotations needed
24+
x = 1;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/method-and-field-eager-resolution.rs:15:5
3+
|
4+
LL | let mut x = Default::default();
5+
| ----- consider giving `x` a type
6+
LL | x.0;
7+
| ^ cannot infer type for `_`
8+
|
9+
= note: type must be known at this point
10+
11+
error[E0282]: type annotations needed
12+
--> $DIR/method-and-field-eager-resolution.rs:22:5
13+
|
14+
LL | let mut x = Default::default();
15+
| ----- consider giving `x` a type
16+
LL | x[0];
17+
| ^ cannot infer type for `_`
18+
|
19+
= note: type must be known at this point
20+
21+
error: aborting due to 2 previous errors
22+
23+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)