Skip to content

Commit 6cf51ad

Browse files
authored
Rollup merge of rust-lang#67285 - ohadravid:indicate-origin-of-where-type-parameter, r=estebank
Indicate origin of where type parameter for uninferred types Based on rust-lang#65951 (which is not merge yet), fixes rust-lang#67277. This PR improves a little the diagnostic for code like: ``` async fn foo() { bar().await; } async fn bar<T>() -> () {} ``` by showing: ``` error[E0698]: type inside `async fn` body must be known in this context --> unresolved_type_param.rs:9:5 | 9 | bar().await; | ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ... ``` (The ``` declared on the function `bar` ``` part is new) A small side note: `Vec` and `slice` seem to resist this change, because querying `item_name()` panics, and `get_opt_name()` returns `None`. r? @estebank
2 parents 27a3576 + 8a4632d commit 6cf51ad

28 files changed

+97
-41
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

+65-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat};
33
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
44
use crate::infer::InferCtxt;
55
use crate::infer::type_variable::TypeVariableOriginKind;
6-
use crate::ty::{self, Ty, Infer, TyVar};
6+
use crate::ty::{self, Ty, Infer, TyVar, DefIdTree};
77
use crate::ty::print::Print;
88
use syntax::source_map::DesugaringKind;
99
use syntax::symbol::kw;
@@ -117,6 +117,8 @@ fn closure_return_type_suggestion(
117117
descr: &str,
118118
name: &str,
119119
ret: &str,
120+
parent_name: Option<String>,
121+
parent_descr: Option<&str>,
120122
) {
121123
let (arrow, post) = match output {
122124
FunctionRetTy::DefaultReturn(_) => ("-> ", " "),
@@ -138,7 +140,12 @@ fn closure_return_type_suggestion(
138140
suggestion,
139141
Applicability::HasPlaceholders,
140142
);
141-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
143+
err.span_label(span, InferCtxt::missing_type_msg(
144+
&name,
145+
&descr,
146+
parent_name,
147+
parent_descr
148+
));
142149
}
143150

144151
/// Given a closure signature, return a `String` containing a list of all its argument types.
@@ -177,16 +184,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
177184
&self,
178185
ty: Ty<'tcx>,
179186
highlight: Option<ty::print::RegionHighlightMode>,
180-
) -> (String, Option<Span>, Cow<'static, str>) {
187+
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
181188
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
182189
let ty_vars = self.type_variables.borrow();
183190
let var_origin = ty_vars.var_origin(ty_vid);
184-
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
191+
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
192+
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
193+
let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id {
194+
let parent_name = self.tcx.def_key(parent_def_id).disambiguated_data.data
195+
.get_opt_name().map(|parent_symbol| parent_symbol.to_string());
196+
197+
let type_parent_desc = self.tcx.def_kind(parent_def_id)
198+
.map(|parent_def_kind| parent_def_kind.descr(parent_def_id));
199+
200+
(parent_name, type_parent_desc)
201+
} else {
202+
(None, None)
203+
};
204+
185205
if name != kw::SelfUpper {
186206
return (
187207
name.to_string(),
188208
Some(var_origin.span),
189209
"type parameter".into(),
210+
parent_name,
211+
parent_desc,
190212
);
191213
}
192214
}
@@ -198,7 +220,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
198220
printer.region_highlight_mode = highlight;
199221
}
200222
let _ = ty.print(printer);
201-
(s, None, ty.prefix_string())
223+
(s, None, ty.prefix_string(), None, None)
202224
}
203225

204226
pub fn need_type_info_err(
@@ -209,7 +231,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
209231
error_code: TypeAnnotationNeeded,
210232
) -> DiagnosticBuilder<'tcx> {
211233
let ty = self.resolve_vars_if_possible(&ty);
212-
let (name, name_sp, descr) = self.extract_type_name(&ty, None);
234+
let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
235+
213236

214237
let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
215238
let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -218,7 +241,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
218241
let ty_vars = self.type_variables.borrow();
219242
let getter = move |ty_vid| {
220243
let var_origin = ty_vars.var_origin(ty_vid);
221-
if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
244+
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind {
222245
return Some(name.to_string());
223246
}
224247
None
@@ -317,6 +340,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
317340
&descr,
318341
&name,
319342
&ret,
343+
parent_name,
344+
parent_descr,
320345
);
321346
// We don't want to give the other suggestions when the problem is the
322347
// closure return type.
@@ -433,8 +458,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
433458
if !err.span.span_labels().iter().any(|span_label| {
434459
span_label.label.is_some() && span_label.span == span
435460
}) && local_visitor.found_arg_pattern.is_none()
436-
{ // Avoid multiple labels pointing at `span`.
437-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
461+
{
462+
// Avoid multiple labels pointing at `span`.
463+
err.span_label(
464+
span,
465+
InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)
466+
);
438467
}
439468

440469
err
@@ -496,19 +525,42 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
496525
ty: Ty<'tcx>,
497526
) -> DiagnosticBuilder<'tcx> {
498527
let ty = self.resolve_vars_if_possible(&ty);
499-
let (name, _, descr) = self.extract_type_name(&ty, None);
528+
let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None);
529+
500530
let mut err = struct_span_err!(
501531
self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
502532
);
503-
err.span_label(span, InferCtxt::missing_type_msg(&name, &descr));
533+
err.span_label(span, InferCtxt::missing_type_msg(
534+
&name,
535+
&descr,
536+
parent_name,
537+
parent_descr
538+
));
504539
err
505540
}
506541

