Move const filter to filter_impls
This commit is contained in:
parent
c4c76a4fbd
commit
5b5a2e600e
2 changed files with 47 additions and 38 deletions
|
@ -121,7 +121,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut candidates = candidate_set.vec;
|
let candidates = candidate_set.vec;
|
||||||
|
|
||||||
debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
|
debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// candidate which assumes $0 == int, one that assumes `$0 ==
|
// candidate which assumes $0 == int, one that assumes `$0 ==
|
||||||
// usize`, etc. This spells an ambiguity.
|
// usize`, etc. This spells an ambiguity.
|
||||||
|
|
||||||
self.filter_impls(&mut candidates, stack);
|
let mut candidates = self.filter_impls(candidates, stack.obligation);
|
||||||
|
|
||||||
// If there is more than one candidate, first winnow them down
|
// If there is more than one candidate, first winnow them down
|
||||||
// by considering extra conditions (nested obligations and so
|
// by considering extra conditions (nested obligations and so
|
||||||
|
|
|
@ -20,7 +20,7 @@ use super::ObligationCauseCode;
|
||||||
use super::Selection;
|
use super::Selection;
|
||||||
use super::SelectionResult;
|
use super::SelectionResult;
|
||||||
use super::TraitQueryMode;
|
use super::TraitQueryMode;
|
||||||
use super::{ErrorReporting, Overflow, SelectionError, Unimplemented};
|
use super::{ErrorReporting, Overflow, SelectionError};
|
||||||
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
||||||
|
|
||||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||||
|
@ -1122,34 +1122,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn filter_impls(
|
fn filter_impls(
|
||||||
&mut self,
|
&mut self,
|
||||||
candidates: &mut Vec<SelectionCandidate<'tcx>>,
|
candidates: Vec<SelectionCandidate<'tcx>>,
|
||||||
stack: &TraitObligationStack<'o, 'tcx>,
|
|
||||||
) {
|
|
||||||
let tcx = self.tcx();
|
|
||||||
candidates.retain(|candidate| {
|
|
||||||
if let ImplCandidate(def_id) = candidate {
|
|
||||||
ty::ImplPolarity::Reservation == tcx.impl_polarity(*def_id)
|
|
||||||
|| stack.obligation.polarity() == tcx.impl_polarity(*def_id)
|
|
||||||
|| self.allow_negative_impls
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// filter_reservation_impls filter reservation impl for any goal as ambiguous
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
|
||||||
fn filter_reservation_impls(
|
|
||||||
&mut self,
|
|
||||||
candidate: SelectionCandidate<'tcx>,
|
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
) -> Vec<SelectionCandidate<'tcx>> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
let mut result = Vec::with_capacity(candidates.len());
|
||||||
|
|
||||||
|
for candidate in candidates {
|
||||||
// Respect const trait obligations
|
// Respect const trait obligations
|
||||||
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
||||||
match candidate {
|
match candidate {
|
||||||
// const impl
|
// const impl
|
||||||
ImplCandidate(def_id) if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
ImplCandidate(def_id)
|
||||||
|
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||||
// const param
|
// const param
|
||||||
ParamCandidate((
|
ParamCandidate((
|
||||||
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
|
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
|
||||||
|
@ -1165,10 +1150,34 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
ConstDropCandidate => {}
|
ConstDropCandidate => {}
|
||||||
_ => {
|
_ => {
|
||||||
// reject all other types of candidates
|
// reject all other types of candidates
|
||||||
return Err(Unimplemented);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let ImplCandidate(def_id) = candidate {
|
||||||
|
if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
|
||||||
|
|| obligation.polarity() == tcx.impl_polarity(def_id)
|
||||||
|
|| self.allow_negative_impls
|
||||||
|
{
|
||||||
|
result.push(candidate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.push(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// filter_reservation_impls filter reservation impl for any goal as ambiguous
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
fn filter_reservation_impls(
|
||||||
|
&mut self,
|
||||||
|
candidate: SelectionCandidate<'tcx>,
|
||||||
|
obligation: &TraitObligation<'tcx>,
|
||||||
|
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||||
|
let tcx = self.tcx();
|
||||||
// Treat reservation impls as ambiguity.
|
// Treat reservation impls as ambiguity.
|
||||||
if let ImplCandidate(def_id) = candidate {
|
if let ImplCandidate(def_id) = candidate {
|
||||||
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
|
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue