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