@@ -15,7 +15,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
15
15
hir_map : & ' a hir:: map:: Map < ' gcx > ,
16
16
found_local_pattern : Option < & ' gcx Pat > ,
17
17
found_arg_pattern : Option < & ' gcx Pat > ,
18
- found_ty : Option < String > ,
18
+ found_ty : Option < Ty < ' tcx > > ,
19
19
}
20
20
21
21
impl < ' a , ' gcx , ' tcx > FindLocalByTypeVisitor < ' a , ' gcx , ' tcx > {
@@ -55,7 +55,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
55
55
fn visit_local ( & mut self , local : & ' gcx Local ) {
56
56
if let ( None , Some ( ty) ) = ( self . found_local_pattern , self . node_matches_type ( local. hir_id ) ) {
57
57
self . found_local_pattern = Some ( & * local. pat ) ;
58
- self . found_ty = Some ( ty. to_string ( ) ) ;
58
+ self . found_ty = Some ( ty) ;
59
59
}
60
60
intravisit:: walk_local ( self , local) ;
61
61
}
@@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
67
67
self . node_matches_type ( argument. hir_id ) ,
68
68
) {
69
69
self . found_arg_pattern = Some ( & * argument. pat ) ;
70
- self . found_ty = Some ( ty. to_string ( ) ) ;
70
+ self . found_ty = Some ( ty) ;
71
71
}
72
72
}
73
73
intravisit:: walk_body ( self , body) ;
@@ -117,14 +117,43 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
117
117
found_arg_pattern : None ,
118
118
found_ty : None ,
119
119
} ;
120
+ let ty_to_string = |ty : Ty < ' tcx > | -> String {
121
+ let mut s = String :: new ( ) ;
122
+ let mut printer = ty:: print:: FmtPrinter :: new ( self . tcx , & mut s, Namespace :: TypeNS ) ;
123
+ let ty_vars = self . type_variables . borrow ( ) ;
124
+ let getter = move |ty_vid| {
125
+ if let TypeVariableOrigin :: TypeParameterDefinition ( _, name) =
126
+ * ty_vars. var_origin ( ty_vid) {
127
+ return Some ( name. to_string ( ) ) ;
128
+ }
129
+ None
130
+ } ;
131
+ printer. name_resolver = Some ( Box :: new ( & getter) ) ;
132
+ let _ = ty. print ( printer) ;
133
+ s
134
+ } ;
120
135
121
136
if let Some ( body_id) = body_id {
122
137
let expr = self . tcx . hir ( ) . expect_expr_by_hir_id ( body_id. hir_id ) ;
123
138
local_visitor. visit_expr ( expr) ;
124
139
}
125
140
141
+ // When `name` corresponds to a type argument, show the path of the full type we're
142
+ // trying to infer. In the following example, `ty_msg` contains
143
+ // " in `std::result::Result<i32, E>`":
144
+ // ```
145
+ // error[E0282]: type annotations needed in `std::result::Result<i32, E>`
146
+ // --> file.rs:L:CC
147
+ // |
148
+ // L | let b = Ok(4);
149
+ // | - ^^ cannot infer type for `E` in `std::result::Result<i32, E>`
150
+ // | |
151
+ // | consider giving `b` a type
152
+ // ```
126
153
let ty_msg = match & local_visitor. found_ty {
127
- Some ( ty) if & ty[ ..] != "_" && ty != & name => format ! ( " in `{}`" , ty) ,
154
+ Some ( ty) if & ty. to_string ( ) != "_" && ty. to_string ( ) != name => {
155
+ format ! ( " in `{}`" , ty_to_string( ty) )
156
+ }
128
157
_ => String :: new ( ) ,
129
158
} ;
130
159
let mut labels = vec ! [ ( span, InferCtxt :: missing_type_msg( & name, & ty_msg) ) ] ;
@@ -144,17 +173,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
144
173
// After clearing, it looks something like this:
145
174
// ```
146
175
// let x = |_| { };
147
- // ^ consider giving this closure parameter a type
176
+ // ^ consider giving this closure parameter the type `[_; 0]`
177
+ // with the type parameter `_` specified
148
178
// ```
149
179
labels. clear ( ) ;
150
180
labels. push ( ( pattern. span , format ! (
151
181
"consider giving this closure parameter {}" ,
152
182
match & local_visitor. found_ty {
153
- Some ( ty) if & ty[ ..] != "_" && ty != & name => format!(
154
- "the type `{}` with the type parameter `{}` specified" ,
155
- ty,
156
- name,
157
- ) ,
183
+ Some ( ty) if & ty. to_string( ) != "_" && ty. to_string( ) != name => {
184
+ format!(
185
+ "the type `{}` with the type parameter `{}` specified" ,
186
+ ty_to_string( ty) ,
187
+ name,
188
+ )
189
+ }
158
190
_ => "a type" . to_owned( ) ,
159
191
} ,
160
192
) ) ) ;
0 commit comments