about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2021-10-22 10:56:32 -0300
committerSantiago Pastorino <spastorino@gmail.com>2021-10-22 10:56:32 -0300
commit5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176 (patch)
treeb98be8e01f9c5f7fb3d4de0b46d2c1f7ec645eac
parentc4c76a4fbd046066eb5490d7e5aec4c263e12fde (diff)
downloadrust-5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176.tar.gz
rust-5b5a2e600ebf15aa06dae1c35b7ee9f6c8f74176.zip
Move const filter to filter_impls
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs75
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) {