Skip to content

Commit 252773a

Browse files
committed
Deduplicate logic
1 parent 12af256 commit 252773a

21 files changed

+121
-78
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ use std::{cmp, fmt};
7070
mod note;
7171

7272
mod need_type_info;
73+
pub use need_type_info::TypeAnnotationNeeded;
7374

7475
pub mod nice_region_error;
7576

src/librustc/infer/error_reporting/need_type_info.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,25 @@ fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String {
151151
.unwrap_or_default()
152152
}
153153

154+
pub enum TypeAnnotationNeeded {
155+
E0282,
156+
E0283,
157+
E0284,
158+
}
159+
160+
impl Into<errors::DiagnosticId> for TypeAnnotationNeeded {
161+
fn into(self) -> errors::DiagnosticId {
162+
syntax::diagnostic_used!(E0282);
163+
syntax::diagnostic_used!(E0283);
164+
syntax::diagnostic_used!(E0284);
165+
errors::DiagnosticId::Error(match self {
166+
Self::E0282 => "E0282".to_string(),
167+
Self::E0283 => "E0283".to_string(),
168+
Self::E0284 => "E0284".to_string(),
169+
})
170+
}
171+
}
172+
154173
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
155174
pub fn extract_type_name(
156175
&self,
@@ -181,7 +200,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
181200
body_id: Option<hir::BodyId>,
182201
span: Span,
183202
ty: Ty<'tcx>,
184-
is_projection: bool,
203+
error_code: TypeAnnotationNeeded,
185204
) -> DiagnosticBuilder<'tcx> {
186205
let ty = self.resolve_vars_if_possible(&ty);
187206
let (name, name_sp) = self.extract_type_name(&ty, None);
@@ -217,7 +236,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
217236
// 3 | let _ = x.sum() as f64;
218237
// | ^^^ cannot infer type for `S`
219238
span
220-
} else if let Some(ExprKind::MethodCall(_, call_span, _)) = local_visitor.found_method_call {
239+
} else if let Some(
240+
ExprKind::MethodCall(_, call_span, _),
241+
) = local_visitor.found_method_call {
221242
// Point at the call instead of the whole expression:
222243
// error[E0284]: type annotations needed
223244
// --> file.rs:2:5
@@ -268,11 +289,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
268289
// | consider giving `b` the explicit type `std::result::Result<i32, E>`, where
269290
// | the type parameter `E` is specified
270291
// ```
271-
let mut err = if is_projection {
272-
struct_span_err!(self.tcx.sess, err_span, E0284, "type annotations needed{}", ty_msg)
273-
} else {
274-
struct_span_err!(self.tcx.sess, err_span, E0282, "type annotations needed{}", ty_msg)
275-
};
292+
let error_code = error_code.into();
293+
let mut err = self.tcx.sess.struct_span_err_with_code(
294+
err_span,
295+
&format!("type annotations needed{}", ty_msg),
296+
error_code,
297+
);
276298

277299
let suffix = match local_visitor.found_ty {
278300
Some(ty::TyS { kind: ty::Closure(def_id, substs), .. }) => {

src/librustc/traits/error_reporting.rs

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::hir;
2222
use crate::hir::Node;
2323
use crate::hir::def_id::DefId;
2424
use crate::infer::{self, InferCtxt};
25+
use crate::infer::error_reporting::TypeAnnotationNeeded::*;
2526
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2627
use crate::session::DiagnosticMessageId;
2728
use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
@@ -1951,7 +1952,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
19511952
return;
19521953
}
19531954

1954-
match predicate {
1955+
let mut err = match predicate {
19551956
ty::Predicate::Trait(ref data) => {
19561957
let trait_ref = data.to_poly_trait_ref();
19571958
let self_ty = trait_ref.self_ty();
@@ -1985,73 +1986,64 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
19851986
// avoid inundating the user with unnecessary errors, but we now
19861987
// check upstream for type errors and dont add the obligations to
19871988
// begin with in those cases.
1988-
if
1989-
self.tcx.lang_items().sized_trait()
1989+
if self.tcx.lang_items().sized_trait()
19901990
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
19911991
{
1992-
self.need_type_info_err(body_id, span, self_ty, false).emit();
1993-
} else {
1994-
let mut err = struct_span_err!(
1995-
self.tcx.sess,
1996-
span,
1997-
E0283,
1998-
"type annotations needed: cannot resolve `{}`",
1999-
predicate,
2000-
);
2001-
self.note_obligation_cause(&mut err, obligation);
2002-
err.emit();
1992+
self.need_type_info_err(body_id, span, self_ty, E0282).emit();
1993+
return;
20031994
}
1995+
let mut err = self.need_type_info_err(body_id, span, self_ty, E0283);
1996+
err.note(&format!("cannot resolve `{}`", predicate));
1997+
err
20041998
}
20051999

20062000
ty::Predicate::WellFormed(ty) => {
20072001
// Same hacky approach as above to avoid deluging user
20082002
// with error messages.
2009-
if !ty.references_error() && !self.tcx.sess.has_errors() {
2010-
let mut err = self.need_type_info_err(body_id, span, ty, false);
2011-
self.note_obligation_cause(&mut err, obligation);
2012-
err.emit();
2003+
if ty.references_error() || self.tcx.sess.has_errors() {
2004+
return;
20132005
}
2006+
self.need_type_info_err(body_id, span, ty, E0282)
20142007
}
20152008

20162009
ty::Predicate::Subtype(ref data) => {
20172010
if data.references_error() || self.tcx.sess.has_errors() {
20182011
// no need to overload user in such cases
2019-
} else {
2020-
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
2021-
// both must be type variables, or the other would've been instantiated
2022-
assert!(a.is_ty_var() && b.is_ty_var());
2023-
let mut err = self.need_type_info_err(body_id, span, a, false);
2024-
self.note_obligation_cause(&mut err, obligation);
2025-
err.emit();
2012+
return
20262013
}
2014+
let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
2015+
// both must be type variables, or the other would've been instantiated
2016+
assert!(a.is_ty_var() && b.is_ty_var());
2017+
self.need_type_info_err(body_id, span, a, E0282)
20272018
}
20282019
ty::Predicate::Projection(ref data) => {
20292020
let trait_ref = data.to_poly_trait_ref(self.tcx);
20302021
let self_ty = trait_ref.self_ty();
20312022
if predicate.references_error() {
20322023
return;
20332024
}
2034-
let mut err = self.need_type_info_err(body_id, span, self_ty, true);
2025+
let mut err = self.need_type_info_err(body_id, span, self_ty, E0284);
20352026
err.note(&format!("cannot resolve `{}`", predicate));
2036-
self.note_obligation_cause(&mut err, obligation);
2037-
err.emit();
2027+
err
20382028
}
20392029

20402030
_ => {
2041-
if !self.tcx.sess.has_errors() {
2042-
let mut err = struct_span_err!(
2043-
self.tcx.sess,
2044-
span,
2045-
E0284,
2046-
"type annotations needed: cannot resolve `{}`",
2047-
predicate,
2048-
);
2049-
err.span_label(span, &format!("cannot resolve `{}`", predicate));
2050-
self.note_obligation_cause(&mut err, obligation);
2051-
err.emit();
2031+
if self.tcx.sess.has_errors() {
2032+
return;
20522033
}
2034+
let mut err = struct_span_err!(
2035+
self.tcx.sess,
2036+
span,
2037+
E0284,
2038+
"type annotations needed: cannot resolve `{}`",
2039+
predicate,
2040+
);
2041+
err.span_label(span, &format!("cannot resolve `{}`", predicate));
2042+
err
20532043
}
2054-
}
2044+
};
2045+
self.note_obligation_cause(&mut err, obligation);
2046+
err.emit();
20552047
}
20562048

20572049
/// Returns `true` if the trait predicate may apply for *some* assignment

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use rustc_index::vec::Idx;
103103
use rustc_target::spec::abi::Abi;
104104
use rustc::infer::opaque_types::OpaqueTypeDecl;
105105
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
106+
use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
106107
use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
107108
use rustc::middle::region;
108109
use rustc::mir::interpret::{ConstValue, GlobalId};
@@ -5359,7 +5360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
53595360
ty
53605361
} else {
53615362
if !self.is_tainted_by_errors() {
5362-
self.need_type_info_err((**self).body_id, sp, ty, false)
5363+
self.need_type_info_err((**self).body_id, sp, ty, E0282)
53635364
.note("type must be known at this point")
53645365
.emit();
53655366
}

src/librustc_typeck/check/writeback.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc::hir;
88
use rustc::hir::def_id::{DefId, DefIndex};
99
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
1010
use rustc::infer::InferCtxt;
11+
use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
1112
use rustc::ty::adjustment::{Adjust, Adjustment, PointerCast};
1213
use rustc::ty::fold::{TypeFoldable, TypeFolder};
1314
use rustc::ty::{self, Ty, TyCtxt};
@@ -717,7 +718,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
717718
fn report_error(&self, t: Ty<'tcx>) {
718719
if !self.tcx.sess.has_errors() {
719720
self.infcx
720-
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, false)
721+
.need_type_info_err(Some(self.body.id()), self.span.to_span(self.tcx), t, E0282)
721722
.emit();
722723
}
723724
}

src/test/ui/associated-const/issue-63496.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ trait A {
22
const C: usize;
33

44
fn f() -> ([u8; A::C], [u8; A::C]);
5-
//~^ ERROR: type annotations needed: cannot resolve
6-
//~| ERROR: type annotations needed: cannot resolve
5+
//~^ ERROR: type annotations needed
6+
//~| ERROR: type annotations needed
77
}
88

99
fn main() {}

src/test/ui/associated-const/issue-63496.stderr

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
error[E0283]: type annotations needed: cannot resolve `_: A`
1+
error[E0283]: type annotations needed
22
--> $DIR/issue-63496.rs:4:21
33
|
44
LL | const C: usize;
55
| --------------- required by `A::C`
66
LL |
77
LL | fn f() -> ([u8; A::C], [u8; A::C]);
8-
| ^^^^
8+
| ^^^^ cannot infer type
9+
|
10+
= note: cannot resolve `_: A`
911

10-
error[E0283]: type annotations needed: cannot resolve `_: A`
12+
error[E0283]: type annotations needed
1113
--> $DIR/issue-63496.rs:4:33
1214
|
1315
LL | const C: usize;
1416
| --------------- required by `A::C`
1517
LL |
1618
LL | fn f() -> ([u8; A::C], [u8; A::C]);
17-
| ^^^^
19+
| ^^^^ cannot infer type
20+
|
21+
= note: cannot resolve `_: A`
1822

1923
error: aborting due to 2 previous errors
2024

src/test/ui/associated-item/issue-48027.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ LL | const X: usize;
77
LL | impl dyn Bar {}
88
| ^^^^^^^ the trait `Bar` cannot be made into an object
99

10-
error[E0283]: type annotations needed: cannot resolve `_: Bar`
10+
error[E0283]: type annotations needed
1111
--> $DIR/issue-48027.rs:3:32
1212
|
1313
LL | const X: usize;
1414
| --------------- required by `Bar::X`
1515
LL | fn return_n(&self) -> [u8; Bar::X];
16-
| ^^^^^^
16+
| ^^^^^^ cannot infer type
17+
|
18+
= note: cannot resolve `_: Bar`
1719

1820
error: aborting due to 2 previous errors
1921

src/test/ui/error-codes/E0283.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
error[E0283]: type annotations needed: cannot resolve `_: Generator`
1+
error[E0283]: type annotations needed
22
--> $DIR/E0283.rs:18:21
33
|
44
LL | fn create() -> u32;
55
| ------------------- required by `Generator::create`
66
...
77
LL | let cont: u32 = Generator::create();
8-
| ^^^^^^^^^^^^^^^^^
8+
| ^^^^^^^^^^^^^^^^^ cannot infer type
9+
|
10+
= note: cannot resolve `_: Generator`
911

1012
error: aborting due to previous error
1113

src/test/ui/issues/issue-21974.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0283]: type annotations needed: cannot resolve `&'a T: Foo`
1+
error[E0283]: type annotations needed
22
--> $DIR/issue-21974.rs:10:1
33
|
44
LL | trait Foo {
@@ -11,7 +11,9 @@ LL | | {
1111
LL | | x.foo();
1212
LL | | y.foo();
1313
LL | | }
14-
| |_^
14+
| |_^ cannot infer type for `&'a T`
15+
|
16+
= note: cannot resolve `&'a T: Foo`
1517

1618
error: aborting due to previous error
1719

src/test/ui/issues/issue-24424.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ trait Trait1<'l0, T0> {}
22
trait Trait0<'l0> {}
33

44
impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
5-
//~^ ERROR type annotations needed: cannot resolve `T0: Trait0<'l0>`
5+
//~^ ERROR type annotations needed
66

77
fn main() {}

src/test/ui/issues/issue-24424.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
error[E0283]: type annotations needed: cannot resolve `T0: Trait0<'l0>`
1+
error[E0283]: type annotations needed
22
--> $DIR/issue-24424.rs:4:1
33
|
44
LL | trait Trait0<'l0> {}
55
| ----------------- required by `Trait0`
66
LL |
77
LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `T0`
9+
|
10+
= note: cannot resolve `T0: Trait0<'l0>`
911

1012
error: aborting due to previous error
1113

src/test/ui/issues/issue-29147.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ impl Foo for S5<u32> { fn xxx(&self) {} }
1818
impl Foo for S5<u64> { fn xxx(&self) {} }
1919

2020
fn main() {
21-
let _ = <S5<_>>::xxx; //~ ERROR cannot resolve `S5<_>: Foo`
21+
let _ = <S5<_>>::xxx; //~ ERROR type annotations needed
2222
}

src/test/ui/issues/issue-29147.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
error[E0283]: type annotations needed: cannot resolve `S5<_>: Foo`
1+
error[E0283]: type annotations needed
22
--> $DIR/issue-29147.rs:21:13
33
|
44
LL | trait Foo { fn xxx(&self); }
55
| -------------- required by `Foo::xxx`
66
...
77
LL | let _ = <S5<_>>::xxx;
8-
| ^^^^^^^^^^^^
8+
| ^^^^^^^^^^^^ cannot infer type for `S5<_>`
9+
|
10+
= note: cannot resolve `S5<_>: Foo`
911

1012
error: aborting due to previous error
1113

src/test/ui/issues/issue-54954.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ error[E0379]: trait fns cannot be declared const
44
LL | const fn const_val<T: Sized>() -> usize {
55
| ^^^^^ trait fns cannot be const
66

7-
error[E0283]: type annotations needed: cannot resolve `_: Tt`
7+
error[E0283]: type annotations needed
88
--> $DIR/issue-54954.rs:3:24
99
|
1010
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
1212
...
1313
LL | const fn const_val<T: Sized>() -> usize {
1414
| --------- - required by this bound in `Tt::const_val`
15+
|
16+
= note: cannot resolve `_: Tt`
1517

1618
error[E0080]: evaluation of constant value failed
1719
--> $DIR/issue-54954.rs:13:15

src/test/ui/issues/issue-58022.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub trait Foo: Sized {
22
const SIZE: usize;
33

44
fn new(slice: &[u8; Foo::SIZE]) -> Self;
5-
//~^ ERROR: type annotations needed: cannot resolve `_: Foo`
5+
//~^ ERROR: type annotations needed
66
}
77

88
pub struct Bar<T: ?Sized>(T);

0 commit comments

Comments
 (0)