@@ -55,7 +55,7 @@ use hir;
55
55
use hir:: def_id:: DefId ;
56
56
use hir:: Node ;
57
57
use middle:: region;
58
- use std:: { cmp, fmt} ;
58
+ use std:: { cmp, fmt, iter } ;
59
59
use syntax:: ast:: DUMMY_NODE_ID ;
60
60
use syntax_pos:: { Pos , Span } ;
61
61
use traits:: { ObligationCause , ObligationCauseCode } ;
@@ -445,20 +445,69 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
445
445
terr : & TypeError < ' tcx > ,
446
446
sp : Span ,
447
447
) {
448
+ use hir:: def:: Namespace ;
449
+ use hir:: def_id:: CrateNum ;
450
+ use ty:: print:: { PrintCx , Printer } ;
451
+ use ty:: subst:: Substs ;
452
+
453
+ struct AbsolutePathPrinter ;
454
+
455
+ struct NonTrivialPath ;
456
+
457
+ impl Printer for AbsolutePathPrinter {
458
+ type Path = Result < Vec < String > , NonTrivialPath > ;
459
+
460
+ fn path_crate ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , cnum : CrateNum ) -> Self :: Path {
461
+ Ok ( vec ! [ self . tcx. original_crate_name( cnum) . to_string( ) ] )
462
+ }
463
+ fn path_qualified < ' tcx > (
464
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
465
+ _impl_prefix : Option < Self :: Path > ,
466
+ _self_ty : Ty < ' tcx > ,
467
+ _trait_ref : Option < ty:: TraitRef < ' tcx > > ,
468
+ _ns : Namespace ,
469
+ ) -> Self :: Path {
470
+ Err ( NonTrivialPath )
471
+ }
472
+ fn path_append (
473
+ self : & mut PrintCx < ' _ , ' _ , ' _ , Self > ,
474
+ path : Self :: Path ,
475
+ text : & str ,
476
+ ) -> Self :: Path {
477
+ let mut path = path?;
478
+ path. push ( text. to_string ( ) ) ;
479
+ Ok ( path)
480
+ }
481
+ fn path_generic_args < ' tcx > (
482
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
483
+ path : Self :: Path ,
484
+ _params : & [ ty:: GenericParamDef ] ,
485
+ _substs : & ' tcx Substs < ' tcx > ,
486
+ _ns : Namespace ,
487
+ _projections : impl Iterator < Item = ty:: ExistentialProjection < ' tcx > > ,
488
+ ) -> Self :: Path {
489
+ path
490
+ }
491
+ }
492
+
448
493
let report_path_match = |err : & mut DiagnosticBuilder < ' _ > , did1 : DefId , did2 : DefId | {
449
494
// Only external crates, if either is from a local
450
495
// module we could have false positives
451
496
if !( did1. is_local ( ) || did2. is_local ( ) ) && did1. krate != did2. krate {
452
- let exp_path = self . tcx . def_path_str ( did1) ;
453
- let found_path = self . tcx . def_path_str ( did2) ;
454
- // HACK(eddyb) switch form `with_forced_absolute_paths`
455
- // to a custom implementation of `ty::print::Printer`.
456
- let ( exp_abs_path, found_abs_path) = ty:: print:: with_forced_absolute_paths ( || {
457
- ( self . tcx . def_path_str ( did1) , self . tcx . def_path_str ( did2) )
458
- } ) ;
497
+ let abs_path = |def_id| {
498
+ PrintCx :: new ( self . tcx , AbsolutePathPrinter )
499
+ . print_def_path ( def_id, None , Namespace :: TypeNS , iter:: empty ( ) )
500
+ } ;
501
+
459
502
// We compare strings because DefPath can be different
460
503
// for imported and non-imported crates
461
- if exp_path == found_path || exp_abs_path == found_abs_path {
504
+ let same_path = || -> Result < _ , NonTrivialPath > {
505
+ Ok (
506
+ self . tcx . def_path_str ( did1) == self . tcx . def_path_str ( did2) ||
507
+ abs_path ( did1) ? == abs_path ( did2) ?
508
+ )
509
+ } ;
510
+ if same_path ( ) . unwrap_or ( false ) {
462
511
let crate_name = self . tcx . crate_name ( did1. krate ) ;
463
512
err. span_note (
464
513
sp,
0 commit comments