Skip to content

Commit c781fc4

Browse files
committed
Auto merge of #36320 - GuillaumeGomez:rustdoc_test_info, r=alexcrichton
Add information in case of markdown block code test failure r? @steveklabnik cc @jonathandturner
2 parents 0648517 + b7f1d7a commit c781fc4

File tree

15 files changed

+207
-57
lines changed

15 files changed

+207
-57
lines changed

.gitmodules

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[submodule "src/rt/hoedown"]
99
path = src/rt/hoedown
1010
url = https://github.com/rust-lang/hoedown.git
11+
branch = rust-2015-09-21-do-not-delete
1112
[submodule "src/jemalloc"]
1213
path = src/jemalloc
1314
url = https://github.com/rust-lang/jemalloc.git

src/librustdoc/clean/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -521,17 +521,22 @@ impl<'a, I: IntoIterator<Item=&'a ast::NestedMetaItem>> NestedAttributesExt for
521521
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug, Default)]
522522
pub struct Attributes {
523523
pub doc_strings: Vec<String>,
524-
pub other_attrs: Vec<ast::Attribute>
524+
pub other_attrs: Vec<ast::Attribute>,
525+
pub span: Option<syntax_pos::Span>,
525526
}
526527

527528
impl Attributes {
528529
pub fn from_ast(attrs: &[ast::Attribute]) -> Attributes {
529530
let mut doc_strings = vec![];
531+
let mut sp = None;
530532
let other_attrs = attrs.iter().filter_map(|attr| {
531533
attr.with_desugared_doc(|attr| {
532534
if let Some(value) = attr.value_str() {
533535
if attr.check_name("doc") {
534536
doc_strings.push(value.to_string());
537+
if sp.is_none() {
538+
sp = Some(attr.span);
539+
}
535540
return None;
536541
}
537542
}
@@ -541,7 +546,8 @@ impl Attributes {
541546
}).collect();
542547
Attributes {
543548
doc_strings: doc_strings,
544-
other_attrs: other_attrs
549+
other_attrs: other_attrs,
550+
span: sp,
545551
}
546552
}
547553

src/librustdoc/html/markdown.rs

+37-19
Original file line numberDiff line numberDiff line change
@@ -71,29 +71,31 @@ const HOEDOWN_EXTENSIONS: libc::c_uint =
7171
enum hoedown_document {}
7272

7373
type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
74-
*const hoedown_buffer, *const hoedown_renderer_data);
74+
*const hoedown_buffer, *const hoedown_renderer_data,
75+
libc::size_t);
7576

7677
type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
77-
*const hoedown_renderer_data);
78+
*const hoedown_renderer_data, libc::size_t);
7879

7980
type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
80-
libc::c_int, *const hoedown_renderer_data);
81+
libc::c_int, *const hoedown_renderer_data,
82+
libc::size_t);
8183

8284
type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
83-
*const hoedown_renderer_data);
85+
*const hoedown_renderer_data, libc::size_t);
8486

8587
type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
86-
*const hoedown_renderer_data) -> libc::c_int;
88+
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;
8789

8890
type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
8991
*const hoedown_buffer, *const hoedown_buffer,
90-
*const hoedown_renderer_data) -> libc::c_int;
92+
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;
9193

9294
type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
93-
*const hoedown_renderer_data);
95+
*const hoedown_renderer_data, libc::size_t);
9496

9597
type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
96-
*const hoedown_renderer_data);
98+
*const hoedown_renderer_data, libc::size_t);
9799

98100
#[repr(C)]
99101
struct hoedown_renderer_data {
@@ -147,7 +149,8 @@ struct html_toc_data {
147149

148150
struct MyOpaque {
149151
dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
150-
*const hoedown_buffer, *const hoedown_renderer_data),
152+
*const hoedown_buffer, *const hoedown_renderer_data,
153+
libc::size_t),
151154
toc_builder: Option<TocBuilder>,
152155
}
153156

