Skip to content

Commit da023c0

Browse files
committed
Add more context for type parameters
1 parent 45550ef commit da023c0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+128
-51
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use syntax::source_map::DesugaringKind;
99
use syntax::symbol::kw;
1010
use syntax_pos::Span;
1111
use errors::{Applicability, DiagnosticBuilder};
12+
use std::borrow::Cow;
1213

1314
use rustc_error_codes::*;
1415

@@ -113,6 +114,7 @@ fn closure_return_type_suggestion(
113114
err: &mut DiagnosticBuilder<'_>,
114115
output: &FunctionRetTy,
115116
body: &Body,
117+
descr: &str,
116118
name: &str,
117119
ret: &str,
118120
) {
@@ -136,7 +138,7 @@ fn closure_return_type_suggestion(
136138
suggestion,
137139
Applicability::HasPlaceholders,
138140
);
139-
err.span_label(span, InferCtxt::missing_type_msg(&name));
141+
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
140142
}
141143

142144
/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -175,13 +177,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
175177
&self,
176178
ty: Ty<'tcx>,
177179
highlight: Option<ty::print::RegionHighlightMode>,
178-
) -> (String, Option<Span>) {
180+
) -> (String, Option<Span>, Cow<'static, str>) {
179181
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
180182
let ty_vars = self.type_variables.borrow();
181183
let var_origin = ty_vars.var_origin(ty_vid);
182184
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
183185
if name != kw::SelfUpper {
184-
return (name.to_string(), Some(var_origin.span));
186+
return (
187+
name.to_string(),
188+
Some(var_origin.span),
189+
"type parameter".into(),
190+
);
185191
}
186192
}
187193
}
@@ -192,7 +198,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
192198
printer.region_highlight_mode = highlight;
193199
}
194200
let _ = ty.print(printer);
195-
(s, None)
201+
(s, None, ty.prefix_string())
196202
}
197203

198204
pub fn need_type_info_err(
@@ -203,7 +209,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
203209
error_code: TypeAnnotationNeeded,
204210
) -> DiagnosticBuilder<'tcx> {
205211
let ty = self.resolve_vars_if_possible(&ty);
206-
let (name, name_sp) = self.extract_type_name(&ty, None);
212+
let (name, name_sp, descr) = self.extract_type_name(&ty, None);
207213

208214
let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
209215
let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -308,6 +314,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
308314
&mut err,
309315
&decl.output,
310316
&body,
317+
&descr,
311318
&name,
312319
&ret,
313320
);
@@ -427,7 +434,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
427434
span_label.label.is_some() && span_label.span == span
428435
}) && local_visitor.found_arg_pattern.is_none()
429436
{ // Avoid multiple labels pointing at `span`.
430-
err.span_label(span, InferCtxt::missing_type_msg(&name));
437+
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
431438
}
432439

433440
err
@@ -468,10 +475,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
468475
);
469476
} else {
470477
let sig = self.tcx.fn_sig(did);
471-
err.span_label(e.span, &format!(
472-
"this method call resolves to `{:?}`",
473-
sig.output().skip_binder(),
474-
));
478+
let bound_output = sig.output();
479+
let output = bound_output.skip_binder();
480+
err.span_label(e.span, &format!("this method call resolves to `{:?}`", output));
481+
let kind = &output.kind;
482+
if let ty::Projection(proj) | ty::UnnormalizedProjection(proj) = kind {
483+
if let Some(span) = self.tcx.hir().span_if_local(proj.item_def_id) {
484+
err.span_label(span, &format!("`{:?}` defined here", output));
485+
}
486+
}
475487
}
476488
}
477489
}
@@ -484,19 +496,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
484496
ty: Ty<'tcx>,
485497
) -> DiagnosticBuilder<'tcx> {
486498
let ty = self.resolve_vars_if_possible(&ty);
487-
let name = self.extract_type_name(&ty, None).0;
499+
let (name, _, descr) = self.extract_type_name(&ty, None);
488500
let mut err = struct_span_err!(
489501
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
490502
);
491-
err.span_label(span, InferCtxt::missing_type_msg(&name));
503+
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
492504
err
493505
}
494506

495-
fn missing_type_msg(type_name: &str) -> String {
507+
fn missing_type_msg(type_name: &str, descr: &str) -> Cow<'static, str>{
496508
if type_name == "_" {
497-
"cannot infer type".to_owned()
509+
"cannot infer type".into()
498510
} else {
499-
format!("cannot infer type for `{}`", type_name)
511+
format!("cannot infer type for {} `{}`", descr, type_name).into()
500512
}
501513
}
502514
}

