Treat different opaque types of the same def id as equal during coherence
This commit is contained in:
parent
2752e328c9
commit
94fe30ff2f
17 changed files with 182 additions and 50 deletions
|
@ -81,6 +81,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
.normalize_fn_sig_for_diagnostic
|
||||
.as_ref()
|
||||
.map(|f| f.clone()),
|
||||
intercrate: self.intercrate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -521,6 +521,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
|||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.infcx.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
}
|
||||
|
@ -799,6 +804,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
|||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.infcx.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
|||
self.fields.tcx()
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.fields.infcx.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.fields.param_env
|
||||
}
|
||||
|
|
|
@ -2937,6 +2937,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
|
|||
self.0.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.0.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
// Unused, only for consts which we treat as always equal
|
||||
ty::ParamEnv::empty()
|
||||
|
|
|
@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
|||
"Glb"
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.fields.infcx.intercrate
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.fields.tcx()
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
|||
"Lub"
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.fields.infcx.intercrate
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.fields.tcx()
|
||||
}
|
||||
|
|
|
@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> {
|
|||
|
||||
normalize_fn_sig_for_diagnostic:
|
||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
||||
|
||||
/// During coherence we have to assume that other crates may add
|
||||
/// additional impls which we currently don't know about.
|
||||
///
|
||||
/// To deal with this evaluation should be conservative
|
||||
/// and consider the possibility of impls from outside this crate.
|
||||
/// This comes up primarily when resolving ambiguity. Imagine
|
||||
/// there is some trait reference `$0: Bar` where `$0` is an
|
||||
/// inference variable. If `intercrate` is true, then we can never
|
||||
/// say for sure that this reference is not implemented, even if
|
||||
/// there are *no impls at all for `Bar`*, because `$0` could be
|
||||
/// bound to some type that in a downstream crate that implements
|
||||
/// `Bar`.
|
||||
///
|
||||
/// Outside of coherence we set this to false because we are only
|
||||
/// interested in types that the user could actually have written.
|
||||
/// In other words, we consider `$0: Bar` to be unimplemented if
|
||||
/// there is no type that the user could *actually name* that
|
||||
/// would satisfy it. This avoids crippling inference, basically.
|
||||
pub intercrate: bool,
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
|
@ -554,6 +574,7 @@ pub struct InferCtxtBuilder<'tcx> {
|
|||
considering_regions: bool,
|
||||
normalize_fn_sig_for_diagnostic:
|
||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
||||
intercrate: bool,
|
||||
}
|
||||
|
||||
pub trait TyCtxtInferExt<'tcx> {
|
||||
|
@ -567,6 +588,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
|
|||
defining_use_anchor: DefiningAnchor::Error,
|
||||
considering_regions: true,
|
||||
normalize_fn_sig_for_diagnostic: None,
|
||||
intercrate: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -583,6 +605,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn intercrate(mut self) -> Self {
|
||||
self.intercrate = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ignoring_regions(mut self) -> Self {
|
||||
self.considering_regions = false;
|
||||
self
|
||||
|
@ -622,6 +649,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
defining_use_anchor,
|
||||
considering_regions,
|
||||
ref normalize_fn_sig_for_diagnostic,
|
||||
intercrate,
|
||||
} = *self;
|
||||
InferCtxt {
|
||||
tcx,
|
||||
|
@ -641,6 +669,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
|
||||
.as_ref()
|
||||
.map(|f| f.clone()),
|
||||
intercrate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -531,6 +531,10 @@ where
|
|||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.infcx.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.delegate.param_env()
|
||||
}
|
||||
|
@ -898,6 +902,10 @@ where
|
|||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.infcx.intercrate
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.delegate.param_env()
|
||||
}
|
||||
|
|
|
@ -136,6 +136,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
|
|||
fn tag(&self) -> &'static str {
|
||||
"Match"
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
|||
fn tag(&self) -> &'static str {
|
||||
"Sub"
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
self.fields.infcx.intercrate
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.fields.infcx.tcx
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue