@@ -51,6 +51,47 @@ pub use rustc_middle::traits::select::*;
5151mod candidate_assembly;
5252mod confirmation;
5353
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+
5495pub struct SelectionContext < ' cx , ' tcx > {
5596 infcx : & ' cx InferCtxt < ' cx , ' tcx > ,
5697
0 commit comments