@@ -229,7 +232,8 @@ pub fn render(w: &mut fmt::Formatter,
229232
print_toc: bool,
230233
html_flags: libc::c_uint) -> fmt::Result {
231234
extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
232-
lang: *const hoedown_buffer, data: *const hoedown_renderer_data) {
235+
lang: *const hoedown_buffer, data: *const hoedown_renderer_data,
236+
line: libc::size_t) {
233237
unsafe {
234238
if orig_text.is_null() { return }
235239

@@ -246,7 +250,8 @@ pub fn render(w: &mut fmt::Formatter,
246250
let rlang = str::from_utf8(rlang).unwrap();
247251
if !LangString::parse(rlang).rust {
248252
(my_opaque.dfltblk)(ob, orig_text, lang,
249-
opaque as *const hoedown_renderer_data);
253+
opaque as *const hoedown_renderer_data,
254+
line);
250255
true
251256
} else {
252257
false
@@ -312,7 +317,8 @@ pub fn render(w: &mut fmt::Formatter,
312317
}
313318

314319
extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
315-
level: libc::c_int, data: *const hoedown_renderer_data) {
320+
level: libc::c_int, data: *const hoedown_renderer_data,
321+
_: libc::size_t) {
316322
// hoedown does this, we may as well too
317323
unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); }
318324

@@ -373,6 +379,7 @@ pub fn render(w: &mut fmt::Formatter,
373379
ob: *mut hoedown_buffer,
374380
text: *const hoedown_buffer,
375381
_: *const hoedown_renderer_data,
382+
_: libc::size_t
376383
) -> libc::c_int {
377384
let content = if text.is_null() {
378385
"".to_owned()
@@ -422,11 +429,12 @@ pub fn render(w: &mut fmt::Formatter,
422429
}
423430
}
424431

425-
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
432+
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, start_line: usize) {
426433
extern fn block(_ob: *mut hoedown_buffer,
427434
text: *const hoedown_buffer,
428435
lang: *const hoedown_buffer,
429-
data: *const hoedown_renderer_data) {
436+
data: *const hoedown_renderer_data,
437+
line: libc::size_t) {
430438
unsafe {
431439
if text.is_null() { return }
432440
let block_info = if lang.is_null() {
@@ -445,16 +453,19 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
445453
stripped_filtered_line(l).unwrap_or(l)
446454
});
447455
let text = lines.collect::<Vec<&str>>().join("\n");
456+
let line = tests.get_line() + line;
448457
tests.add_test(text.to_owned(),
449458
block_info.should_panic, block_info.no_run,
450459
block_info.ignore, block_info.test_harness,
451-
block_info.compile_fail, block_info.error_codes);
460+
block_info.compile_fail, block_info.error_codes,
461+
line);
452462
}
453463
}
454464

455465
extern fn header(_ob: *mut hoedown_buffer,
456466
text: *const hoedown_buffer,
457-
level: libc::c_int, data: *const hoedown_renderer_data) {
467+
level: libc::c_int, data: *const hoedown_renderer_data,
468+
_: libc::size_t) {
458469
unsafe {
459470
let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
460471
let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
@@ -468,6 +479,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
468479
}
469480
}
470481

