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