@@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> {
337337
338338 normalize_fn_sig_for_diagnostic :
339339 Option < Lrc < dyn Fn ( & InferCtxt < ' tcx > , ty:: PolyFnSig < ' tcx > ) -> ty:: PolyFnSig < ' tcx > > > ,
340+
341+ /// During coherence we have to assume that other crates may add
342+ /// additional impls which we currently don't know about.
343+ ///
344+ /// To deal with this evaluation should be conservative
345+ /// and consider the possibility of impls from outside this crate.
346+ /// This comes up primarily when resolving ambiguity. Imagine
347+ /// there is some trait reference `$0: Bar` where `$0` is an
348+ /// inference variable. If `intercrate` is true, then we can never
349+ /// say for sure that this reference is not implemented, even if
350+ /// there are *no impls at all for `Bar`*, because `$0` could be
351+ /// bound to some type that in a downstream crate that implements
352+ /// `Bar`.
353+ ///
354+ /// Outside of coherence we set this to false because we are only
355+ /// interested in types that the user could actually have written.
356+ /// In other words, we consider `$0: Bar` to be unimplemented if
357+ /// there is no type that the user could *actually name* that
358+ /// would satisfy it. This avoids crippling inference, basically.
359+ pub intercrate : bool ,
340360}
341361
342362/// See the `error_reporting` module for more details.
@@ -554,6 +574,7 @@ pub struct InferCtxtBuilder<'tcx> {
554574 considering_regions : bool ,
555575 normalize_fn_sig_for_diagnostic :
556576 Option < Lrc < dyn Fn ( & InferCtxt < ' tcx > , ty:: PolyFnSig < ' tcx > ) -> ty:: PolyFnSig < ' tcx > > > ,
577+ intercrate : bool ,
557578}
558579
559580pub trait TyCtxtInferExt < ' tcx > {
@@ -567,6 +588,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
567588 defining_use_anchor : DefiningAnchor :: Error ,
568589 considering_regions : true ,
569590 normalize_fn_sig_for_diagnostic : None ,
591+ intercrate : false ,
570592 }
571593 }
572594}
@@ -583,6 +605,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
583605 self
584606 }
585607
608+ pub fn intercrate ( mut self ) -> Self {
609+ self . intercrate = true ;
610+ self
611+ }
612+
586613 pub fn ignoring_regions ( mut self ) -> Self {
587614 self . considering_regions = false ;
588615 self
@@ -622,6 +649,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
622649 defining_use_anchor,
623650 considering_regions,
624651 ref normalize_fn_sig_for_diagnostic,
652+ intercrate,
625653 } = * self ;
626654 InferCtxt {
627655 tcx,
@@ -641,6 +669,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
641669 normalize_fn_sig_for_diagnostic : normalize_fn_sig_for_diagnostic
642670 . as_ref ( )
643671 . map ( |f| f. clone ( ) ) ,
672+ intercrate,
644673 }
645674 }
646675}
0 commit comments