@@ -10,7 +10,7 @@ use rustc_middle::ty::adjustment::{
10
10
Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability ,
11
11
} ;
12
12
use rustc_middle:: ty:: TyKind :: { Adt , Array , Char , FnDef , Never , Ref , Str , Tuple , Uint } ;
13
- use rustc_middle:: ty:: { self , suggest_constraining_type_param, Ty , TypeFoldable } ;
13
+ use rustc_middle:: ty:: { self , suggest_constraining_type_param, Ty , TyCtxt , TypeFoldable } ;
14
14
use rustc_span:: Span ;
15
15
use rustc_trait_selection:: infer:: InferCtxtExt ;
16
16
@@ -254,49 +254,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
254
254
if !lhs_ty. references_error ( ) {
255
255
let source_map = self . tcx . sess . source_map ( ) ;
256
256
257
- let suggest_constraining_param =
258
- |mut err : & mut DiagnosticBuilder < ' _ > ,
259
- missing_trait : & str ,
260
- p : ty:: ParamTy ,
261
- set_output : bool | {
262
- let hir = self . tcx . hir ( ) ;
263
- let msg =
264
- & format ! ( "`{}` might need a bound for `{}`" , lhs_ty, missing_trait) ;
265
- if let Some ( def_id) = hir
266
- . find ( hir. get_parent_item ( expr. hir_id ) )
267
- . and_then ( |node| node. hir_id ( ) )
268
- . and_then ( |hir_id| hir. opt_local_def_id ( hir_id) )
269
- {
270
- let generics = self . tcx . generics_of ( def_id) ;
271
- let param_def_id = generics. type_param ( & p, self . tcx ) . def_id ;
272
- if let Some ( generics) = hir
273
- . as_local_hir_id ( param_def_id)
274
- . and_then ( |id| hir. find ( hir. get_parent_item ( id) ) )
275
- . as_ref ( )
276
- . and_then ( |node| node. generics ( ) )
277
- {
278
- let output = if set_output {
279
- format ! ( "<Output = {}>" , rhs_ty)
280
- } else {
281
- String :: new ( )
282
- } ;
283
- suggest_constraining_type_param (
284
- self . tcx ,
285
- generics,
286
- & mut err,
287
- & format ! ( "{}" , lhs_ty) ,
288
- & format ! ( "{}{}" , missing_trait, output) ,
289
- None ,
290
- ) ;
291
- } else {
292
- let span = self . tcx . def_span ( param_def_id) ;
293
- err. span_label ( span, msg) ;
294
- }
295
- } else {
296
- err. note ( & msg) ;
297
- }
298
- } ;
299
-
300
257
match is_assign {
301
258
IsAssign :: Yes => {
302
259
let mut err = struct_span_err ! (
@@ -362,7 +319,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362
319
// concatenation (e.g., "Hello " += "World!"). This means
363
320
// we don't want the note in the else clause to be emitted
364
321
} else if let ty:: Param ( p) = lhs_ty. kind {
365
- suggest_constraining_param ( & mut err, missing_trait, p, false ) ;
322
+ suggest_constraining_param (
323
+ self . tcx ,
324
+ & mut err,
325
+ lhs_ty,
326
+ rhs_ty,
327
+ & expr,
328
+ missing_trait,
329
+ p,
330
+ false ,
331
+ ) ;
366
332
} else if !suggested_deref {
367
333
suggest_impl_missing ( & mut err, lhs_ty, & missing_trait) ;
368
334
}
@@ -514,7 +480,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
514
480
// we don't want the note in the else clause to be emitted
515
481
} else if let ty:: Param ( p) = lhs_ty. kind {
516
482
suggest_constraining_param (
483
+ self . tcx ,
517
484
& mut err,
485
+ lhs_ty,
486
+ rhs_ty,
487
+ & expr,
518
488
missing_trait,
519
489
p,
520
490
use_output,
@@ -965,3 +935,49 @@ fn suggest_impl_missing(err: &mut DiagnosticBuilder<'_>, ty: Ty<'_>, missing_tra
965
935
}
966
936
}
967
937
}
938
+
939
+ fn suggest_constraining_param (
940
+ tcx : TyCtxt < ' _ > ,
941
+ mut err : & mut DiagnosticBuilder < ' _ > ,
942
+ lhs_ty : Ty < ' _ > ,
943
+ rhs_ty : Ty < ' _ > ,
944
+ expr : & hir:: Expr < ' _ > ,
945
+ missing_trait : & str ,
946
+ p : ty:: ParamTy ,
947
+ set_output : bool ,
948
+ ) {
949
+ let hir = tcx. hir ( ) ;
950
+ let msg = & format ! ( "`{}` might need a bound for `{}`" , lhs_ty, missing_trait) ;
951
+ // Try to find the def-id and details for the parameter p. We have only the index,
952
+ // so we have to find the enclosing function's def-id, then look through its declared
953
+ // generic parameters to get the declaration.
954
+ if let Some ( def_id) = hir
955
+ . find ( hir. get_parent_item ( expr. hir_id ) )
956
+ . and_then ( |node| node. hir_id ( ) )
957
+ . and_then ( |hir_id| hir. opt_local_def_id ( hir_id) )
958
+ {
959
+ let generics = tcx. generics_of ( def_id) ;
960
+ let param_def_id = generics. type_param ( & p, tcx) . def_id ;
961
+ if let Some ( generics) = hir
962
+ . as_local_hir_id ( param_def_id)
963
+ . and_then ( |id| hir. find ( hir. get_parent_item ( id) ) )
964
+ . as_ref ( )
965
+ . and_then ( |node| node. generics ( ) )
966
+ {
967
+ let output = if set_output { format ! ( "<Output = {}>" , rhs_ty) } else { String :: new ( ) } ;
968
+ suggest_constraining_type_param (
969
+ tcx,
970
+ generics,
971
+ & mut err,
972
+ & format ! ( "{}" , lhs_ty) ,
973
+ & format ! ( "{}{}" , missing_trait, output) ,
974
+ None ,
975
+ ) ;
976
+ } else {
977
+ let span = tcx. def_span ( param_def_id) ;
978
+ err. span_label ( span, msg) ;
979
+ }
980
+ } else {
981
+ err. note ( & msg) ;
982
+ }
983
+ }
0 commit comments