507-
fn missing_type_msg(type_name: &str, descr: &str) -> Cow<'static, str>{
542+
fn missing_type_msg(
543+
type_name: &str,
544+
descr: &str,
545+
parent_name: Option<String>,
546+
parent_descr: Option<&str>,
547+
) -> Cow<'static, str> {
508548
if type_name == "_" {
509549
"cannot infer type".into()
510550
} else {
511-
format!("cannot infer type for {} `{}`", descr, type_name).into()
551+
let parent_desc = if let Some(parent_name) = parent_name {
552+
let parent_type_descr = if let Some(parent_descr) = parent_descr {
553+
format!(" the {}", parent_descr)
554+
} else {
555+
"".into()
556+
};
557+
558+
format!(" declared on{} `{}`", parent_type_descr, parent_name)
559+
} else {
560+
"".to_string()
561+
};
562+
563+
format!("cannot infer type for {} `{}`{}", descr, type_name, parent_desc).into()
512564
}
513565
}
514566
}

src/librustc/infer/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11351135
self.universe(),
11361136
false,
11371137
TypeVariableOrigin {
1138-
kind: TypeVariableOriginKind::TypeParameterDefinition(param.name),
1138+
kind: TypeVariableOriginKind::TypeParameterDefinition(
1139+
param.name,
1140+
Some(param.def_id)
1141+
),
11391142
span,
11401143
},
11411144
);

src/librustc/infer/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
124124
if let ty::TyVar(ty_vid) = infer_ty {
125125
let ty_vars = self.infcx.type_variables.borrow();
126126
if let TypeVariableOrigin {
127-
kind: TypeVariableOriginKind::TypeParameterDefinition(_),
127+
kind: TypeVariableOriginKind::TypeParameterDefinition(_, _),
128128
span,
129129
} = *ty_vars.var_origin(ty_vid)
130130
{

src/librustc/infer/type_variable.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use syntax::symbol::Symbol;
22
use syntax_pos::Span;
33
use crate::ty::{self, Ty, TyVid};
4+
use crate::hir::def_id::DefId;
45

56
use std::cmp;
67
use std::marker::PhantomData;
@@ -49,7 +50,7 @@ pub enum TypeVariableOriginKind {
4950
MiscVariable,
5051
NormalizeProjectionType,
5152
TypeInference,
52-
TypeParameterDefinition(Symbol),
53+
TypeParameterDefinition(Symbol, Option<DefId>),
5354

5455
/// One of the upvars or closure kind parameters in a `ClosureSubsts`
5556
/// (before it has been determined).

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2113,7 +2113,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
21132113
self.var_map.entry(ty).or_insert_with(||
21142114
infcx.next_ty_var(
21152115
TypeVariableOrigin {
2116-
kind: TypeVariableOriginKind::TypeParameterDefinition(name),
2116+
kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
21172117
span: DUMMY_SP,
21182118
}
21192119
)

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 type parameter `T`
5+
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
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/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 type parameter `T`
33+
| ^^^^^^^ cannot infer type for type parameter `T` declared on the function `generic`
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 type parameter `T`
5+
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
66

77
error[E0282]: type annotations needed
88
--> $DIR/issue-64662.rs:3:9
99
|
1010
LL | B = foo(),
11-
| ^^^ cannot infer type for type parameter `T`
11+
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
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 type parameter `U`
39+
| ^^^^ cannot infer type for type parameter `U` declared on the function `bfnr`
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 type parameter `H`
5+
| ^^^^^^^^^^^^ cannot infer type for type parameter `H` declared on the trait `StreamHash`
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 type parameter `M`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic`
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 type parameter `T`
5+
| --- ^ cannot infer type for type parameter `T` declared on the struct `B`
66
| |
77
| consider giving `foo` the explicit type `B<T>`, where the type parameter `T` is specified
88

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 type parameter `T`
8+
| ^^^ cannot infer type for type parameter `T` declared on the struct `Foo`
99

1010
error: aborting due to previous error
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 type parameter `T`
5+
| ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`
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 type parameter `T`
5+
| ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`
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 type parameter `U`
5+
| ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute`
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 type parameter `State`
5+
| ^^^ cannot infer type for type parameter `State` declared on the function `foo`
66

77
error: aborting due to previous error
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 type parameter `X`
5+
| ^^^ cannot infer type for type parameter `X` declared on the function `foo`
66

77
error: aborting due to previous error
88

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 type parameter `S`
7+
| cannot infer type for type parameter `S` declared on the method `sum`
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 type parameter `U`
5+
| ^^^^ cannot infer type for type parameter `U` declared on the function `test`
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 type parameter `F`
7+
| cannot infer type for type parameter `F` declared on the method `or_else`
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 type parameter `K`
7+
| cannot infer type for type parameter `K` declared on the method `sort_by_key`
88

99
error: aborting due to previous error
1010

src/test/ui/type-inference/unbounded-associated-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | S(std::marker::PhantomData).foo();
88
| ^--------------------------------
99
| |
1010
| this method call resolves to `<Self as T>::A`
11-
| cannot infer type for type parameter `X`
11+
| cannot infer type for type parameter `X` declared on the struct `S`
1212

1313
error: aborting due to previous error
1414

src/test/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:8:5
33
|
44
LL | foo();
5-
| ^^^ cannot infer type for type parameter `T`
5+
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
66

77
error: aborting due to previous error
88

src/test/ui/type-inference/unbounded-type-param-in-fn.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
22
--> $DIR/unbounded-type-param-in-fn.rs:6:5
33
|
44
LL | foo();
5-
| ^^^ cannot infer type for type parameter `T`
5+
| ^^^ cannot infer type for type parameter `T` declared on the function `foo`
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)