@@ -1015,13 +1015,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10151015 ( result, dep_node)
10161016 }
10171017
1018- // Treat negative impls as unimplemented, and reservation impls as ambiguity.
1019- fn filter_negative_and_reservation_impls (
1018+ fn filter_impls (
10201019 & mut self ,
10211020 candidate : SelectionCandidate < ' tcx > ,
1021+ obligation : & TraitObligation < ' tcx > ,
10221022 ) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
1023+ let tcx = self . tcx ( ) ;
1024+ // Respect const trait obligations
1025+ if let hir:: Constness :: Const = obligation. predicate . skip_binder ( ) . constness {
1026+ match candidate {
1027+ // const impl
1028+ ImplCandidate ( def_id) if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1029+ // const param
1030+ ParamCandidate ( ty:: ConstnessAnd { constness : hir:: Constness :: Const , .. } ) => { }
1031+ // auto trait impl
1032+ AutoImplCandidate ( ..) => { }
1033+ // FIXME check if this is right, but this would allow Sized impls
1034+ BuiltinCandidate { .. } => { }
1035+ _ => { // reject all other types of candidates
1036+ return Err ( Unimplemented )
1037+ }
1038+ }
1039+ }
1040+ // Treat negative impls as unimplemented, and reservation impls as ambiguity.
10231041 if let ImplCandidate ( def_id) = candidate {
1024- let tcx = self . tcx ( ) ;
10251042 match tcx. impl_polarity ( def_id) {
10261043 ty:: ImplPolarity :: Negative if !self . allow_negative_impls => {
10271044 return Err ( Unimplemented ) ;
@@ -1035,7 +1052,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10351052 let value = attr. and_then ( |a| a. value_str ( ) ) ;
10361053 if let Some ( value) = value {
10371054 debug ! (
1038- "filter_negative_and_reservation_impls : \
1055+ "filter_impls : \
10391056 reservation impl ambiguity on {:?}",
10401057 def_id
10411058 ) ;
0 commit comments