upgrade rustdoc's pulldown-cmark to 0.4.1

This commit is contained in:
Andy Russell 2019-04-20 13:03:59 -04:00
parent a850a42649
commit 303016485b
No known key found for this signature in database
GPG Key ID: BE2221033EDBC374
8 changed files with 113 additions and 124 deletions

View File

@ -10,7 +10,7 @@ name = "aho-corasick"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -972,7 +972,7 @@ name = "fwdansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1027,7 +1027,7 @@ dependencies = [
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1143,7 +1143,7 @@ dependencies = [
"globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1441,7 +1441,7 @@ dependencies = [
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1469,7 +1469,7 @@ dependencies = [
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1494,13 +1494,8 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.1.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memmap"
@ -2004,6 +1999,16 @@ dependencies = [
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pulldown-cmark"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.2"
@ -2169,7 +2174,7 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2181,7 +2186,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3015,7 +3020,7 @@ version = "0.0.0"
dependencies = [
"minifier 0.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3774,6 +3779,14 @@ name = "ucd-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
@ -4132,7 +4145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
"checksum mdbook 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba0d44cb4089c741b9a91f3e5218298a40699c2f3a070a85014eed290c60819"
"checksum measureme 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "36bb2b263a6795d352035024d6b30ce465bb79a5e5280d74c3b5f8464c657bcc"
"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum minifier 0.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4950cb2617b1933e2da0446e864dfe0d6a22c22ff72297996c46e6a63b210b"
@ -4184,6 +4197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f5844db2f839e97e3021980975f6ebf8691d9b9b2ca67ed3feb38dc3edb52c"
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
"checksum pulldown-cmark 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d1b74cc784b038a9921fd1a48310cc2e238101aa8ae0b94201e2d85121dd68b5"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
@ -4293,6 +4307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41d17211f887da8e4a70a45b9536f26fc5de166b81e2d5d80de4a17fd22553bd"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"

View File

@ -9,7 +9,7 @@ name = "rustdoc"
path = "lib.rs"
[dependencies]
pulldown-cmark = { version = "0.1.2", default-features = false }
pulldown-cmark = { version = "0.4.1", default-features = false }
minifier = "0.0.29"
tempfile = "3"
parking_lot = "0.7"

View File

@ -33,8 +33,11 @@ use crate::html::toc::TocBuilder;
use crate::html::highlight;
use crate::test;
use pulldown_cmark::{html, Event, Tag, Parser};
use pulldown_cmark::{Options, OPTION_ENABLE_FOOTNOTES, OPTION_ENABLE_TABLES};
use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag};
fn opts() -> Options {
Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES
}
/// A unit struct which has the `fmt::Display` trait implemented. When
/// formatted, this struct will emit the HTML corresponding to the rendered
@ -297,12 +300,11 @@ impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, 'b, I>
fn next(&mut self) -> Option<Self::Item> {
let event = self.inner.next();
if let Some(Event::Start(Tag::Link(dest, text))) = event {
if let Some(&(_, ref replace)) = self.links.into_iter().find(|link| &*link.0 == &*dest)
{
Some(Event::Start(Tag::Link(replace.to_owned().into(), text)))
if let Some(Event::Start(Tag::Link(kind, dest, text))) = event {
if let Some(&(_, ref replace)) = self.links.iter().find(|link| link.0 == *dest) {
Some(Event::Start(Tag::Link(kind, replace.to_owned().into(), text)))
} else {
Some(Event::Start(Tag::Link(dest, text)))
Some(Event::Start(Tag::Link(kind, dest, text)))
}
} else {
event
@ -393,7 +395,7 @@ fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
| Tag::Emphasis
| Tag::Strong
| Tag::Code
| Tag::Link(_, _)
| Tag::Link(..)
| Tag::BlockQuote => true,
_ => false,
}
@ -520,63 +522,39 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
}
}
pub struct TestableCodeError(());
impl fmt::Display for TestableCodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid start of a new code block")
}
}
pub fn find_testable_code<T: test::Tester>(
doc: &str,
tests: &mut T,
error_codes: ErrorCodes,
) -> Result<(), TestableCodeError> {
pub fn find_testable_code<T: test::Tester>(doc: &str, tests: &mut T, error_codes: ErrorCodes) {
let mut parser = Parser::new(doc);
let mut prev_offset = 0;
let mut nb_lines = 0;
let mut register_header = None;
'main: while let Some(event) = parser.next() {
while let Some(event) = parser.next() {
match event {
Event::Start(Tag::CodeBlock(s)) => {
let offset = parser.get_offset();
let block_info = if s.is_empty() {
LangString::all_false()
} else {
LangString::parse(&*s, error_codes)
};
if !block_info.rust {
continue
continue;
}
let mut test_s = String::new();
let mut offset = None;
loop {
let event = parser.next();
if let Some(event) = event {
match event {
Event::End(Tag::CodeBlock(_)) => break,
Event::Text(ref s) => {
test_s.push_str(s);
if offset.is_none() {
offset = Some(parser.get_offset());
}
}
_ => {}
}
} else {
break 'main;
}
}
if let Some(offset) = offset {
let lines = test_s.lines().map(|l| map_line(l).for_code());
let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
nb_lines += doc[prev_offset..offset].lines().count();
let line = tests.get_line() + (nb_lines - 1);
tests.add_test(text, block_info, line);
prev_offset = offset;
} else {
return Err(TestableCodeError(()));
while let Some(Event::Text(s)) = parser.next() {
test_s.push_str(&s);
}
let text = test_s
.lines()
.map(|l| map_line(l).for_code())
.collect::<Vec<Cow<'_, str>>>()
.join("\n");
nb_lines += doc[prev_offset..offset].lines().count();
let line = tests.get_line() + nb_lines;
tests.add_test(text, block_info, line);
prev_offset = offset;
}
Event::Start(Tag::Header(level)) => {
register_header = Some(level as u32);
@ -593,7 +571,6 @@ pub fn find_testable_code<T: test::Tester>(
_ => {}
}
}
Ok(())
}
#[derive(Eq, PartialEq, Clone, Debug)]
@ -687,10 +664,6 @@ impl<'a> fmt::Display for Markdown<'a> {
// This is actually common enough to special-case
if md.is_empty() { return Ok(()) }
let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
let replacer = |_: &str, s: &str| {
if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) {
Some((replace.clone(), s.to_owned()))
@ -699,7 +672,7 @@ impl<'a> fmt::Display for Markdown<'a> {
}
};
let p = Parser::new_with_broken_link_callback(md, opts, Some(&replacer));
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&replacer));
let mut s = String::with_capacity(md.len() * 3 / 2);
@ -718,11 +691,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
let MarkdownWithToc(md, ref ids, codes) = *self;
let mut ids = ids.borrow_mut();
let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
let p = Parser::new_ext(md, opts);
let p = Parser::new_ext(md, opts());
let mut s = String::with_capacity(md.len() * 3 / 2);
@ -748,11 +717,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
// This is actually common enough to special-case
if md.is_empty() { return Ok(()) }
let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
let p = Parser::new_ext(md, opts);
let p = Parser::new_ext(md, opts());
// Treat inline HTML as plain text.
let p = p.map(|event| match event {
@ -868,10 +833,6 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
return vec![];
}
let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
let mut links = vec![];
let shortcut_links = RefCell::new(vec![]);
@ -894,8 +855,7 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
shortcut_links.borrow_mut().push((s.to_owned(), locate(s)));
None
};
let p = Parser::new_with_broken_link_callback(md, opts,
Some(&push));
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&push));
// There's no need to thread an IdMap through to here because
// the IDs generated aren't going to be emitted anywhere.
@ -903,11 +863,11 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
for ev in iter {
if let Event::Start(Tag::Link(dest, _)) = ev {
if let Event::Start(Tag::Link(_, dest, _)) = ev {
debug!("found link: {}", dest);
links.push(match dest {
Cow::Borrowed(s) => (s.to_owned(), locate(s)),
Cow::Owned(s) => (s, None),
CowStr::Borrowed(s) => (s.to_owned(), locate(s)),
s @ CowStr::Boxed(..) | s @ CowStr::Inlined(..) => (s.into_string(), None),
});
}
}
@ -939,10 +899,7 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
return code_blocks;
}
let mut opts = Options::empty();
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
let mut p = Parser::new_ext(md, opts);
let mut p = Parser::new_ext(md, opts());
let mut code_block_start = 0;
let mut code_start = 0;
@ -1013,7 +970,7 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
end: code_end,
},
syntax: if !syntax.is_empty() {
Some(syntax.into_owned())
Some(syntax.into_string())
} else {
None
},

View File

@ -143,10 +143,9 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
options.linker, options.edition, options.persist_doctests);
collector.set_position(DUMMY_SP);
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
let res = find_testable_code(&input_str, &mut collector, codes);
if let Err(err) = res {
diag.span_warn(DUMMY_SP, &err.to_string());
}
find_testable_code(&input_str, &mut collector, codes);
options.test_args.insert(0, "rustdoctest".to_string());
testing::test_main(&options.test_args, collector.tests,
testing::Options::new().display_output(options.display_warnings));

View File

@ -333,24 +333,24 @@ pub fn look_for_tests<'tcx>(
found_tests: 0,
};
if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() {
if check_missing_code == true && tests.found_tests == 0 {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
hir::CRATE_HIR_ID,
span_of_attrs(&item.attrs),
"Missing code example in this documentation");
diag.emit();
} else if check_missing_code == false &&
tests.found_tests > 0 &&
!cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::PRIVATE_DOC_TESTS,
hir::CRATE_HIR_ID,
span_of_attrs(&item.attrs),
"Documentation test in private item");
diag.emit();
}
find_testable_code(&dox, &mut tests, ErrorCodes::No);
if check_missing_code == true && tests.found_tests == 0 {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
hir::CRATE_HIR_ID,
span_of_attrs(&item.attrs),
"Missing code example in this documentation");
diag.emit();
} else if check_missing_code == false &&
tests.found_tests > 0 &&
!cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::PRIVATE_DOC_TESTS,
hir::CRATE_HIR_ID,
span_of_attrs(&item.attrs),
"Documentation test in private item");
diag.emit();
}
}