482+
tests.set_line(start_line);
471483
unsafe {
472484
let ob = hoedown_buffer_new(DEF_OUNIT);
473485
let renderer = hoedown_html_renderer_new(0, 0);
@@ -488,6 +500,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
488500

489501
#[derive(Eq, PartialEq, Clone, Debug)]
490502
struct LangString {
503+
original: String,
491504
should_panic: bool,
492505
no_run: bool,
493506
ignore: bool,
@@ -500,6 +513,7 @@ struct LangString {
500513
impl LangString {
501514
fn all_false() -> LangString {
502515
LangString {
516+
original: String::new(),
503517
should_panic: false,
504518
no_run: false,
505519
ignore: false,
@@ -521,6 +535,7 @@ impl LangString {
521535
allow_error_code_check = true;
522536
}
523537

538+
data.original = string.to_owned();
524539
let tokens = string.split(|c: char|
525540
!(c == '_' || c == '-' || c.is_alphanumeric())
526541
);
@@ -586,7 +601,8 @@ pub fn plain_summary_line(md: &str) -> String {
586601
_link: *const hoedown_buffer,
587602
_title: *const hoedown_buffer,
588603
content: *const hoedown_buffer,
589-
data: *const hoedown_renderer_data) -> libc::c_int
604+
data: *const hoedown_renderer_data,
605+
_: libc::size_t) -> libc::c_int
590606
{
591607
unsafe {
592608
if !content.is_null() && (*content).size > 0 {
@@ -599,8 +615,9 @@ pub fn plain_summary_line(md: &str) -> String {
599615
}
600616

601617
extern fn normal_text(_ob: *mut hoedown_buffer,
602-
text: *const hoedown_buffer,
603-
data: *const hoedown_renderer_data)
618+
text: *const hoedown_buffer,
619+
data: *const hoedown_renderer_data,
620+
_: libc::size_t)
604621
{
605622
unsafe {
606623
let ob = (*data).opaque as *mut hoedown_buffer;
@@ -647,6 +664,7 @@ mod tests {
647664
test_harness: test_harness,
648665
compile_fail: compile_fail,
649666
error_codes: error_codes,
667+
original: s.to_owned(),
650668
})
651669
}
652670

src/librustdoc/markdown.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,9 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
154154
let mut opts = TestOptions::default();
155155
opts.no_crate_inject = true;
156156
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
157-
true, opts, maybe_sysroot);
158-
find_testable_code(&input_str, &mut collector);
157+
true, opts, maybe_sysroot, "input".to_string(),
158+
None);
159+
find_testable_code(&input_str, &mut collector, 0);
159160
test_args.insert(0, "rustdoctest".to_string());
160161
testing::test_main(&test_args, collector.tests);
161162
0

src/librustdoc/test.rs

+36-13
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use rustc_trans::back::link;
3737
use syntax::ast;
3838
use syntax::codemap::CodeMap;
3939
use syntax::feature_gate::UnstableFeatures;
40+
use syntax_pos::{BytePos, DUMMY_SP, Pos};
4041
use errors;
4142
use errors::emitter::ColorConfig;
4243

@@ -79,7 +80,7 @@ pub fn run(input: &str,
7980
let _ignore = dep_graph.in_ignore();
8081
let cstore = Rc::new(CStore::new(&dep_graph));
8182
let mut sess = session::build_session_(
82-
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap, cstore.clone(),
83+
sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(),
8384
);
8485
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
8586
sess.parse_sess.config =
@@ -96,13 +97,16 @@ pub fn run(input: &str,
9697
link::find_crate_name(None, &hir_forest.krate().attrs, &input)
9798
});
9899
let opts = scrape_test_config(hir_forest.krate());
100+
let filename = input_path.to_str().unwrap_or("").to_owned();
99101
let mut collector = Collector::new(crate_name,
100102
cfgs,
101103
libs,
102104
externs,
103105
false,
104106
opts,
105-
maybe_sysroot);
107+
maybe_sysroot,
108+
filename,
109+
Some(codemap));
106110

107111
{
108112
let dep_graph = DepGraph::new(false);
@@ -256,7 +260,9 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
256260
error_codes.retain(|err| !out.contains(err));
257261
}
258262
}
259-
Ok(()) if compile_fail => panic!("test compiled while it wasn't supposed to"),
263+
Ok(()) if compile_fail => {
264+
panic!("test compiled while it wasn't supposed to")
265+
}
260266
_ => {}
261267
}
262268
}
@@ -302,7 +308,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
302308
if should_panic && out.status.success() {
303309
panic!("test executable succeeded when it should have failed");
304310
} else if !should_panic && !out.status.success() {
305-
panic!("test executable failed:\n{}\n{}",
311+
panic!("test executable failed:\n{}\n{}\n",
306312
str::from_utf8(&out.stdout).unwrap_or(""),
307313
str::from_utf8(&out.stderr).unwrap_or(""));
308314
}
@@ -384,11 +390,15 @@ pub struct Collector {
384390
cratename: String,
385391
opts: TestOptions,
386392
maybe_sysroot: Option<PathBuf>,
393+
filename: String,
394+
start_line: usize,
395+
codemap: Option<Rc<CodeMap>>,
387396
}
388397

389398
impl Collector {
390399
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
391-
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>) -> Collector {
400+
use_headers: bool, opts: TestOptions, maybe_sysroot: Option<PathBuf>,
401+
filename: String, codemap: Option<Rc<CodeMap>>) -> Collector {
392402
Collector {
393403
tests: Vec::new(),
394404
names: Vec::new(),
@@ -401,18 +411,17 @@ impl Collector {
401411
cratename: cratename,
402412
opts: opts,
403413
maybe_sysroot: maybe_sysroot,
414+
filename: filename,
415+
start_line: 0,
416+
codemap: codemap,
404417
}
405418
}
406419

407420
pub fn add_test(&mut self, test: String,
408421
should_panic: bool, no_run: bool, should_ignore: bool,
409-
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>) {
410-
let name = if self.use_headers {
411-
let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
412-
format!("{}_{}", s, self.cnt)
413-
} else {
414-
format!("{}_{}", self.names.join("::"), self.cnt)
415-
};
422+
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
423+
line: usize) {
424+
let name = format!("{} - line {}", self.filename, line);
416425
self.cnt += 1;
417426
let cfgs = self.cfgs.clone();
418427
let libs = self.libs.clone();
@@ -456,6 +465,19 @@ impl Collector {
456465
});
457466
}
458467

468+
pub fn get_line(&self) -> usize {
469+
if let Some(ref codemap) = self.codemap{
470+
let line = codemap.lookup_char_pos(BytePos(self.start_line as u32)).line;
471+
if line > 0 { line - 1 } else { line }
472+
} else {
473+
self.start_line
474+
}
475+
}
476+
477+
pub fn set_line(&mut self, start_line: usize) {
478+
self.start_line = start_line;
479+
}
480+
459481
pub fn register_header(&mut self, name: &str, level: u32) {
460482
if self.use_headers && level == 1 {
461483
// we use these headings as test names, so it's good if
@@ -496,7 +518,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
496518
attrs.unindent_doc_comments();
497519
if let Some(doc) = attrs.doc_value() {
498520
self.collector.cnt = 0;
499-
markdown::find_testable_code(doc, self.collector);
521+
markdown::find_testable_code(doc, self.collector,
522+
attrs.span.unwrap_or(DUMMY_SP).lo.to_usize());
500523
}
501524

502525
nested(self);

0 commit comments

Comments
 (0)