Point at overlapping impls when type annotations are needed
This commit is contained in:
@@ -18,7 +18,7 @@ use crate::traits;
|
||||
use crate::traits::coherence::Conflict;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{util, SelectionResult};
|
||||
use crate::traits::{ErrorReporting, Overflow, Unimplemented};
|
||||
use crate::traits::{Ambiguous, ErrorReporting, Overflow, Unimplemented};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
use super::IntercrateAmbiguityCause;
|
||||
@@ -197,7 +197,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// and report ambiguity.
|
||||
if i > 1 {
|
||||
debug!("multiple matches, ambig");
|
||||
return Ok(None);
|
||||
return Err(Ambiguous(
|
||||
candidates
|
||||
.into_iter()
|
||||
.filter_map(|c| match c.candidate {
|
||||
SelectionCandidate::ImplCandidate(def_id) => Some(def_id),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,18 +357,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> SelectionResult<'tcx, Selection<'tcx>> {
|
||||
debug_assert!(!obligation.predicate.has_escaping_bound_vars());
|
||||
|
||||
let pec = &ProvisionalEvaluationCache::default();
|
||||
let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
|
||||
|
||||
let candidate = match self.candidate_from_obligation(&stack) {
|
||||
let candidate = match self.select_from_obligation(obligation) {
|
||||
Err(SelectionError::Overflow) => {
|
||||
// In standard mode, overflow must have been caught and reported
|
||||
// earlier.
|
||||
assert!(self.query_mode == TraitQueryMode::Canonical);
|
||||
return Err(SelectionError::Overflow);
|
||||
}
|
||||
Err(SelectionError::Ambiguous(_)) => {
|
||||
return Ok(None);
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
@@ -391,6 +389,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
crate fn select_from_obligation(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||
debug_assert!(!obligation.predicate.has_escaping_bound_vars());
|
||||
|
||||
let pec = &ProvisionalEvaluationCache::default();
|
||||
let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation);
|
||||
|
||||
self.candidate_from_obligation(&stack)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EVALUATION
|
||||
//
|
||||
@@ -915,6 +925,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
match self.candidate_from_obligation(stack) {
|
||||
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
|
||||
Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig),
|
||||
Ok(None) => Ok(EvaluatedToAmbig),
|
||||
Err(Overflow) => Err(OverflowError::Canonical),
|
||||
Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
|
||||
|
||||
Reference in New Issue
Block a user