@@ -3876,36 +3876,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3876
3876
call_sp : Span ,
3877
3877
args : & ' tcx [ hir:: Expr ] ,
3878
3878
) {
3879
- if !call_sp. desugaring_kind ( ) . is_some ( ) {
3880
- // We *do not* do this for desugared call spans to keep good diagnostics when involving
3881
- // the `?` operator.
3882
- for error in errors {
3883
- if let ty:: Predicate :: Trait ( predicate) = error. obligation . predicate {
3884
- // Collect the argument position for all arguments that could have caused this
3885
- // `FulfillmentError`.
3886
- let mut referenced_in = final_arg_types. iter ( )
3887
- . map ( |( i, checked_ty, _) | ( i, checked_ty) )
3888
- . chain ( final_arg_types. iter ( ) . map ( |( i, _, coerced_ty) | ( i, coerced_ty) ) )
3889
- . flat_map ( |( i, ty) | {
3890
- let ty = self . resolve_vars_if_possible ( ty) ;
3891
- // We walk the argument type because the argument's type could have
3892
- // been `Option<T>`, but the `FulfillmentError` references `T`.
3893
- ty. walk ( )
3894
- . filter ( |& ty| ty == predicate. skip_binder ( ) . self_ty ( ) )
3895
- . map ( move |_| * i)
3896
- } )
3897
- . collect :: < Vec < _ > > ( ) ;
3879
+ // We *do not* do this for desugared call spans to keep good diagnostics when involving
3880
+ // the `?` operator.
3881
+ if call_sp. desugaring_kind ( ) . is_some ( ) {
3882
+ return
3883
+ }
3884
+
3885
+ for error in errors {
3886
+ // Only if the cause is somewhere inside the expression we want try to point at arg.
3887
+ // Otherwise, it means that the cause is somewhere else and we should not change
3888
+ // anything because we can break the correct span.
3889
+ if !call_sp. contains ( error. obligation . cause . span ) {
3890
+ continue
3891
+ }
3892
+
3893
+ if let ty:: Predicate :: Trait ( predicate) = error. obligation . predicate {
3894
+ // Collect the argument position for all arguments that could have caused this
3895
+ // `FulfillmentError`.
3896
+ let mut referenced_in = final_arg_types. iter ( )
3897
+ . map ( |( i, checked_ty, _) | ( i, checked_ty) )
3898
+ . chain ( final_arg_types. iter ( ) . map ( |( i, _, coerced_ty) | ( i, coerced_ty) ) )
3899
+ . flat_map ( |( i, ty) | {
3900
+ let ty = self . resolve_vars_if_possible ( ty) ;
3901
+ // We walk the argument type because the argument's type could have
3902
+ // been `Option<T>`, but the `FulfillmentError` references `T`.
3903
+ ty. walk ( )
3904
+ . filter ( |& ty| ty == predicate. skip_binder ( ) . self_ty ( ) )
3905
+ . map ( move |_| * i)
3906
+ } )
3907
+ . collect :: < Vec < _ > > ( ) ;
3898
3908
3899
- // Both checked and coerced types could have matched, thus we need to remove
3900
- // duplicates.
3901
- referenced_in. dedup ( ) ;
3909
+ // Both checked and coerced types could have matched, thus we need to remove
3910
+ // duplicates.
3911
+ referenced_in. dedup ( ) ;
3902
3912
3903
- if let ( Some ( ref_in) , None ) = ( referenced_in. pop ( ) , referenced_in. pop ( ) ) {
3904
- // We make sure that only *one* argument matches the obligation failure
3905
- // and we assign the obligation's span to its expression's.
3906
- error. obligation . cause . span = args[ ref_in] . span ;
3907
- error. points_at_arg_span = true ;
3908
- }
3913
+ if let ( Some ( ref_in) , None ) = ( referenced_in. pop ( ) , referenced_in. pop ( ) ) {
3914
+ // We make sure that only *one* argument matches the obligation failure
3915
+ // and we assign the obligation's span to its expression's.
3916
+ error. obligation . cause . span = args[ ref_in] . span ;
3917
+ error. points_at_arg_span = true ;
3909
3918
}
3910
3919
}
3911
3920
}
0 commit comments