Filter out Negative impls on intercrate mode's ambiguous reasoning
This commit is contained in:
parent
85c8fd9c94
commit
89a419cf7d
1 changed files with 30 additions and 23 deletions
|
@ -866,6 +866,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// precise still.
|
// precise still.
|
||||||
let unbound_input_types =
|
let unbound_input_types =
|
||||||
stack.fresh_trait_ref.value.skip_binder().substs.types().any(|ty| ty.is_fresh());
|
stack.fresh_trait_ref.value.skip_binder().substs.types().any(|ty| ty.is_fresh());
|
||||||
|
|
||||||
|
if stack.obligation.predicate.skip_binder().polarity != ty::ImplPolarity::Negative {
|
||||||
// This check was an imperfect workaround for a bug in the old
|
// This check was an imperfect workaround for a bug in the old
|
||||||
// intercrate mode; it should be removed when that goes away.
|
// intercrate mode; it should be removed when that goes away.
|
||||||
if unbound_input_types && self.intercrate {
|
if unbound_input_types && self.intercrate {
|
||||||
|
@ -877,14 +879,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
|
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
|
||||||
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
let cause =
|
let cause = with_no_trimmed_paths(|| {
|
||||||
with_no_trimmed_paths(|| IntercrateAmbiguityCause::DownstreamCrate {
|
IntercrateAmbiguityCause::DownstreamCrate {
|
||||||
trait_desc: trait_ref.print_only_trait_path().to_string(),
|
trait_desc: trait_ref.print_only_trait_path().to_string(),
|
||||||
self_desc: if self_ty.has_concrete_skeleton() {
|
self_desc: if self_ty.has_concrete_skeleton() {
|
||||||
Some(self_ty.to_string())
|
Some(self_ty.to_string())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!(?cause, "evaluate_stack: pushing cause");
|
debug!(?cause, "evaluate_stack: pushing cause");
|
||||||
|
@ -894,6 +897,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
return Ok(EvaluatedToAmbig);
|
return Ok(EvaluatedToAmbig);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if unbound_input_types
|
if unbound_input_types
|
||||||
&& stack.iter().skip(1).any(|prev| {
|
&& stack.iter().skip(1).any(|prev| {
|
||||||
stack.obligation.param_env == prev.obligation.param_env
|
stack.obligation.param_env == prev.obligation.param_env
|
||||||
|
@ -1178,7 +1183,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option<Conflict> {
|
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option<Conflict> {
|
||||||
debug!("is_knowable(intercrate={:?})", self.intercrate);
|
debug!("is_knowable(intercrate={:?})", self.intercrate);
|
||||||
|
|
||||||
if !self.intercrate {
|
if !self.intercrate
|
||||||
|
|| stack.obligation.predicate.skip_binder().polarity == ty::ImplPolarity::Negative
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue