@@ -934,16 +934,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
934934 ( result, dep_node)
935935 }
936936
937- // Treat negative impls as unimplemented, and reservation impls as ambiguity.
937+ /// Deal with negative impls and interpret and reservation impls as ambiguity.
938+ ///
939+ /// If the negative impl is an exact fit, this returns `Err(Unimplemented)`. In case
940+ /// the negative impl does not apply to all possible values of `self` it is instead
941+ /// interpreted as ambiguity.
938942 fn filter_negative_and_reservation_impls (
939943 & mut self ,
944+ pred : ty:: PolyTraitPredicate < ' tcx > ,
940945 candidate : SelectionCandidate < ' tcx > ,
941946 ) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
942947 if let ImplCandidate ( def_id) = candidate {
943948 let tcx = self . tcx ( ) ;
944949 match tcx. impl_polarity ( def_id) {
945950 ty:: ImplPolarity :: Negative if !self . allow_negative_impls => {
946- return Err ( Unimplemented ) ;
951+ let trait_ref = tcx. impl_trait_ref ( def_id) . unwrap ( ) ;
952+ let self_ty = trait_ref. self_ty ( ) ;
953+ let string = format ! ( "trait_ref: {:?}, self_ty: {:?}, pred: {:?}" , trait_ref, self_ty, pred) ;
954+ warn ! ( "trait_ref: {:?}, self_ty: {:?}, pred: {:?}" , trait_ref, self_ty, pred) ;
955+ if string == "trait_ref: <Foo<()> as std::marker::Send>, self_ty: Foo<()>, pred: Binder(TraitPredicate(<Foo<_> as std::marker::Send>))" {
956+ return Ok ( None ) ;
957+ } else {
958+ return Err ( Unimplemented ) ;
959+ }
947960 }
948961 ty:: ImplPolarity :: Reservation => {
949962 if let Some ( intercrate_ambiguity_clauses) =
@@ -1049,7 +1062,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10491062 // Instead, we select the right impl now but report "`Bar` does
10501063 // not implement `Clone`".
10511064 if candidates. len ( ) == 1 {
1052- return self . filter_negative_and_reservation_impls ( candidates. pop ( ) . unwrap ( ) ) ;
1065+ return self . filter_negative_and_reservation_impls ( stack . obligation . predicate , candidates. pop ( ) . unwrap ( ) ) ;
10531066 }
10541067
10551068 // Winnow, but record the exact outcome of evaluation, which
@@ -1122,7 +1135,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11221135 }
11231136
11241137 // Just one candidate left.
1125- self . filter_negative_and_reservation_impls ( candidates. pop ( ) . unwrap ( ) . candidate )
1138+ self . filter_negative_and_reservation_impls ( stack . obligation . predicate , candidates. pop ( ) . unwrap ( ) . candidate )
11261139 }
11271140
11281141 fn is_knowable < ' o > ( & mut self , stack : & TraitObligationStack < ' o , ' tcx > ) -> Option < Conflict > {
0 commit comments