@@ -140,55 +140,59 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> boo
140
140
}
141
141
142
142
/// Checks if the lines immediately preceding the item contain a safety comment.
143
+ #[ allow( clippy:: collapsible_match) ]
143
144
fn item_has_safety_comment ( cx : & LateContext < ' _ > , item : & hir:: Item < ' _ > ) -> bool {
144
145
if span_from_macro_expansion_has_safety_comment ( cx, item. span ) || span_in_body_has_safety_comment ( cx, item. span ) {
145
146
return true ;
146
147
}
147
148
148
149
if item. span . ctxt ( ) == SyntaxContext :: root ( ) {
149
150
if let Some ( parent_node) = get_parent_node ( cx. tcx , item. hir_id ( ) ) {
150
- let mut span_before_item = None ;
151
- let mut hi = false ;
152
- if let Node :: Item ( parent_item) = parent_node {
153
- if let ItemKind :: Mod ( parent_mod) = & parent_item. kind {
154
- for ( idx, item_id) in parent_mod. item_ids . iter ( ) . enumerate ( ) {
155
- if * item_id == item. item_id ( ) {
156
- if idx == 0 {
157
- // mod A { /* comment */ unsafe impl T {} ... }
158
- // ^------------------------------------------^ gets this span
159
- // ^---------------------^ finally checks the text in this range
160
- hi = false ;
161
- span_before_item = Some ( parent_item. span ) ;
162
- } else {
163
- let prev_item = cx. tcx . hir ( ) . item ( parent_mod. item_ids [ idx - 1 ] ) ;
164
- // some_item /* comment */ unsafe impl T {}
165
- // ^-------^ gets this span
166
- // ^---------------^ finally checks the text in this range
167
- hi = true ;
168
- span_before_item = Some ( prev_item. span ) ;
169
- }
170
- break ;
151
+ let comment_start;
152
+ match parent_node {
153
+ Node :: Crate ( parent_mod) => {
154
+ comment_start = comment_start_before_impl_in_mod ( cx, parent_mod, parent_mod. spans . inner_span , item) ;
155
+ } ,
156
+ Node :: Item ( parent_item) => {
157
+ if let ItemKind :: Mod ( parent_mod) = & parent_item. kind {
158
+ comment_start = comment_start_before_impl_in_mod ( cx, parent_mod, parent_item. span , item) ;
159
+ } else {
160
+ // Doesn't support impls in this position. Pretend a comment was found.
161
+ return true ;
162
+ }
163
+ } ,
164
+ Node :: Stmt ( stmt) => {
165
+ if let Some ( stmt_parent) = get_parent_node ( cx. tcx , stmt. hir_id ) {
166
+ match stmt_parent {
167
+ Node :: Block ( block) => {
168
+ comment_start = walk_span_to_context ( block. span , SyntaxContext :: root ( ) ) . map ( Span :: lo) ;
169
+ } ,
170
+ _ => {
171
+ // Doesn't support impls in this position. Pretend a comment was found.
172
+ return true ;
173
+ } ,
171
174
}
175
+ } else {
176
+ // Doesn't support impls in this position. Pretend a comment was found.
177
+ return true ;
172
178
}
173
- }
179
+ } ,
180
+ _ => {
181
+ // Doesn't support impls in this position. Pretend a comment was found.
182
+ return true ;
183
+ } ,
174
184
}
175
- let span_before_item = span_before_item. unwrap ( ) ;
176
185
177
186
let source_map = cx. sess ( ) . source_map ( ) ;
178
- if let Some ( item_span) = walk_span_to_context ( item. span , SyntaxContext :: root ( ) )
179
- && let Some ( span_before_item) = walk_span_to_context ( span_before_item, SyntaxContext :: root ( ) )
180
- && let Ok ( unsafe_line) = source_map. lookup_line ( item_span. lo ( ) )
181
- && let Ok ( line_before_unsafe) = source_map. lookup_line ( if hi {
182
- span_before_item. hi ( )
183
- } else {
184
- span_before_item. lo ( )
185
- } )
186
- && Lrc :: ptr_eq ( & unsafe_line. sf , & line_before_unsafe. sf )
187
+ if let Some ( comment_start) = comment_start
188
+ && let Ok ( unsafe_line) = source_map. lookup_line ( item. span . lo ( ) )
189
+ && let Ok ( comment_start_line) = source_map. lookup_line ( comment_start)
190
+ && Lrc :: ptr_eq ( & unsafe_line. sf , & comment_start_line. sf )
187
191
&& let Some ( src) = unsafe_line. sf . src . as_deref ( )
188
192
{
189
- line_before_unsafe . line < unsafe_line. line && text_has_safety_comment (
193
+ comment_start_line . line < unsafe_line. line && text_has_safety_comment (
190
194
src,
191
- & unsafe_line. sf . lines [ line_before_unsafe . line + 1 ..=unsafe_line. line ] ,
195
+ & unsafe_line. sf . lines [ comment_start_line . line + 1 ..=unsafe_line. line ] ,
192
196
unsafe_line. sf . start_pos . to_usize ( ) ,
193
197
)
194
198
} else {
@@ -204,6 +208,35 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> bool {
204
208
}
205
209
}
206
210
211
+ fn comment_start_before_impl_in_mod (
212
+ cx : & LateContext < ' _ > ,
213
+ parent_mod : & hir:: Mod < ' _ > ,
214
+ parent_mod_span : Span ,
215
+ imple : & hir:: Item < ' _ > ,
216
+ ) -> Option < BytePos > {
217
+ parent_mod. item_ids . iter ( ) . enumerate ( ) . find_map ( |( idx, item_id) | {
218
+ if * item_id == imple. item_id ( ) {
219
+ if idx == 0 {
220
+ // mod A { /* comment */ unsafe impl T {} ... }
221
+ // ^------------------------------------------^ returns the start of this span
222
+ // ^---------------^ finally checks comments in this range
223
+ if let Some ( sp) = walk_span_to_context ( parent_mod_span, SyntaxContext :: root ( ) ) {
224
+ return Some ( sp. lo ( ) ) ;
225
+ }
226
+ } else {
227
+ // some_item /* comment */ unsafe impl T {}
228
+ // ^-------^ returns the end of this span
229
+ // ^---------------^ finally checks comments in this range
230
+ let prev_item = cx. tcx . hir ( ) . item ( parent_mod. item_ids [ idx - 1 ] ) ;
231
+ if let Some ( sp) = walk_span_to_context ( prev_item. span , SyntaxContext :: root ( ) ) {
232
+ return Some ( sp. hi ( ) ) ;
233
+ }
234
+ }
235
+ }
236
+ None
237
+ } )
238
+ }
239
+
207
240
fn span_from_macro_expansion_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> bool {
208
241
let source_map = cx. sess ( ) . source_map ( ) ;
209
242
let ctxt = span. ctxt ( ) ;
0 commit comments