Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 5b5a2e6

Browse files
committed
Move const filter to filter_impls
1 parent c4c76a4 commit 5b5a2e6

File tree

2 files changed

+44
-35
lines changed

2 files changed

+44
-35
lines changed

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
121121
return Ok(None);
122122
}
123123

124-
let mut candidates = candidate_set.vec;
124+
let candidates = candidate_set.vec;
125125

126126
debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
127127

@@ -134,7 +134,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
134134
// candidate which assumes $0 == int, one that assumes `$0 ==
135135
// usize`, etc. This spells an ambiguity.
136136

137-
self.filter_impls(&mut candidates, stack);
137+
let mut candidates = self.filter_impls(candidates, stack.obligation);
138138

139139
// If there is more than one candidate, first winnow them down
140140
// by considering extra conditions (nested obligations and so

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use super::ObligationCauseCode;
2020
use super::Selection;
2121
use super::SelectionResult;
2222
use super::TraitQueryMode;
23-
use super::{ErrorReporting, Overflow, SelectionError, Unimplemented};
23+
use super::{ErrorReporting, Overflow, SelectionError};
2424
use super::{ObligationCause, PredicateObligation, TraitObligation};
2525

2626
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
@@ -1122,19 +1122,52 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11221122
#[instrument(level = "debug", skip(self))]
11231123
fn filter_impls(
11241124
&mut self,
1125-
candidates: &mut Vec<SelectionCandidate<'tcx>>,
1126-
stack: &TraitObligationStack<'o, 'tcx>,
1127-
) {
1125+
candidates: Vec<SelectionCandidate<'tcx>>,
1126+
obligation: &TraitObligation<'tcx>,
1127+
) -> Vec<SelectionCandidate<'tcx>> {
11281128
let tcx = self.tcx();
1129-
candidates.retain(|candidate| {
1129+
let mut result = Vec::with_capacity(candidates.len());
1130+
1131+
for candidate in candidates {
1132+
// Respect const trait obligations
1133+
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
1134+
match candidate {
1135+
// const impl
1136+
ImplCandidate(def_id)
1137+
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
1138+
// const param
1139+
ParamCandidate((
1140+
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
1141+
_,
1142+
)) => {}
1143+
// auto trait impl
1144+
AutoImplCandidate(..) => {}
1145+
// generator, this will raise error in other places
1146+
// or ignore error with const_async_blocks feature
1147+
GeneratorCandidate => {}
1148+
// FnDef where the function is const
1149+
FnPointerCandidate { is_const: true } => {}
1150+
ConstDropCandidate => {}
1151+
_ => {
1152+
// reject all other types of candidates
1153+
continue;
1154+
}
1155+
}
1156+
}
1157+
11301158
if let ImplCandidate(def_id) = candidate {
1131-
ty::ImplPolarity::Reservation == tcx.impl_polarity(*def_id)
1132-
|| stack.obligation.polarity() == tcx.impl_polarity(*def_id)
1159+
if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
1160+
|| obligation.polarity() == tcx.impl_polarity(def_id)
11331161
|| self.allow_negative_impls
1162+
{
1163+
result.push(candidate);
1164+
}
11341165
} else {
1135-
true
1166+
result.push(candidate);
11361167
}
1137-
});
1168+
}
1169+
1170+
result
11381171
}
11391172

11401173
/// filter_reservation_impls filter reservation impl for any goal as ambiguous
@@ -1145,30 +1178,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11451178
obligation: &TraitObligation<'tcx>,
11461179
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
11471180
let tcx = self.tcx();
1148-
// Respect const trait obligations
1149-
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
1150-
match candidate {
1151-
// const impl
1152-
ImplCandidate(def_id) if tcx.impl_constness(def_id) == hir::Constness::Const => {}
1153-
// const param
1154-
ParamCandidate((
1155-
ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
1156-
_,
1157-
)) => {}
1158-
// auto trait impl
1159-
AutoImplCandidate(..) => {}
1160-
// generator, this will raise error in other places
1161-
// or ignore error with const_async_blocks feature
1162-
GeneratorCandidate => {}
1163-
// FnDef where the function is const
1164-
FnPointerCandidate { is_const: true } => {}
1165-
ConstDropCandidate => {}
1166-
_ => {
1167-
// reject all other types of candidates
1168-
return Err(Unimplemented);
1169-
}
1170-
}
1171-
}
11721181
// Treat reservation impls as ambiguity.
11731182
if let ImplCandidate(def_id) = candidate {
11741183
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {

0 commit comments

Comments
 (0)