@@ -20,7 +20,7 @@ use super::ObligationCauseCode;
20
20
use super :: Selection ;
21
21
use super :: SelectionResult ;
22
22
use super :: TraitQueryMode ;
23
- use super :: { ErrorReporting , Overflow , SelectionError , Unimplemented } ;
23
+ use super :: { ErrorReporting , Overflow , SelectionError } ;
24
24
use super :: { ObligationCause , PredicateObligation , TraitObligation } ;
25
25
26
26
use crate :: infer:: { InferCtxt , InferOk , TypeFreshener } ;
@@ -1122,19 +1122,52 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1122
1122
#[ instrument( level = "debug" , skip( self ) ) ]
1123
1123
fn filter_impls (
1124
1124
& 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 > > {
1128
1128
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
+
1130
1158
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)
1133
1161
|| self . allow_negative_impls
1162
+ {
1163
+ result. push ( candidate) ;
1164
+ }
1134
1165
} else {
1135
- true
1166
+ result . push ( candidate ) ;
1136
1167
}
1137
- } ) ;
1168
+ }
1169
+
1170
+ result
1138
1171
}
1139
1172
1140
1173
/// filter_reservation_impls filter reservation impl for any goal as ambiguous
@@ -1145,30 +1178,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1145
1178
obligation : & TraitObligation < ' tcx > ,
1146
1179
) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
1147
1180
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
- }
1172
1181
// Treat reservation impls as ambiguity.
1173
1182
if let ImplCandidate ( def_id) = candidate {
1174
1183
if let ty:: ImplPolarity :: Reservation = tcx. impl_polarity ( def_id) {
0 commit comments