@@ -2,6 +2,7 @@ use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item,
22use if_chain:: if_chain;
33use itertools:: Itertools ;
44use rustc_ast:: ast:: { AttrKind , Attribute } ;
5+ use rustc_ast:: token:: CommentKind ;
56use rustc_data_structures:: fx:: FxHashSet ;
67use rustc_hir as hir;
78use rustc_lint:: { LateContext , LateLintPass } ;
@@ -249,62 +250,52 @@ fn lint_for_missing_headers<'tcx>(
249250 }
250251}
251252
252- /// Cleanup documentation decoration (`///` and such) .
253+ /// Cleanup documentation decoration.
253254///
254255/// We can't use `rustc_ast::attr::AttributeMethods::with_desugared_doc` or
255256/// `rustc_ast::parse::lexer::comments::strip_doc_comment_decoration` because we
256257/// need to keep track of
257258/// the spans but this function is inspired from the later.
258259#[ allow( clippy:: cast_possible_truncation) ]
259260#[ must_use]
260- pub fn strip_doc_comment_decoration ( comment : & str , span : Span ) -> ( String , Vec < ( usize , Span ) > ) {
261+ pub fn strip_doc_comment_decoration ( doc : & str , comment_kind : CommentKind , span : Span ) -> ( String , Vec < ( usize , Span ) > ) {
261262 // one-line comments lose their prefix
262- const ONELINERS : & [ & str ] = & [ "///!" , "///" , "//!" , "//" ] ;
263- for prefix in ONELINERS {
264- if comment. starts_with ( * prefix) {
265- let doc = & comment[ prefix. len ( ) ..] ;
266- let mut doc = doc. to_owned ( ) ;
267- doc. push ( '\n' ) ;
268- return (
269- doc. to_owned ( ) ,
270- vec ! [ ( doc. len( ) , span. with_lo( span. lo( ) + BytePos ( prefix. len( ) as u32 ) ) ) ] ,
271- ) ;
272- }
263+ if comment_kind == CommentKind :: Line {
264+ let mut doc = doc. to_owned ( ) ;
265+ doc. push ( '\n' ) ;
266+ let len = doc. len ( ) ;
267+ return ( doc, vec ! [ ( len, span. with_lo( span. lo( ) + BytePos ( 3 ) ) ) ] ) ;
273268 }
274269
275- if comment. starts_with ( "/*" ) {
276- let doc = & comment[ 3 ..comment. len ( ) - 2 ] ;
277- let mut sizes = vec ! [ ] ;
278- let mut contains_initial_stars = false ;
279- for line in doc. lines ( ) {
280- let offset = line. as_ptr ( ) as usize - comment. as_ptr ( ) as usize ;
281- debug_assert_eq ! ( offset as u32 as usize , offset) ;
282- contains_initial_stars |= line. trim_start ( ) . starts_with ( '*' ) ;
283- // +1 for the newline
284- sizes. push ( ( line. len ( ) + 1 , span. with_lo ( span. lo ( ) + BytePos ( offset as u32 ) ) ) ) ;
285- }
286- if !contains_initial_stars {
287- return ( doc. to_string ( ) , sizes) ;
288- }
289- // remove the initial '*'s if any
290- let mut no_stars = String :: with_capacity ( doc. len ( ) ) ;
291- for line in doc. lines ( ) {
292- let mut chars = line. chars ( ) ;
293- while let Some ( c) = chars. next ( ) {
294- if c. is_whitespace ( ) {
295- no_stars. push ( c) ;
296- } else {
297- no_stars. push ( if c == '*' { ' ' } else { c } ) ;
298- break ;
299- }
270+ let mut sizes = vec ! [ ] ;
271+ let mut contains_initial_stars = false ;
272+ for line in doc. lines ( ) {
273+ let offset = line. as_ptr ( ) as usize - doc. as_ptr ( ) as usize ;
274+ debug_assert_eq ! ( offset as u32 as usize , offset) ;
275+ contains_initial_stars |= line. trim_start ( ) . starts_with ( '*' ) ;
276+ // +1 for the newline
277+ sizes. push ( ( line. len ( ) + 1 , span. with_lo ( span. lo ( ) + BytePos ( 3 + offset as u32 ) ) ) ) ;
278+ }
279+ if !contains_initial_stars {
280+ return ( doc. to_string ( ) , sizes) ;
281+ }
282+ // remove the initial '*'s if any
283+ let mut no_stars = String :: with_capacity ( doc. len ( ) ) ;
284+ for line in doc. lines ( ) {
285+ let mut chars = line. chars ( ) ;
286+ while let Some ( c) = chars. next ( ) {
287+ if c. is_whitespace ( ) {
288+ no_stars. push ( c) ;
289+ } else {
290+ no_stars. push ( if c == '*' { ' ' } else { c } ) ;
291+ break ;
300292 }
301- no_stars. push_str ( chars. as_str ( ) ) ;
302- no_stars. push ( '\n' ) ;
303293 }
304- return ( no_stars, sizes) ;
294+ no_stars. push_str ( chars. as_str ( ) ) ;
295+ no_stars. push ( '\n' ) ;
305296 }
306297
307- panic ! ( "not a doc-comment: {}" , comment ) ;
298+ ( no_stars , sizes )
308299}
309300
310301#[ derive( Copy , Clone ) ]
@@ -318,9 +309,8 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
318309 let mut spans = vec ! [ ] ;
319310
320311 for attr in attrs {
321- if let AttrKind :: DocComment ( ref comment) = attr. kind {
322- let comment = comment. to_string ( ) ;
323- let ( comment, current_spans) = strip_doc_comment_decoration ( & comment, attr. span ) ;
312+ if let AttrKind :: DocComment ( comment_kind, comment) = attr. kind {
313+ let ( comment, current_spans) = strip_doc_comment_decoration ( & comment. as_str ( ) , comment_kind, attr. span ) ;
324314 spans. extend_from_slice ( & current_spans) ;
325315 doc. push_str ( & comment) ;
326316 } else if attr. has_name ( sym ! ( doc) ) {
0 commit comments