- // 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);
+ 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);