@@ -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,9 @@ 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 (
279
+ & mut self ,
280
+ ) -> FxIndexSet < IntercrateAmbiguityCause < ' tcx > > {
274
281
assert ! ( self . is_intercrate( ) ) ;
275
282
self . intercrate_ambiguity_causes . take ( ) . unwrap_or_default ( )
276
283
}
@@ -428,19 +435,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
428
435
) ;
429
436
if !trait_ref. references_error ( ) {
430
437
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
- } ) ;
438
+ let self_ty = self_ty. has_concrete_skeleton ( ) . then ( || self_ty) ;
437
439
let cause = if let Conflict :: Upstream = conflict {
438
- IntercrateAmbiguityCause :: UpstreamCrateUpdate {
439
- trait_desc,
440
- self_desc,
441
- }
440
+ IntercrateAmbiguityCause :: UpstreamCrateUpdate { trait_ref, self_ty }
442
441
} else {
443
- IntercrateAmbiguityCause :: DownstreamCrate { trait_desc , self_desc }
442
+ IntercrateAmbiguityCause :: DownstreamCrate { trait_ref , self_ty }
444
443
} ;
445
444
debug ! ( ?cause, "evaluate_stack: pushing cause" ) ;
446
445
self . intercrate_ambiguity_causes . as_mut ( ) . unwrap ( ) . insert ( cause) ;
@@ -1451,20 +1450,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1451
1450
if let ImplCandidate ( def_id) = candidate {
1452
1451
if let ty:: ImplPolarity :: Reservation = tcx. impl_polarity ( def_id) {
1453
1452
if let Some ( intercrate_ambiguity_clauses) = & mut self . intercrate_ambiguity_causes {
1454
- let value = tcx
1453
+ let message = tcx
1455
1454
. get_attr ( def_id, sym:: rustc_reservation_impl)
1456
1455
. and_then ( |a| a. value_str ( ) ) ;
1457
- if let Some ( value ) = value {
1456
+ if let Some ( message ) = message {
1458
1457
debug ! (
1459
1458
"filter_reservation_impls: \
1460
1459
reservation impl ambiguity on {:?}",
1461
1460
def_id
1462
1461
) ;
1463
- intercrate_ambiguity_clauses. insert (
1464
- IntercrateAmbiguityCause :: ReservationImpl {
1465
- message : value. to_string ( ) ,
1466
- } ,
1467
- ) ;
1462
+ intercrate_ambiguity_clauses
1463
+ . insert ( IntercrateAmbiguityCause :: ReservationImpl { message } ) ;
1468
1464
}
1469
1465
}
1470
1466
return Ok ( None ) ;
0 commit comments