@@ -51,6 +51,47 @@ pub use rustc_middle::traits::select::*;
51
51
mod candidate_assembly;
52
52
mod confirmation;
53
53
54
+ #[ derive( Clone , Debug ) ]
55
+ pub enum IntercrateAmbiguityCause {
56
+ DownstreamCrate { trait_desc : String , self_desc : Option < String > } ,
57
+ UpstreamCrateUpdate { trait_desc : String , self_desc : Option < String > } ,
58
+ ReservationImpl { message : String } ,
59
+ }
60
+
61
+ impl IntercrateAmbiguityCause {
62
+ /// Emits notes when the overlap is caused by complex intercrate ambiguities.
63
+ /// See #23980 for details.
64
+ pub fn add_intercrate_ambiguity_hint ( & self , err : & mut rustc_errors:: DiagnosticBuilder < ' _ > ) {
65
+ err. note ( & self . intercrate_ambiguity_hint ( ) ) ;
66
+ }
67
+
68
+ pub fn intercrate_ambiguity_hint ( & self ) -> String {
69
+ match self {
70
+ & IntercrateAmbiguityCause :: DownstreamCrate { ref trait_desc, ref self_desc } => {
71
+ let self_desc = if let & Some ( ref ty) = self_desc {
72
+ format ! ( " for type `{}`" , ty)
73
+ } else {
74
+ String :: new ( )
75
+ } ;
76
+ format ! ( "downstream crates may implement trait `{}`{}" , trait_desc, self_desc)
77
+ }
78
+ & IntercrateAmbiguityCause :: UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
79
+ let self_desc = if let & Some ( ref ty) = self_desc {
80
+ format ! ( " for type `{}`" , ty)
81
+ } else {
82
+ String :: new ( )
83
+ } ;
84
+ format ! (
85
+ "upstream crates may add a new impl of trait `{}`{} \
86
+ in future versions",
87
+ trait_desc, self_desc
88
+ )
89
+ }
90
+ & IntercrateAmbiguityCause :: ReservationImpl { ref message } => message. clone ( ) ,
91
+ }
92
+ }
93
+ }
94
+
54
95
pub struct SelectionContext < ' cx , ' tcx > {
55
96
infcx : & ' cx InferCtxt < ' cx , ' tcx > ,
56
97
0 commit comments