@@ -20,7 +20,7 @@ use super::ObligationCauseCode;
2020use super :: Selection ;
2121use super :: SelectionResult ;
2222use super :: TraitQueryMode ;
23- use super :: { ErrorReporting , Overflow , SelectionError , Unimplemented } ;
23+ use super :: { ErrorReporting , Overflow , SelectionError } ;
2424use super :: { ObligationCause , PredicateObligation , TraitObligation } ;
2525
2626use 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