src/test/ui/associated-types/associated-types-overridden-binding.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0284]: type annotations needed
44
LL | trait Foo: Iterator<Item = i32> {}
55
| ------------------------------- required by `Foo`
66
LL | trait Bar: Foo<Item = u32> {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `Self`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
88
|
99
= note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
1010

@@ -14,7 +14,7 @@ error[E0284]: type annotations needed
1414
LL | trait I32Iterator = Iterator<Item = i32>;
1515
| ----------------------------------------- required by `I32Iterator`
1616
LL | trait U32Iterator = I32Iterator<Item = u32>;
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `Self`
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Self`
1818
|
1919
= note: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
2020

src/test/ui/async-await/unresolved_type_param.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ async fn bar<T>() -> () {}
88
async fn foo() {
99
bar().await;
1010
//~^ ERROR type inside `async fn` body must be known in this context
11-
//~| NOTE cannot infer type for `T`
11+
//~| NOTE cannot infer type for type parameter `T`
1212
//~| NOTE the type is part of the `async fn` body because of this `await`
1313
//~| NOTE in this expansion of desugaring of `await`
1414
}

src/test/ui/async-await/unresolved_type_param.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0698]: type inside `async fn` body must be known in this context
22
--> $DIR/unresolved_type_param.rs:9:5
33
|
44
LL | bar().await;
5-
| ^^^ cannot infer type for `T`
5+
| ^^^ cannot infer type for type parameter `T`
66
|
77
note: the type is part of the `async fn` body because of this `await`
88
--> $DIR/unresolved_type_param.rs:9:5

src/test/ui/const-generics/cannot-infer-const-args.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error[E0282]: type annotations needed
1010
--> $DIR/cannot-infer-const-args.rs:9:5
1111
|
1212
LL | foo();
13-
| ^^^ cannot infer type for `fn() -> usize {foo::<_: usize>}`
13+
| ^^^ cannot infer type for fn item `fn() -> usize {foo::<_: usize>}`
1414

1515
error: aborting due to previous error
1616

src/test/ui/const-generics/fn-const-param-infer.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ error[E0282]: type annotations needed
3030
--> $DIR/fn-const-param-infer.rs:22:23
3131
|
3232
LL | let _ = Checked::<generic>;
33-
| ^^^^^^^ cannot infer type for `T`
33+
| ^^^^^^^ cannot infer type for type parameter `T`
3434

3535
error[E0308]: mismatched types
3636
--> $DIR/fn-const-param-infer.rs:25:40

src/test/ui/consts/issue-64662.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-64662.rs:2:9
33
|
44
LL | A = foo(),
5-
| ^^^ cannot infer type for `T`
5+
| ^^^ cannot infer type for type parameter `T`
66

77
error[E0282]: type annotations needed
88
--> $DIR/issue-64662.rs:3:9
99
|
1010
LL | B = foo(),
11-
| ^^^ cannot infer type for `T`
11+
| ^^^ cannot infer type for type parameter `T`
1212

1313
error: aborting due to 2 previous errors
1414

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ error[E0282]: type annotations needed
3636
--> $DIR/E0401.rs:11:5
3737
|
3838
LL | bfnr(x);
39-
| ^^^^ cannot infer type for `U`
39+
| ^^^^ cannot infer type for type parameter `U`
4040

4141
error: aborting due to 4 previous errors
4242

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0284]: type annotations needed
22
--> $DIR/issue-12028.rs:27:14
33
|
44
LL | self.input_stream(&mut stream);
5-
| ^^^^^^^^^^^^ cannot infer type for `H`
5+
| ^^^^^^^^^^^^ cannot infer type for type parameter `H`
66
|
77
= note: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-16966.rs:2:5
33
|
44
LL | panic!(std::default::Default::default());
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `M`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M`
66
|
77
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `B<T>`
22
--> $DIR/issue-17551.rs:6:15
33
|
44
LL | let foo = B(marker::PhantomData);
5-
| --- ^ cannot infer type for `T`
5+
| --- ^ cannot infer type for type parameter `T`
66
| |
77
| consider giving `foo` the explicit type `B<T>`, where the type parameter `T` is specified
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | | {
1111
LL | | x.foo();
1212
LL | | y.foo();
1313
LL | | }
14-
| |_^ cannot infer type for `&'a T`
14+
| |_^ cannot infer type for reference `&'a T`
1515
|
1616
= note: cannot resolve `&'a T: Foo`
1717

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ 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-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for `T0`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T0`
99
|
1010
= note: cannot resolve `T0: Trait0<'l0>`
1111

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let (tx, rx) = channel();
55
| -------- consider giving this pattern the explicit type `(std::sync::mpsc::Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`, where the type parameter `T` is specified
66
...
77
LL | tx.send(Foo{ foo: PhantomData });
8-
| ^^^ cannot infer type for `T`
8+
| ^^^ cannot infer type for type parameter `T`
99

1010
error: aborting due to previous error
1111

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | trait Foo { fn xxx(&self); }
55
| -------------- required by `Foo::xxx`
66
...
77
LL | let _ = <S5<_>>::xxx;
8-
| ^^^^^^^^^^^^ cannot infer type for `S5<_>`
8+
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
99
|
1010
= note: cannot resolve `S5<_>: Foo`
1111

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-5062.rs:1:29
33
|
44
LL | fn main() { format!("{:?}", None); }
5-
| ^^^^ cannot infer type for `T`
5+
| ^^^^ cannot infer type for type parameter `T`
66

77
error: aborting due to previous error
88

src/test/ui/issues/issue-6458-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-6458-2.rs:3:21
33
|
44
LL | format!("{:?}", None);
5-
| ^^^^ cannot infer type for `T`
5+
| ^^^^ cannot infer type for type parameter `T`
66

77
error: aborting due to previous error
88

src/test/ui/issues/issue-6458-3.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-6458-3.rs:4:5
33
|
44
LL | mem::transmute(0);
5-
| ^^^^^^^^^^^^^^ cannot infer type for `U`
5+
| ^^^^^^^^^^^^^^ cannot infer type for type parameter `U`
66

77
error: aborting due to previous error
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/issue-6458.rs:9:4
33
|
44
LL | foo(TypeWithState(marker::PhantomData));
5-
| ^^^ cannot infer type for `State`
5+
| ^^^ cannot infer type for type parameter `State`
66

77
error: aborting due to previous error
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
44
LL | let x = buffer.last().unwrap().0.clone();
55
| -------^^^^--
66
| | |
7-
| | cannot infer type for `T`
7+
| | cannot infer type for type parameter `T`
88
| this method call resolves to `std::option::Option<&T>`
99
|
1010
= note: type must be known at this point

src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `std::vec::Vec<T>`
22
--> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17
33
|
44
LL | let mut x = Vec::new();
5-
| ----- ^^^^^^^^ cannot infer type for `T`
5+
| ----- ^^^^^^^^ cannot infer type for type parameter `T`
66
| |
77
| consider giving `x` the explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified
88

src/test/ui/missing/missing-items/missing-type-parameter.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/missing-type-parameter.rs:4:5
33
|
44
LL | foo();
5-
| ^^^ cannot infer type for `X`
5+
| ^^^ cannot infer type for type parameter `X`
66

77
error: aborting due to previous error
88

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `std::option::Option<_>`
44
LL | let x: Option<_> = None;
55
| - consider giving `x` the explicit type `std::option::Option<_>`, where the type parameter `T` is specified
66
LL | x.unwrap().method_that_could_exist_on_some_type();
7-
| ^^^^^^ cannot infer type for `T`
7+
| ^^^^^^ cannot infer type for type parameter `T`
88
|
99
= note: type must be known at this point
1010

src/test/ui/span/type-annotations-needed-expr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
44
LL | let _ = (vec![1,2,3]).into_iter().sum() as f64;
55
| ^^^
66
| |
7-
| cannot infer type for `S`
7+
| cannot infer type for type parameter `S`
88
| help: consider specifying the type argument in the method call: `sum::<S>`
99
|
1010
= note: type must be known at this point

src/test/ui/traits/traits-multidispatch-convert-ambig-dest.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/traits-multidispatch-convert-ambig-dest.rs:26:5
33
|
44
LL | test(22, std::default::Default::default());
5-
| ^^^^ cannot infer type for `U`
5+
| ^^^^ cannot infer type for type parameter `U`
66

77
error: aborting due to previous error
88

src/test/ui/type-inference/or_else-multiple-type-params.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
44
LL | .or_else(|err| {
55
| ^^^^^^^
66
| |
7-
| cannot infer type for `F`
7+
| cannot infer type for type parameter `F`
88
| help: consider specifying the type arguments in the method call: `or_else::<F, O>`
99

1010
error: aborting due to previous error

src/test/ui/type-inference/sort_by_key.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
44
LL | lst.sort_by_key(|&(v, _)| v.iter().sum());
55
| ^^^^^^^^^^^ --- help: consider specifying the type argument in the method call: `sum::<S>`
66
| |
7-
| cannot infer type for `K`
7+
| cannot infer type for type parameter `K`
88

99
error: aborting due to previous error
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait T {
2+
type A;
3+
fn foo(&self) -> Self::A {
4+
panic!()
5+
}
6+
}
7+
8+
struct S<X>(std::marker::PhantomData<X>);
9+
10+
impl<X> T for S<X> {
11+
type A = X;
12+
}
13+
14+
fn main() {
15+
S(std::marker::PhantomData).foo(); //~ ERROR type annotations needed
16+
}

0 commit comments

Comments
 (0)