View File

@ -796,11 +796,7 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
// anything else, this will combine them for us.
if let Some(doc) = attrs.collapsed_doc_value() {
self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP));
let res = markdown::find_testable_code(&doc, self.collector, self.codes);
if let Err(err) = res {
self.sess.diagnostic().span_warn(attrs.span.unwrap_or(DUMMY_SP),
&err.to_string());
}
markdown::find_testable_code(&doc, self.collector, self.codes);
}
nested(self);

View File

@ -5,4 +5,9 @@
all:
$(RUSTDOC) --test input.rs > $(TMPDIR)/output || true
$(CGREP) 'input.rs - foo (line 5)' < $(TMPDIR)/output
$(CGREP) 'input.rs:7:15' < $(TMPDIR)/output
$(CGREP) 'input.rs - bar (line 15)' < $(TMPDIR)/output
$(CGREP) 'input.rs:17:15' < $(TMPDIR)/output
$(CGREP) 'input.rs - bar (line 24)' < $(TMPDIR)/output
$(CGREP) 'input.rs:26:15' < $(TMPDIR)/output

View File

@ -9,3 +9,20 @@
pub fn foo() {
}
/// Add some text around the test...
///
/// ```rust
/// #![feature(nll)]
/// let x: char = 1;
/// ```
///
/// ...to make sure that the line number is still correct.
///
/// Let's also add a second test in the same doc comment.
///
/// ```rust
/// #![feature(nll)]
/// let x: char = 1;
/// ```
pub fn bar() {}