@@ -46,6 +46,7 @@ use rustc_middle::ty::GenericArgsRef;
46
46
use rustc_middle:: ty:: { self , EarlyBinder , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
47
47
use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable , TypeVisitableExt } ;
48
48
use rustc_span:: symbol:: sym;
49
+ use rustc_span:: Symbol ;
49
50
50
51
use std:: cell:: { Cell , RefCell } ;
51
52
use std:: cmp;
@@ -59,42 +60,46 @@ mod candidate_assembly;
59
60
mod confirmation;
60
61
61
62
#[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
62
- pub enum IntercrateAmbiguityCause {
63
- DownstreamCrate { trait_desc : String , self_desc : Option < String > } ,
64
- UpstreamCrateUpdate { trait_desc : String , self_desc : Option < String > } ,
65
- ReservationImpl { message : String } ,
63
+ pub enum IntercrateAmbiguityCause < ' tcx > {
64
+ DownstreamCrate { trait_ref : ty :: TraitRef < ' tcx > , self_ty : Option < Ty < ' tcx > > } ,
65
+ UpstreamCrateUpdate { trait_ref : ty :: TraitRef < ' tcx > , self_ty : Option < Ty < ' tcx > > } ,
66
+ ReservationImpl { message : Symbol } ,
66
67
}
67
68
68
- impl IntercrateAmbiguityCause {
69
+ impl < ' tcx > IntercrateAmbiguityCause < ' tcx > {
69
70
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
70
71
/// See #23980 for details.
71
72
pub fn add_intercrate_ambiguity_hint ( & self , err : & mut Diagnostic ) {
72
73
err. note ( self . intercrate_ambiguity_hint ( ) ) ;
73
74
}
74
75
75
76
pub fn intercrate_ambiguity_hint ( & self ) -> String {
76
- match self {
77
- IntercrateAmbiguityCause :: DownstreamCrate { trait_desc, self_desc } => {
78
- let self_desc = if let Some ( ty) = self_desc {
79
- format ! ( " for type `{ty}`" )
80
- } else {
81
- String :: new ( )
82
- } ;
83
- format ! ( "downstream crates may implement trait `{trait_desc}`{self_desc}" )
77
+ with_no_trimmed_paths ! ( match self {
78
+ IntercrateAmbiguityCause :: DownstreamCrate { trait_ref, self_ty } => {
79
+ format!(
80
+ "downstream crates may implement trait `{trait_desc}`{self_desc}" ,
81
+ trait_desc = trait_ref. print_only_trait_path( ) ,
82
+ self_desc = if let Some ( self_ty) = self_ty {
83
+ format!( " for type `{self_ty}`" )
84
+ } else {
85
+ String :: new( )
86
+ }
87
+ )
84
88
}
85
- IntercrateAmbiguityCause :: UpstreamCrateUpdate { trait_desc, self_desc } => {
86
- let self_desc = if let Some ( ty) = self_desc {
87
- format ! ( " for type `{ty}`" )
88
- } else {
89
- String :: new ( )
90
- } ;
89
+ IntercrateAmbiguityCause :: UpstreamCrateUpdate { trait_ref, self_ty } => {
91
90
format!(
92
91
"upstream crates may add a new impl of trait `{trait_desc}`{self_desc} \
93
- in future versions"
92
+ in future versions",
93
+ trait_desc = trait_ref. print_only_trait_path( ) ,
94
+ self_desc = if let Some ( self_ty) = self_ty {
95
+ format!( " for type `{self_ty}`" )
96
+ } else {
97
+ String :: new( )
98
+ }
94
99
)
95
100
}
96
- IntercrateAmbiguityCause :: ReservationImpl { message } => message. clone ( ) ,
97
- }
101
+ IntercrateAmbiguityCause :: ReservationImpl { message } => message. to_string ( ) ,
102
+ } )
98
103
}
99
104
}
100
105
@@ -114,7 +119,7 @@ pub struct SelectionContext<'cx, 'tcx> {
114
119
/// We don't do his until we detect a coherence error because it can
115
120
/// lead to false overflow results (#47139) and because always
116
121
/// computing it may negatively impact performance.
117
- intercrate_ambiguity_causes : Option < FxIndexSet < IntercrateAmbiguityCause > > ,
122
+ intercrate_ambiguity_causes : Option < FxIndexSet < IntercrateAmbiguityCause < ' tcx > > > ,
118
123
119
124
/// The mode that trait queries run in, which informs our error handling
120
125
/// policy. In essence, canonicalized queries need their errors propagated
@@ -270,7 +275,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
270
275
/// Gets the intercrate ambiguity causes collected since tracking
271
276
/// was enabled and disables tracking at the same time. If
272
277
/// tracking is not enabled, just returns an empty vector.
273
- pub fn take_intercrate_ambiguity_causes ( & mut self ) -> FxIndexSet < IntercrateAmbiguityCause > {
278
+ pub fn take_intercrate_ambiguity_causes ( & mut self ) -> FxIndexSet < IntercrateAmbiguityCause < ' tcx > > {
274
279
assert ! ( self . is_intercrate( ) ) ;
275
280
self . intercrate_ambiguity_causes . take ( ) . unwrap_or_default ( )
276
281
}
@@ -428,19 +433,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
428
433
) ;
429
434
if !trait_ref. references_error ( ) {
430
435
let self_ty = trait_ref. self_ty ( ) ;
431
- let ( trait_desc, self_desc) = with_no_trimmed_paths ! ( {
432
- let trait_desc = trait_ref. print_only_trait_path( ) . to_string( ) ;
433
- let self_desc =
434
- self_ty. has_concrete_skeleton( ) . then( || self_ty. to_string( ) ) ;
435
- ( trait_desc, self_desc)
436
- } ) ;
436
+ let self_ty = self_ty. has_concrete_skeleton ( ) . then ( || self_ty) ;
437
437
let cause = if let Conflict :: Upstream = conflict {
438
- IntercrateAmbiguityCause :: UpstreamCrateUpdate {
439
- trait_desc,
440
- self_desc,
441
- }
438
+ IntercrateAmbiguityCause :: UpstreamCrateUpdate { trait_ref, self_ty }
442
439
} else {
443
- IntercrateAmbiguityCause :: DownstreamCrate { trait_desc , self_desc }
440
+ IntercrateAmbiguityCause :: DownstreamCrate { trait_ref , self_ty }
444
441
} ;
445
442
debug ! ( ?cause, "evaluate_stack: pushing cause" ) ;
446
443
self . intercrate_ambiguity_causes . as_mut ( ) . unwrap ( ) . insert ( cause) ;
@@ -1451,18 +1448,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1451
1448
if let ImplCandidate ( def_id) = candidate {
1452
1449
if let ty:: ImplPolarity :: Reservation = tcx. impl_polarity ( def_id) {
1453
1450
if let Some ( intercrate_ambiguity_clauses) = & mut self . intercrate_ambiguity_causes {
1454
- let value = tcx
1451
+ let message = tcx
1455
1452
. get_attr ( def_id, sym:: rustc_reservation_impl)
1456
1453
. and_then ( |a| a. value_str ( ) ) ;
1457
- if let Some ( value ) = value {
1454
+ if let Some ( message ) = message {
1458
1455
debug ! (
1459
1456
"filter_reservation_impls: \
1460
1457
reservation impl ambiguity on {:?}",
1461
1458
def_id
1462
1459
) ;
1463
1460
intercrate_ambiguity_clauses. insert (
1464
1461
IntercrateAmbiguityCause :: ReservationImpl {
1465
- message : value . to_string ( ) ,
1462
+ message,
1466
1463
} ,
1467
1464
) ;
1468
1465
}
0 commit comments