@@ -934,16 +934,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
934
934
( result, dep_node)
935
935
}
936
936
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.
938
942
fn filter_negative_and_reservation_impls (
939
943
& mut self ,
944
+ pred : ty:: PolyTraitPredicate < ' tcx > ,
940
945
candidate : SelectionCandidate < ' tcx > ,
941
946
) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
942
947
if let ImplCandidate ( def_id) = candidate {
943
948
let tcx = self . tcx ( ) ;
944
949
match tcx. impl_polarity ( def_id) {
945
950
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
+ }
947
960
}
948
961
ty:: ImplPolarity :: Reservation => {
949
962
if let Some ( intercrate_ambiguity_clauses) =
@@ -1049,7 +1062,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1049
1062
// Instead, we select the right impl now but report "`Bar` does
1050
1063
// not implement `Clone`".
1051
1064
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 ( ) ) ;
1053
1066
}
1054
1067
1055
1068
// Winnow, but record the exact outcome of evaluation, which
@@ -1122,7 +1135,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1122
1135
}
1123
1136
1124
1137
// 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 )
1126
1139
}
1127
1140
1128
1141
fn is_knowable < ' o > ( & mut self , stack : & TraitObligationStack < ' o , ' tcx > ) -> Option < Conflict > {
0 commit comments