Skip to content

Commit 5d27440

Browse files
Only take outer attributes into account when generating content between first non-crate items and the crate items
1 parent 49f1e9c commit 5d27440

File tree

2 files changed

+19
-120
lines changed

2 files changed

+19
-120
lines changed

src/librustdoc/doctest/make.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::sync::Arc;
77

88
use rustc_ast::token::{Delimiter, TokenKind};
99
use rustc_ast::tokenstream::TokenTree;
10-
use rustc_ast::{self as ast, HasAttrs, StmtKind};
10+
use rustc_ast::{self as ast, AttrStyle, HasAttrs, StmtKind};
1111
use rustc_errors::ColorConfig;
1212
use rustc_errors::emitter::stderr_destination;
1313
use rustc_parse::new_parser_from_source_str;
@@ -388,7 +388,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
388388
for attr in &item.attrs {
389389
let attr_name = attr.name_or_empty();
390390

391-
if attr.style == ast::AttrStyle::Outer || not_crate_attrs.contains(&attr_name) {
391+
if attr.style == AttrStyle::Outer || not_crate_attrs.contains(&attr_name) {
392392
// There is one exception to these attributes:
393393
// `#![allow(internal_features)]`. If this attribute is used, we need to
394394
// consider it only as a crate-level attribute.
@@ -447,7 +447,9 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
447447
// Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
448448
// tweak the span to include the attributes as well.
449449
let mut span = stmt.span;
450-
if let Some(attr) = stmt.kind.attrs().first() {
450+
if let Some(attr) =
451+
stmt.kind.attrs().iter().find(|attr| attr.style == AttrStyle::Outer)
452+
{
451453
span = span.with_lo(attr.span.lo());
452454
}
453455
if info.everything_else.is_empty()

src/librustdoc/doctest/tests.rs

+14-117
Original file line numberDiff line numberDiff line change
@@ -448,133 +448,30 @@ fn main() {}"
448448
assert_eq!((output, len), (expected, 1));
449449
}
450450

451+
// This test ensures that the only attributes taken into account when we switch between
452+
// "crate level" content and the rest doesn't include inner attributes span, as it would
453+
// include part of the item and generate broken code.
451454
#[test]
452-
fn comments() {
455+
fn inner_attributes() {
453456
let opts = default_global_opts("");
454-
let input = r##"
457+
let input = r#"
455458
//! A doc comment that applies to the implicit anonymous module of this crate
456459
457460
pub mod outer_module {
458-
459-
//! - Inner line doc
460461
//!! - Still an inner line doc (but with a bang at the beginning)
461-
462-
/*! - Inner block doc */
463-
/*!! - Still an inner block doc (but with a bang at the beginning) */
464-
465-
// - Only a comment
466-
/// - Outer line doc (exactly 3 slashes)
467-
//// - Only a comment
468-
469-
/* - Only a comment */
470-
/** - Outer block doc (exactly) 2 asterisks */
471-
/*** - Only a comment */
472-
473-
pub mod inner_module {}
474-
475-
pub mod nested_comments {
476-
/* In Rust /* we can /* nest comments */ */ */
477-
478-
// All three types of block comments can contain or be nested inside
479-
// any other type:
480-
481-
/* /* */ /** */ /*! */ */
482-
/*! /* */ /** */ /*! */ */
483-
/** /* */ /** */ /*! */ */
484-
pub mod dummy_item {}
485-
}
486-
487-
pub mod degenerate_cases {
488-
// empty inner line doc
489-
//!
490-
491-
// empty inner block doc
492-
/*!*/
493-
494-
// empty line comment
495-
//
496-
497-
// empty outer line doc
498-
///
499-
500-
// empty block comment
501-
/**/
502-
503-
pub mod dummy_item {}
504-
505-
// empty 2-asterisk block isn't a doc block, it is a block comment
506-
/***/
507-
508-
}
509-
510-
/* The next one isn't allowed because outer doc comments
511-
require an item that will receive the doc */
512-
513-
/// Where is my item?
514462
}
515-
"##;
516-
let expected = "
463+
"#;
464+
let expected = "#![allow(unused)]
465+
517466
//! A doc comment that applies to the implicit anonymous module of this crate
518467
519-
pub mod outer_module {
520468
521-
//! - Inner line doc
469+
fn main() {
470+
pub mod outer_module {
522471
//!! - Still an inner line doc (but with a bang at the beginning)
523-
524-
/*! - Inner block doc */
525-
/*!! - Still an inner block doc (but with a bang at the beginning) */
526-
527-
// - Only a comment
528-
/// - Outer line doc (exactly 3 slashes)
529-
//// - Only a comment
530-
531-
/* - Only a comment */
532-
/** - Outer block doc (exactly) 2 asterisks */
533-
/*** - Only a comment */
534-
535-
pub mod inner_module {}
536-
537-
pub mod nested_comments {
538-
/* In Rust /* we can /* nest comments */ */ */
539-
540-
// All three types of block comments can contain or be nested inside
541-
// any other type:
542-
543-
/* /* */ /** */ /*! */ */
544-
/*! /* */ /** */ /*! */ */
545-
/** /* */ /** */ /*! */ */
546-
pub mod dummy_item {}
547-
}
548-
549-
pub mod degenerate_cases {
550-
// empty inner line doc
551-
//!
552-
553-
// empty inner block doc
554-
/*!*/
555-
556-
// empty line comment
557-
//
558-
559-
// empty outer line doc
560-
///
561-
562-
// empty block comment
563-
/**/
564-
565-
pub mod dummy_item {}
566-
567-
// empty 2-asterisk block isn't a doc block, it is a block comment
568-
/***/
569-
570-
}
571-
572-
/* The next one isn't allowed because outer doc comments
573-
require an item that will receive the doc */
574-
575-
/// Where is my item?
576472
}
577-
".to_string();
473+
}"
474+
.to_string();
578475
let (output, len) = make_test(input, None, false, &opts, None);
579-
assert_eq!((output, len), (expected, 0));
580-
}
476+
assert_eq!((output, len), (expected, 2));
477+
}

0 commit comments

Comments
 (0)