Skip to content

Commit 89a419c

Browse files
committed
Filter out Negative impls on intercrate mode's ambiguous reasoning
1 parent 85c8fd9 commit 89a419c

File tree

1 file changed

+30
-23
lines changed
  • compiler/rustc_trait_selection/src/traits/select

1 file changed

+30
-23
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

+30-23
Original file line numberDiff line numberDiff line change
@@ -866,34 +866,39 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
866866
// precise still.
867867
let unbound_input_types =
868868
stack.fresh_trait_ref.value.skip_binder().substs.types().any(|ty| ty.is_fresh());
869-
// This check was an imperfect workaround for a bug in the old
870-
// intercrate mode; it should be removed when that goes away.
871-
if unbound_input_types && self.intercrate {
872-
debug!("evaluate_stack --> unbound argument, intercrate --> ambiguous",);
873-
// Heuristics: show the diagnostics when there are no candidates in crate.
874-
if self.intercrate_ambiguity_causes.is_some() {
875-
debug!("evaluate_stack: intercrate_ambiguity_causes is some");
876-
if let Ok(candidate_set) = self.assemble_candidates(stack) {
877-
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
878-
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
879-
let self_ty = trait_ref.self_ty();
880-
let cause =
881-
with_no_trimmed_paths(|| IntercrateAmbiguityCause::DownstreamCrate {
882-
trait_desc: trait_ref.print_only_trait_path().to_string(),
883-
self_desc: if self_ty.has_concrete_skeleton() {
884-
Some(self_ty.to_string())
885-
} else {
886-
None
887-
},
869+
870+
if stack.obligation.predicate.skip_binder().polarity != ty::ImplPolarity::Negative {
871+
// This check was an imperfect workaround for a bug in the old
872+
// intercrate mode; it should be removed when that goes away.
873+
if unbound_input_types && self.intercrate {
874+
debug!("evaluate_stack --> unbound argument, intercrate --> ambiguous",);
875+
// Heuristics: show the diagnostics when there are no candidates in crate.
876+
if self.intercrate_ambiguity_causes.is_some() {
877+
debug!("evaluate_stack: intercrate_ambiguity_causes is some");
878+
if let Ok(candidate_set) = self.assemble_candidates(stack) {
879+
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
880+
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
881+
let self_ty = trait_ref.self_ty();
882+
let cause = with_no_trimmed_paths(|| {
883+
IntercrateAmbiguityCause::DownstreamCrate {
884+
trait_desc: trait_ref.print_only_trait_path().to_string(),
885+
self_desc: if self_ty.has_concrete_skeleton() {
886+
Some(self_ty.to_string())
887+
} else {
888+
None
889+
},
890+
}
888891
});
889892

890-
debug!(?cause, "evaluate_stack: pushing cause");
891-
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
893+
debug!(?cause, "evaluate_stack: pushing cause");
894+
self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
895+
}
892896
}
893897
}
898+
return Ok(EvaluatedToAmbig);
894899
}
895-
return Ok(EvaluatedToAmbig);
896900
}
901+
897902
if unbound_input_types
898903
&& stack.iter().skip(1).any(|prev| {
899904
stack.obligation.param_env == prev.obligation.param_env
@@ -1178,7 +1183,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11781183
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Option<Conflict> {
11791184
debug!("is_knowable(intercrate={:?})", self.intercrate);
11801185

1181-
if !self.intercrate {
1186+
if !self.intercrate
1187+
|| stack.obligation.predicate.skip_binder().polarity == ty::ImplPolarity::Negative
1188+
{
11821189
return None;
11831190
}
11841191

0 commit comments

Comments
 (0)