@@ -39,6 +39,21 @@ struct DiagnosticSpan {
39
39
expansion : Option < Box < DiagnosticSpanMacroExpansion > > ,
40
40
}
41
41
42
+ impl DiagnosticSpan {
43
+ /// Returns the deepest source span in the macro call stack with a given file name.
44
+ /// This is either the supplied span, or the span for some macro callsite that expanded to it.
45
+ fn first_callsite_in_file ( & self , file_name : & str ) -> & DiagnosticSpan {
46
+ if self . file_name == file_name {
47
+ self
48
+ } else {
49
+ self . expansion
50
+ . as_ref ( )
51
+ . map ( |origin| origin. span . first_callsite_in_file ( file_name) )
52
+ . unwrap_or ( self )
53
+ }
54
+ }
55
+ }
56
+
42
57
#[ derive( Deserialize , Clone ) ]
43
58
struct DiagnosticSpanMacroExpansion {
44
59
/// span where macro was applied to generate this code
@@ -89,15 +104,23 @@ fn push_expected_errors(expected_errors: &mut Vec<Error>,
89
104
diagnostic : & Diagnostic ,
90
105
default_spans : & [ & DiagnosticSpan ] ,
91
106
file_name : & str ) {
92
- let spans_in_this_file: Vec < _ > = diagnostic. spans
107
+ // In case of macro expansions, we need to get the span of the callsite
108
+ let spans_info_in_this_file: Vec < _ > = diagnostic
109
+ . spans
93
110
. iter ( )
94
- . filter ( |span| Path :: new ( & span. file_name ) == Path :: new ( & file_name) )
111
+ . map ( |span| ( span. is_primary , span. first_callsite_in_file ( file_name) ) )
112
+ . filter ( |( _, span) | Path :: new ( & span. file_name ) == Path :: new ( & file_name) )
95
113
. collect ( ) ;
96
114
97
- let primary_spans: Vec < _ > = spans_in_this_file. iter ( )
98
- . cloned ( )
99
- . filter ( |span| span. is_primary )
115
+ let spans_in_this_file: Vec < _ > = spans_info_in_this_file. iter ( )
116
+ . map ( |( _, span) | span)
117
+ . collect ( ) ;
118
+
119
+ let primary_spans: Vec < _ > = spans_info_in_this_file. iter ( )
120
+ . filter ( |( is_primary, _) | * is_primary)
121
+ . map ( |( _, span) | span)
100
122
. take ( 1 ) // sometimes we have more than one showing up in the json; pick first
123
+ . cloned ( )
101
124
. collect ( ) ;
102
125
let primary_spans = if primary_spans. is_empty ( ) {
103
126
// subdiagnostics often don't have a span of their own;
0 commit comments