@@ -575,6 +575,44 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
575
575
= self . on_unimplemented_note ( trait_ref, obligation) ;
576
576
let have_alt_message = message. is_some ( ) || label. is_some ( ) ;
577
577
578
+ // {
579
+ // let ty::Binder(trait_ref) = trait_ref;
580
+ // println!("TraitRef: {:?}", trait_ref);
581
+ // println!("TraitRef: id:{:?}; subst:{:?}", trait_ref.def_id, trait_ref.substs);
582
+
583
+ // if let ty::Predicate::Trait(trait_predicate_binder) =
584
+ // trait_ref.to_predicate() {
585
+ // let trait_predicate = trait_predicate_binder.skip_binder();
586
+ // println!("TraitPredicateBinder: {:?}", trait_predicate_binder);
587
+ // println!("TraitPredicate: {:?}", trait_predicate);
588
+
589
+ // let trait_ty = trait_ref.self_ty();
590
+ // println!("TraitPredicateTy: {:?}", trait_ty);
591
+ // println!("TraitPredicateTy: sty:{:?}; flags{:?}", trait_ty.sty, trait_ty.flags);
592
+ // }
593
+
594
+ // for in_ty in trait_ref.input_types() {
595
+ // println!("\t- {:?}", in_ty);
596
+ // println!("\t\t- sty:{:?}; flags:{:?}", in_ty.sty, in_ty.flags);
597
+ // }
598
+
599
+ // println!("Message: {:?}", message);
600
+ // println!("Label: {:?}", label);
601
+ // println!("Obligation: {:?}", obligation);
602
+ // println!("Span: {:?}", self.tcx.sess.codemap().span_to_string(span));
603
+
604
+ // let body_id = obligation.cause.body_id;
605
+ // println!("BodyId: {:?}", body_id);
606
+ // println!("BodyIdSpan: {:?}", self.tcx.hir.span(body_id));
607
+
608
+ // match self.tcx.hir.find(body_id) {
609
+ // Some(node) => println!("Node: {:?}", node),
610
+ // None => println!("Node not found."),
611
+ // }
612
+
613
+ // println!("=------------------------------=");
614
+ // }
615
+
578
616
let mut err = struct_span_err ! (
579
617
self . tcx. sess,
580
618
span,
@@ -606,6 +644,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
606
644
}
607
645
608
646
self . suggest_borrow_on_unsized_slice ( & obligation. cause . code , & mut err) ;
647
+ self . suggest_remove_reference ( & obligation, & mut err, & trait_ref) ;
609
648
610
649
// Try to report a help message
611
650
if !trait_ref. has_infer_types ( ) &&
@@ -844,6 +883,54 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
844
883
}
845
884
}
846
885
886
+ fn suggest_remove_reference ( & self ,
887
+ obligation : & PredicateObligation < ' tcx > ,
888
+ err : & mut DiagnosticBuilder < ' tcx > ,
889
+ trait_ref : & ty:: Binder < ty:: TraitRef < ' tcx > > ) {
890
+ let ty:: Binder ( trait_ref) = trait_ref;
891
+
892
+ let span = obligation. cause . span ;
893
+ let mut snippet = match self . tcx . sess . codemap ( ) . span_to_snippet ( span) {
894
+ Ok ( s) => s,
895
+ Err ( _) => String :: from ( "" ) ,
896
+ } ;
897
+
898
+ let mut refs_number = 0 ;
899
+
900
+ for c in snippet. chars ( ) {
901
+ if c == '&' {
902
+ refs_number += 1 ;
903
+ }
904
+ }
905
+
906
+ let mut refs_remaining = refs_number;
907
+ let mut trait_type = trait_ref. self_ty ( ) ;
908
+ let mut selcx = SelectionContext :: new ( self ) ;
909
+
910
+ while refs_remaining > 0 {
911
+ if let ty:: TypeVariants :: TyRef ( _, ty:: TypeAndMut { ty : t_type, mutbl : _ } ) =
912
+ trait_type. sty {
913
+ trait_type = t_type;
914
+ refs_remaining -= 1 ;
915
+
916
+ let substs = self . tcx . mk_substs_trait ( trait_type, & [ ] ) ;
917
+ let new_trait_ref = ty:: TraitRef :: new ( trait_ref. def_id , substs) ;
918
+ let new_obligation = Obligation :: new ( ObligationCause :: dummy ( ) ,
919
+ obligation. param_env ,
920
+ new_trait_ref. to_predicate ( ) ) ;
921
+
922
+ if selcx. evaluate_obligation ( & new_obligation) {
923
+ for i in 0 ..refs_number {
924
+ snippet. remove ( i) ;
925
+ }
926
+ err. span_suggestion ( span, "consider removing `&`s like" , format ! ( "{}" , snippet) ) ;
927
+ }
928
+ } else {
929
+ break ;
930
+ }
931
+ }
932
+ }
933
+
847
934
/// Given some node representing a fn-like thing in the HIR map,
848
935
/// returns a span and `ArgKind` information that describes the
849
936
/// arguments it expects. This can be supplied to
0 commit comments