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