mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
Move const filter to filter_impls
This commit is contained in:
parent
c4c76a4fbd
commit
5b5a2e600e
@ -121,7 +121,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mut candidates = candidate_set.vec;
|
||||
let candidates = candidate_set.vec;
|
||||
|
||||
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 ==
|
||||
// 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
|
||||
// by considering extra conditions (nested obligations and so
|
||||
|
@ -20,7 +20,7 @@ use super::ObligationCauseCode;
|
||||
use super::Selection;
|
||||
use super::SelectionResult;
|
||||
use super::TraitQueryMode;
|
||||
use super::{ErrorReporting, Overflow, SelectionError, Unimplemented};
|
||||
use super::{ErrorReporting, Overflow, SelectionError};
|
||||
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
||||
|
||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
@ -1122,19 +1122,52 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn filter_impls(
|
||||
&mut self,
|
||||
candidates: &mut Vec<SelectionCandidate<'tcx>>,
|
||||
stack: &TraitObligationStack<'o, 'tcx>,
|
||||
) {
|
||||
candidates: Vec<SelectionCandidate<'tcx>>,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Vec<SelectionCandidate<'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
|
||||
let mut result = Vec::with_capacity(candidates.len());
|
||||
|
||||
for candidate in candidates {
|
||||
// Respect const trait obligations
|
||||
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
||||
match candidate {
|
||||
// const impl
|
||||
ImplCandidate(def_id)
|
||||
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||
// const param
|
||||
ParamCandidate((
|
||||
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
|
||||
_,
|
||||
)) => {}
|
||||
// auto trait impl
|
||||
AutoImplCandidate(..) => {}
|
||||
// generator, this will raise error in other places
|
||||
// or ignore error with const_async_blocks feature
|
||||
GeneratorCandidate => {}
|
||||
// FnDef where the function is const
|
||||
FnPointerCandidate { is_const: true } => {}
|
||||
ConstDropCandidate => {}
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
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
|
||||
@ -1145,30 +1178,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
// Respect const trait obligations
|
||||
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
||||
match candidate {
|
||||
// const impl
|
||||
ImplCandidate(def_id) if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||
// const param
|
||||
ParamCandidate((
|
||||
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
|
||||
_,
|
||||
)) => {}
|
||||
// auto trait impl
|
||||
AutoImplCandidate(..) => {}
|
||||
// generator, this will raise error in other places
|
||||
// or ignore error with const_async_blocks feature
|
||||
GeneratorCandidate => {}
|
||||
// FnDef where the function is const
|
||||
FnPointerCandidate { is_const: true } => {}
|
||||
ConstDropCandidate => {}
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
return Err(Unimplemented);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Treat reservation impls as ambiguity.
|
||||
if let ImplCandidate(def_id) = candidate {
|
||||
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
|
||||
|
Loading…
Reference in New Issue
Block a user