11
11
use Span ;
12
12
13
13
use rustc_errors as errors;
14
- use syntax_pos:: MultiSpan ;
15
14
16
15
/// An enum representing a diagnostic level.
17
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
16
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
18
17
#[ derive( Copy , Clone , Debug ) ]
19
18
#[ non_exhaustive]
20
19
pub enum Level {
@@ -28,43 +27,74 @@ pub enum Level {
28
27
Help ,
29
28
}
30
29
30
+ /// Trait implemented by types that can be converted into a set of `Span`s.
31
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
32
+ pub trait MultiSpan {
33
+ /// Converts `self` into a `Vec<Span>`.
34
+ fn into_spans ( self ) -> Vec < Span > ;
35
+ }
36
+
37
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
38
+ impl MultiSpan for Span {
39
+ fn into_spans ( self ) -> Vec < Span > {
40
+ vec ! [ self ]
41
+ }
42
+ }
43
+
44
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
45
+ impl MultiSpan for Vec < Span > {
46
+ fn into_spans ( self ) -> Vec < Span > {
47
+ self
48
+ }
49
+ }
50
+
51
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
52
+ impl < ' a > MultiSpan for & ' a [ Span ] {
53
+ fn into_spans ( self ) -> Vec < Span > {
54
+ self . to_vec ( )
55
+ }
56
+ }
57
+
31
58
/// A structure representing a diagnostic message and associated children
32
59
/// messages.
33
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
60
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
34
61
#[ derive( Clone , Debug ) ]
35
62
pub struct Diagnostic {
36
63
level : Level ,
37
64
message : String ,
38
- span : Option < Span > ,
65
+ spans : Vec < Span > ,
39
66
children : Vec < Diagnostic >
40
67
}
41
68
42
69
macro_rules! diagnostic_child_methods {
43
70
( $spanned: ident, $regular: ident, $level: expr) => (
44
71
/// Add a new child diagnostic message to `self` with the level
45
- /// identified by this methods name with the given `span` and `message`.
46
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356" ) ]
47
- pub fn $spanned<T : Into <String >>( mut self , span: Span , message: T ) -> Diagnostic {
48
- self . children. push( Diagnostic :: spanned( span, $level, message) ) ;
72
+ /// identified by this method's name with the given `spans` and
73
+ /// `message`.
74
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
75
+ pub fn $spanned<S , T >( mut self , spans: S , message: T ) -> Diagnostic
76
+ where S : MultiSpan , T : Into <String >
77
+ {
78
+ self . children. push( Diagnostic :: spanned( spans, $level, message) ) ;
49
79
self
50
80
}
51
81
52
82
/// Add a new child diagnostic message to `self` with the level
53
83
/// identified by this method's name with the given `message`.
54
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
84
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
55
85
pub fn $regular<T : Into <String >>( mut self , message: T ) -> Diagnostic {
56
86
self . children. push( Diagnostic :: new( $level, message) ) ;
57
87
self
58
88
}
59
89
)
60
90
}
61
91
62
- #[ derive( Debug , Clone ) ]
63
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356" ) ]
64
92
/// Iterator over the children diagnostics of a `Diagnostic`.
93
+ #[ derive( Debug , Clone ) ]
94
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
65
95
pub struct Children < ' a > ( :: std:: slice:: Iter < ' a , Diagnostic > ) ;
66
96
67
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
97
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
68
98
impl < ' a > Iterator for Children < ' a > {
69
99
type Item = & ' a Diagnostic ;
70
100
@@ -73,27 +103,29 @@ impl<'a> Iterator for Children<'a> {
73
103
}
74
104
}
75
105
76
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
106
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
77
107
impl Diagnostic {
78
108
/// Create a new diagnostic with the given `level` and `message`.
79
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
109
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
80
110
pub fn new < T : Into < String > > ( level : Level , message : T ) -> Diagnostic {
81
111
Diagnostic {
82
112
level : level,
83
113
message : message. into ( ) ,
84
- span : None ,
114
+ spans : vec ! [ ] ,
85
115
children : vec ! [ ]
86
116
}
87
117
}
88
118
89
119
/// Create a new diagnostic with the given `level` and `message` pointing to
90
- /// the given `span`.
91
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356" ) ]
92
- pub fn spanned < T : Into < String > > ( span : Span , level : Level , message : T ) -> Diagnostic {
120
+ /// the given set of `spans`.
121
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
122
+ pub fn spanned < S , T > ( spans : S , level : Level , message : T ) -> Diagnostic
123
+ where S : MultiSpan , T : Into < String >
124
+ {
93
125
Diagnostic {
94
126
level : level,
95
127
message : message. into ( ) ,
96
- span : Some ( span ) ,
128
+ spans : spans . into_spans ( ) ,
97
129
children : vec ! [ ]
98
130
}
99
131
}
@@ -104,61 +136,62 @@ impl Diagnostic {
104
136
diagnostic_child_methods ! ( span_help, help, Level :: Help ) ;
105
137
106
138
/// Returns the diagnostic `level` for `self`.
107
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
139
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
108
140
pub fn level ( & self ) -> Level {
109
141
self . level
110
142
}
111
143
112
144
/// Sets the level in `self` to `level`.
113
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
145
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
114
146
pub fn set_level ( & mut self , level : Level ) {
115
147
self . level = level;
116
148
}
117
149
118
150
/// Returns the message in `self`.
119
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
151
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
120
152
pub fn message ( & self ) -> & str {
121
153
& self . message
122
154
}
123
155
124
156
/// Sets the message in `self` to `message`.
125
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
157
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
126
158
pub fn set_message < T : Into < String > > ( & mut self , message : T ) {
127
159
self . message = message. into ( ) ;
128
160
}
129
161
130
- /// Returns the `Span` in `self`.
131
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
132
- pub fn span ( & self ) -> Option < Span > {
133
- self . span
162
+ /// Returns the `Span`s in `self`.
163
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
164
+ pub fn spans ( & self ) -> & [ Span ] {
165
+ & self . spans
134
166
}
135
167
136
- /// Sets the `Span` in `self` to `span `.
137
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
138
- pub fn set_span ( & mut self , span : Span ) {
139
- self . span = Some ( span ) ;
168
+ /// Sets the `Span`s in `self` to `spans `.
169
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
170
+ pub fn set_spans < S : MultiSpan > ( & mut self , spans : S ) {
171
+ self . spans = spans . into_spans ( ) ;
140
172
}
141
173
142
174
/// Returns an iterator over the children diagnostics of `self`.
143
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
175
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
144
176
pub fn children ( & self ) -> Children {
145
177
Children ( self . children . iter ( ) )
146
178
}
147
179
148
180
/// Emit the diagnostic.
149
- #[ unstable( feature = "proc_macro_diagnostic" , issue = "38356 " ) ]
181
+ #[ unstable( feature = "proc_macro_diagnostic" , issue = "54140 " ) ]
150
182
pub fn emit ( self ) {
183
+ fn to_internal ( spans : Vec < Span > ) -> :: syntax_pos:: MultiSpan {
184
+ let spans: Vec < _ > = spans. into_iter ( ) . map ( |s| s. 0 ) . collect ( ) ;
185
+ :: syntax_pos:: MultiSpan :: from_spans ( spans)
186
+ }
187
+
151
188
let level = self . level . to_internal ( ) ;
152
189
let mut diag = errors:: Diagnostic :: new ( level, & * self . message ) ;
153
-
154
- if let Some ( span) = self . span {
155
- diag. set_span ( span. 0 ) ;
156
- }
190
+ diag. set_span ( to_internal ( self . spans ) ) ;
157
191
158
192
for child in self . children {
159
- let span = child. span . map_or ( MultiSpan :: new ( ) , |s| s. 0 . into ( ) ) ;
160
193
let level = child. level . to_internal ( ) ;
161
- diag. sub ( level, & * child. message , span , None ) ;
194
+ diag. sub ( level, & * child. message , to_internal ( child . spans ) , None ) ;
162
195
}
163
196
164
197
:: __internal:: with_sess ( move |sess, _| {
0 commit comments