diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2021-10-22 10:56:32 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2021-10-22 10:56:32 -0300 |
| commit | 5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176 (patch) | |
| tree | b98be8e01f9c5f7fb3d4de0b46d2c1f7ec645eac | |
| parent | c4c76a4fbd046066eb5490d7e5aec4c263e12fde (diff) | |
| download | rust-5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176.tar.gz rust-5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176.zip | |
Move const filter to filter_impls
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 75 |
2 files changed, 44 insertions, 35 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 8bb7ed8de23..77b1c279efa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 94c4bc55f79..dfadf693872 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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| { + 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 { - ty::ImplPolarity::Reservation == tcx.impl_polarity(*def_id) - || stack.obligation.polarity() == tcx.impl_polarity(*def_id) + if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id) + || obligation.polarity() == tcx.impl_polarity(def_id) || self.allow_negative_impls + { + result.push(candidate); + } } else { - true + 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) { |
