@@ -15,6 +15,7 @@ use self::EvaluationResult::*;
1515
1616use super :: coherence:: { self , Conflict } ;
1717use super :: DerivedObligationCause ;
18+ use super :: IntercrateMode ;
1819use super :: project;
1920use super :: project:: { normalize_with_depth, Normalized , ProjectionCacheKey } ;
2021use super :: { PredicateObligation , TraitObligation , ObligationCause } ;
@@ -87,7 +88,7 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
8788 /// other words, we consider `$0 : Bar` to be unimplemented if
8889 /// there is no type that the user could *actually name* that
8990 /// would satisfy it. This avoids crippling inference, basically.
90- intercrate : bool ,
91+ intercrate : Option < IntercrateMode > ,
9192
9293 inferred_obligations : SnapshotVec < InferredObligationsSnapshotVecDelegate < ' tcx > > ,
9394
@@ -111,21 +112,24 @@ impl IntercrateAmbiguityCause {
111112 /// See #23980 for details.
112113 pub fn add_intercrate_ambiguity_hint < ' a , ' tcx > ( & self ,
113114 err : & mut :: errors:: DiagnosticBuilder ) {
115+ err. note ( & self . intercrate_ambiguity_hint ( ) ) ;
116+ }
117+
118+ pub fn intercrate_ambiguity_hint ( & self ) -> String {
114119 match self {
115120 & IntercrateAmbiguityCause :: DownstreamCrate { ref trait_desc, ref self_desc } => {
116121 let self_desc = if let & Some ( ref ty) = self_desc {
117122 format ! ( " for type `{}`" , ty)
118123 } else { "" . to_string ( ) } ;
119- err. note ( & format ! ( "downstream crates may implement trait `{}`{}" ,
120- trait_desc, self_desc) ) ;
124+ format ! ( "downstream crates may implement trait `{}`{}" , trait_desc, self_desc)
121125 }
122126 & IntercrateAmbiguityCause :: UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
123127 let self_desc = if let & Some ( ref ty) = self_desc {
124128 format ! ( " for type `{}`" , ty)
125129 } else { "" . to_string ( ) } ;
126- err . note ( & format ! ( "upstream crates may add new impl of trait `{}`{} \
127- in future versions",
128- trait_desc, self_desc) ) ;
130+ format ! ( "upstream crates may add new impl of trait `{}`{} \
131+ in future versions",
132+ trait_desc, self_desc)
129133 }
130134 }
131135 }
@@ -417,17 +421,19 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
417421 SelectionContext {
418422 infcx,
419423 freshener : infcx. freshener ( ) ,
420- intercrate : false ,
424+ intercrate : None ,
421425 inferred_obligations : SnapshotVec :: new ( ) ,
422426 intercrate_ambiguity_causes : Vec :: new ( ) ,
423427 }
424428 }
425429
426- pub fn intercrate ( infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ) -> SelectionContext < ' cx , ' gcx , ' tcx > {
430+ pub fn intercrate ( infcx : & ' cx InferCtxt < ' cx , ' gcx , ' tcx > ,
431+ mode : IntercrateMode ) -> SelectionContext < ' cx , ' gcx , ' tcx > {
432+ debug ! ( "intercrate({:?})" , mode) ;
427433 SelectionContext {
428434 infcx,
429435 freshener : infcx. freshener ( ) ,
430- intercrate : true ,
436+ intercrate : Some ( mode ) ,
431437 inferred_obligations : SnapshotVec :: new ( ) ,
432438 intercrate_ambiguity_causes : Vec :: new ( ) ,
433439 }
@@ -758,7 +764,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
758764 debug ! ( "evaluate_trait_predicate_recursively({:?})" ,
759765 obligation) ;
760766
761- if !self . intercrate && obligation. is_global ( ) {
767+ if !self . intercrate . is_some ( ) && obligation. is_global ( ) {
762768 // If a param env is consistent, global obligations do not depend on its particular
763769 // value in order to work, so we can clear out the param env and get better
764770 // caching. (If the current param env is inconsistent, we don't care what happens).
@@ -814,7 +820,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
814820 // terms of `Fn` etc, but we could probably make this more
815821 // precise still.
816822 let unbound_input_types = stack. fresh_trait_ref . input_types ( ) . any ( |ty| ty. is_fresh ( ) ) ;
817- if unbound_input_types && self . intercrate && false {
823+ // this check was an imperfect workaround for a bug n the old
824+ // intercrate mode, it should be removed when that goes away.
825+ if unbound_input_types &&
826+ self . intercrate == Some ( IntercrateMode :: Issue43355 )
827+ {
818828 debug ! ( "evaluate_stack({:?}) --> unbound argument, intercrate --> ambiguous" ,
819829 stack. fresh_trait_ref) ;
820830 // Heuristics: show the diagnostics when there are no candidates in crate.
@@ -1212,9 +1222,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12121222 stack : & TraitObligationStack < ' o , ' tcx > )
12131223 -> Option < Conflict >
12141224 {
1215- debug ! ( "is_knowable(intercrate={})" , self . intercrate) ;
1225+ debug ! ( "is_knowable(intercrate={:? })" , self . intercrate) ;
12161226
1217- if !self . intercrate {
1227+ if !self . intercrate . is_some ( ) {
12181228 return None ;
12191229 }
12201230
@@ -1226,7 +1236,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12261236 // bound regions
12271237 let trait_ref = predicate. skip_binder ( ) . trait_ref ;
12281238
1229- coherence:: trait_ref_is_knowable ( self . tcx ( ) , trait_ref)
1239+ let result = coherence:: trait_ref_is_knowable ( self . tcx ( ) , trait_ref) ;
1240+ if let ( Some ( Conflict :: Downstream { used_to_be_broken : true } ) ,
1241+ Some ( IntercrateMode :: Issue43355 ) ) = ( result, self . intercrate ) {
1242+ debug ! ( "is_knowable: IGNORING conflict to be bug-compatible with #43355" ) ;
1243+ None
1244+ } else {
1245+ result
1246+ }
12301247 }
12311248
12321249 /// Returns true if the global caches can be used.
@@ -1251,7 +1268,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12511268 // the master cache. Since coherence executes pretty quickly,
12521269 // it's not worth going to more trouble to increase the
12531270 // hit-rate I don't think.
1254- if self . intercrate {
1271+ if self . intercrate . is_some ( ) {
12551272 return false ;
12561273 }
12571274
0 commit comments