diff options
| author | Jonathan Turner <jturner@mozilla.com> | 2016-06-22 18:39:43 -0400 |
|---|---|---|
| committer | Jonathan Turner <jturner@mozilla.com> | 2016-06-23 08:07:35 -0400 |
| commit | f2fe204dcce8f6509e51b3c518fc02d7e0e25e92 (patch) | |
| tree | 497ce51943e4dd162a664852b412212da4485c81 /src/librustc_errors | |
| parent | 51deb4fedbdab4b9b5a7610985c0be54e89cae73 (diff) | |
| download | rust-f2fe204dcce8f6509e51b3c518fc02d7e0e25e92.tar.gz rust-f2fe204dcce8f6509e51b3c518fc02d7e0e25e92.zip | |
Consolidate codemap tests and fix more errors for travis
Diffstat (limited to 'src/librustc_errors')
| -rw-r--r-- | src/librustc_errors/emitter.rs | 255 | ||||
| -rw-r--r-- | src/librustc_errors/snippet/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_errors/snippet/test.rs | 598 |
3 files changed, 1 insertions, 854 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a31b1e876fa..d46a8f3c453 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -358,7 +358,7 @@ impl EmitterWriter { Ok(()) } - fn highlight_lines(&mut self, + pub fn highlight_lines(&mut self, msp: &MultiSpan, lvl: Level) -> io::Result<()> @@ -619,256 +619,3 @@ impl Write for Destination { } } } - - -#[cfg(test)] -mod test { - use errors::{Level, CodeSuggestion}; - use super::EmitterWriter; - use codemap::CodeMap; - use syntax_pos::{mk_sp, Span, MultiSpan, BytePos, NO_EXPANSION}; - use std::sync::{Arc, Mutex}; - use std::io::{self, Write}; - use std::str::from_utf8; - use std::rc::Rc; - - struct Sink(Arc<Mutex<Vec<u8>>>); - impl Write for Sink { - fn write(&mut self, data: &[u8]) -> io::Result<usize> { - Write::write(&mut *self.0.lock().unwrap(), data) - } - fn flush(&mut self) -> io::Result<()> { Ok(()) } - } - - /// Given a string like " ^~~~~~~~~~~~ ", produces a span - /// coverting that range. The idea is that the string has the same - /// length as the input, and we uncover the byte positions. Note - /// that this can span lines and so on. - fn span_from_selection(input: &str, selection: &str) -> Span { - assert_eq!(input.len(), selection.len()); - let left_index = selection.find('~').unwrap() as u32; - let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index); - Span { lo: BytePos(left_index), hi: BytePos(right_index + 1), expn_id: NO_EXPANSION } - } - - // Diagnostic doesn't align properly in span where line number increases by one digit - #[test] - fn test_hilight_suggestion_issue_11715() { - let data = Arc::new(Mutex::new(Vec::new())); - let cm = Rc::new(CodeMap::new()); - let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone()); - let content = "abcdefg - koksi - line3 - line4 - cinq - line6 - line7 - line8 - line9 - line10 - e-lä-vän - tolv - dreizehn - "; - let file = cm.new_filemap_and_lines("dummy.txt", None, content); - let start = file.lines.borrow()[10]; - let end = file.lines.borrow()[11]; - let sp = mk_sp(start, end); - let lvl = Level::Error; - println!("highlight_lines"); - ew.highlight_lines(&sp.into(), lvl).unwrap(); - println!("done"); - let vec = data.lock().unwrap().clone(); - let vec: &[u8] = &vec; - let str = from_utf8(vec).unwrap(); - println!("r#\"\n{}\"#", str); - assert_eq!(str, &r#" - --> dummy.txt:11:1 - |> -11 |> e-lä-vän - |> ^ -"#[1..]); - } - - #[test] - fn test_single_span_splice() { - // Test that a `MultiSpan` containing a single span splices a substition correctly - let cm = CodeMap::new(); - let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; - let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); - let sp = span_from_selection(inputtext, selection); - let msp: MultiSpan = sp.into(); - - // check that we are extracting the text we thought we were extracting - assert_eq!(&cm.span_to_snippet(sp).unwrap(), "BB\nCCC\nDDDDD"); - - let substitute = "ZZZZZZ".to_owned(); - let expected = "bbbbZZZZZZddddd"; - let suggest = CodeSuggestion { - msp: msp, - substitutes: vec![substitute], - }; - assert_eq!(suggest.splice_lines(&cm), expected); - } - - #[test] - fn test_multi_span_splice() { - // Test that a `MultiSpan` containing multiple spans splices a substition correctly - let cm = CodeMap::new(); - let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; - let selection1 = " \n \n \n \n ~ \n"; // intentionally out of order - let selection2 = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); - let sp1 = span_from_selection(inputtext, selection1); - let sp2 = span_from_selection(inputtext, selection2); - let msp: MultiSpan = MultiSpan::from_spans(vec![sp1, sp2]); - - let expected = "bbbbZZZZZZddddd\neXYZe"; - let suggest = CodeSuggestion { - msp: msp, - substitutes: vec!["ZZZZZZ".to_owned(), - "XYZ".to_owned()] - }; - - assert_eq!(suggest.splice_lines(&cm), expected); - } - - #[test] - fn test_multispan_highlight() { - let data = Arc::new(Mutex::new(Vec::new())); - let cm = Rc::new(CodeMap::new()); - let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone()); - - let inp = "_____aaaaaa____bbbbbb__cccccdd_"; - let sp1 = " ~~~~~~ "; - let sp2 = " ~~~~~~ "; - let sp3 = " ~~~~~ "; - let sp4 = " ~~~~ "; - let sp34 = " ~~~~~~~ "; - - let expect_start = &r#" - --> dummy.txt:1:6 - |> -1 |> _____aaaaaa____bbbbbb__cccccdd_ - |> ^^^^^^ ^^^^^^ ^^^^^^^ -"#[1..]; - - let span = |sp, expected| { - let sp = span_from_selection(inp, sp); - assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected); - sp - }; - cm.new_filemap_and_lines("dummy.txt", None, inp); - let sp1 = span(sp1, "aaaaaa"); - let sp2 = span(sp2, "bbbbbb"); - let sp3 = span(sp3, "ccccc"); - let sp4 = span(sp4, "ccdd"); - let sp34 = span(sp34, "cccccdd"); - - let spans = vec![sp1, sp2, sp3, sp4]; - - let test = |expected, highlight: &mut FnMut()| { - data.lock().unwrap().clear(); - highlight(); - let vec = data.lock().unwrap().clone(); - let actual = from_utf8(&vec[..]).unwrap(); - println!("actual=\n{}", actual); - assert_eq!(actual, expected); - }; - - let msp = MultiSpan::from_spans(vec![sp1, sp2, sp34]); - test(expect_start, &mut || { - diag.highlight_lines(&msp, Level::Error).unwrap(); - }); - test(expect_start, &mut || { - let msp = MultiSpan::from_spans(spans.clone()); - diag.highlight_lines(&msp, Level::Error).unwrap(); - }); - } - - #[test] - fn test_huge_multispan_highlight() { - let data = Arc::new(Mutex::new(Vec::new())); - let cm = Rc::new(CodeMap::new()); - let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone()); - - let inp = "aaaaa\n\ - aaaaa\n\ - aaaaa\n\ - bbbbb\n\ - ccccc\n\ - xxxxx\n\ - yyyyy\n\ - _____\n\ - ddd__eee_\n\ - elided\n\ - __f_gg"; - let file = cm.new_filemap_and_lines("dummy.txt", None, inp); - - let span = |lo, hi, (off_lo, off_hi)| { - let lines = file.lines.borrow(); - let (mut lo, mut hi): (BytePos, BytePos) = (lines[lo], lines[hi]); - lo.0 += off_lo; - hi.0 += off_hi; - mk_sp(lo, hi) - }; - let sp0 = span(4, 6, (0, 5)); - let sp1 = span(0, 6, (0, 5)); - let sp2 = span(8, 8, (0, 3)); - let sp3 = span(8, 8, (5, 8)); - let sp4 = span(10, 10, (2, 3)); - let sp5 = span(10, 10, (4, 6)); - - let expect0 = &r#" - --> dummy.txt:5:1 - |> -5 |> ccccc - |> ^ -... -9 |> ddd__eee_ - |> ^^^ ^^^ -10 |> elided -11 |> __f_gg - |> ^ ^^ -"#[1..]; - - let expect = &r#" - --> dummy.txt:1:1 - |> -1 |> aaaaa - |> ^ -... -9 |> ddd__eee_ - |> ^^^ ^^^ -10 |> elided -11 |> __f_gg - |> ^ ^^ -"#[1..]; - - macro_rules! test { - ($expected: expr, $highlight: expr) => ({ - data.lock().unwrap().clear(); - $highlight(); - let vec = data.lock().unwrap().clone(); - let actual = from_utf8(&vec[..]).unwrap(); - println!("actual:"); - println!("{}", actual); - println!("expected:"); - println!("{}", $expected); - assert_eq!(&actual[..], &$expected[..]); - }); - } - - let msp0 = MultiSpan::from_spans(vec![sp0, sp2, sp3, sp4, sp5]); - let msp = MultiSpan::from_spans(vec![sp1, sp2, sp3, sp4, sp5]); - - test!(expect0, || { - diag.highlight_lines(&msp0, Level::Error).unwrap(); - }); - test!(expect, || { - diag.highlight_lines(&msp, Level::Error).unwrap(); - }); - } -} diff --git a/src/librustc_errors/snippet/mod.rs b/src/librustc_errors/snippet/mod.rs index 59a9d5b05f9..c472994599c 100644 --- a/src/librustc_errors/snippet/mod.rs +++ b/src/librustc_errors/snippet/mod.rs @@ -17,8 +17,6 @@ use std::cmp; use std::rc::Rc; use std::mem; -mod test; - #[derive(Clone)] pub struct SnippetData { codemap: Rc<CodeMapper>, diff --git a/src/librustc_errors/snippet/test.rs b/src/librustc_errors/snippet/test.rs deleted file mode 100644 index f5faccbe528..00000000000 --- a/src/librustc_errors/snippet/test.rs +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Code for testing annotated snippets. - -#![cfg(test)] - -use codemap::{CodeMap}; -use syntax_pos::{NO_EXPANSION, Span, FileMap, BytePos}; -use std::rc::Rc; -use super::{RenderedLine, SnippetData}; - -/// Returns the span corresponding to the `n`th occurrence of -/// `substring` in `source_text`. -trait CodeMapExtension { - fn span_substr(&self, - file: &Rc<FileMap>, - source_text: &str, - substring: &str, - n: usize) - -> Span; -} - -impl CodeMapExtension for CodeMap { - fn span_substr(&self, - file: &Rc<FileMap>, - source_text: &str, - substring: &str, - n: usize) - -> Span - { - println!("span_substr(file={:?}/{:?}, substring={:?}, n={})", - file.name, file.start_pos, substring, n); - let mut i = 0; - let mut hi = 0; - loop { - let offset = source_text[hi..].find(substring).unwrap_or_else(|| { - panic!("source_text `{}` does not have {} occurrences of `{}`, only {}", - source_text, n, substring, i); - }); - let lo = hi + offset; - hi = lo + substring.len(); - if i == n { - let span = Span { - lo: BytePos(lo as u32 + file.start_pos.0), - hi: BytePos(hi as u32 + file.start_pos.0), - expn_id: NO_EXPANSION, - }; - assert_eq!(&self.span_to_snippet(span).unwrap()[..], - substring); - return span; - } - i += 1; - } - } -} - -fn splice(start: Span, end: Span) -> Span { - Span { - lo: start.lo, - hi: end.hi, - expn_id: NO_EXPANSION, - } -} - -fn make_string(lines: &[RenderedLine]) -> String { - lines.iter() - .flat_map(|rl| { - rl.text.iter() - .map(|s| &s.text[..]) - .chain(Some("\n")) - }) - .collect() -} - -#[test] -fn tab() { - let file_text = " -fn foo() { -\tbar; -} -"; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span_bar = cm.span_substr(&foo, file_text, "bar", 0); - - let mut snippet = SnippetData::new(cm, Some(span_bar)); - snippet.push(span_bar, true, None); - - let lines = snippet.render_lines(); - let text = make_string(&lines); - assert_eq!(&text[..], &" - --> foo.rs:3:2 - |> -3 |> \tbar; - |> \t^^^ -"[1..]); -} - -#[test] -fn one_line() { - let file_text = r#" -fn foo() { - vec.push(vec.pop().unwrap()); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0); - let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1); - let span_semi = cm.span_substr(&foo, file_text, ";", 0); - - let mut snippet = SnippetData::new(cm, None); - snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here"))); - snippet.push(span_vec1, false, Some(format!("error occurs here"))); - snippet.push(span_semi, false, Some(format!("previous borrow ends here"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - - let text: String = make_string(&lines); - - println!("text=\n{}", text); - assert_eq!(&text[..], &r#" - ::: foo.rs - |> -3 |> vec.push(vec.pop().unwrap()); - |> --- --- - previous borrow ends here - |> | | - |> | error occurs here - |> previous borrow of `vec` occurs here -"#[1..]); -} - -#[test] -fn two_files() { - let file_text_foo = r#" -fn foo() { - vec.push(vec.pop().unwrap()); -} -"#; - - let file_text_bar = r#" -fn bar() { - // these blank links here - // serve to ensure that the line numbers - // from bar.rs - // require more digits - - - - - - - - - - - vec.push(); - - // this line will get elided - - vec.pop().unwrap()); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo_map = cm.new_filemap_and_lines("foo.rs", None, file_text_foo); - let span_foo_vec0 = cm.span_substr(&foo_map, file_text_foo, "vec", 0); - let span_foo_vec1 = cm.span_substr(&foo_map, file_text_foo, "vec", 1); - let span_foo_semi = cm.span_substr(&foo_map, file_text_foo, ";", 0); - - let bar_map = cm.new_filemap_and_lines("bar.rs", None, file_text_bar); - let span_bar_vec0 = cm.span_substr(&bar_map, file_text_bar, "vec", 0); - let span_bar_vec1 = cm.span_substr(&bar_map, file_text_bar, "vec", 1); - let span_bar_semi = cm.span_substr(&bar_map, file_text_bar, ";", 0); - - let mut snippet = SnippetData::new(cm, Some(span_foo_vec1)); - snippet.push(span_foo_vec0, false, Some(format!("a"))); - snippet.push(span_foo_vec1, true, Some(format!("b"))); - snippet.push(span_foo_semi, false, Some(format!("c"))); - snippet.push(span_bar_vec0, false, Some(format!("d"))); - snippet.push(span_bar_vec1, false, Some(format!("e"))); - snippet.push(span_bar_semi, false, Some(format!("f"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - - let text: String = make_string(&lines); - - println!("text=\n{}", text); - - // Note that the `|>` remain aligned across both files: - assert_eq!(&text[..], &r#" - --> foo.rs:3:14 - |> -3 |> vec.push(vec.pop().unwrap()); - |> --- ^^^ - c - |> | | - |> | b - |> a - ::: bar.rs - |> -17 |> vec.push(); - |> --- - f - |> | - |> d -... -21 |> vec.pop().unwrap()); - |> --- e -"#[1..]); -} - -#[test] -fn multi_line() { - let file_text = r#" -fn foo() { - let name = find_id(&data, 22).unwrap(); - - // Add one more item we forgot to the vector. Silly us. - data.push(Data { name: format!("Hera"), id: 66 }); - - // Print everything out. - println!("Name: {:?}", name); - println!("Data: {:?}", data); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span_data0 = cm.span_substr(&foo, file_text, "data", 0); - let span_data1 = cm.span_substr(&foo, file_text, "data", 1); - let span_rbrace = cm.span_substr(&foo, file_text, "}", 3); - - let mut snippet = SnippetData::new(cm, None); - snippet.push(span_data0, false, Some(format!("immutable borrow begins here"))); - snippet.push(span_data1, false, Some(format!("mutable borrow occurs here"))); - snippet.push(span_rbrace, false, Some(format!("immutable borrow ends here"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - - let text: String = make_string(&lines); - - println!("text=\n{}", text); - assert_eq!(&text[..], &r#" - ::: foo.rs - |> -3 |> let name = find_id(&data, 22).unwrap(); - |> ---- immutable borrow begins here -... -6 |> data.push(Data { name: format!("Hera"), id: 66 }); - |> ---- mutable borrow occurs here -... -11 |> } - |> - immutable borrow ends here -"#[1..]); -} - -#[test] -fn overlapping() { - let file_text = r#" -fn foo() { - vec.push(vec.pop().unwrap()); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span0 = cm.span_substr(&foo, file_text, "vec.push", 0); - let span1 = cm.span_substr(&foo, file_text, "vec", 0); - let span2 = cm.span_substr(&foo, file_text, "ec.push", 0); - let span3 = cm.span_substr(&foo, file_text, "unwrap", 0); - - let mut snippet = SnippetData::new(cm, None); - snippet.push(span0, false, Some(format!("A"))); - snippet.push(span1, false, Some(format!("B"))); - snippet.push(span2, false, Some(format!("C"))); - snippet.push(span3, false, Some(format!("D"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - let text: String = make_string(&lines); - - println!("text=r#\"\n{}\".trim_left()", text); - assert_eq!(&text[..], &r#" - ::: foo.rs - |> -3 |> vec.push(vec.pop().unwrap()); - |> -------- ------ D - |> || - |> |C - |> A - |> B -"#[1..]); -} - -#[test] -fn one_line_out_of_order() { - let file_text = r#" -fn foo() { - vec.push(vec.pop().unwrap()); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0); - let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1); - let span_semi = cm.span_substr(&foo, file_text, ";", 0); - - // intentionally don't push the snippets left to right - let mut snippet = SnippetData::new(cm, None); - snippet.push(span_vec1, false, Some(format!("error occurs here"))); - snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here"))); - snippet.push(span_semi, false, Some(format!("previous borrow ends here"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - let text: String = make_string(&lines); - - println!("text=r#\"\n{}\".trim_left()", text); - assert_eq!(&text[..], &r#" - ::: foo.rs - |> -3 |> vec.push(vec.pop().unwrap()); - |> --- --- - previous borrow ends here - |> | | - |> | error occurs here - |> previous borrow of `vec` occurs here -"#[1..]); -} - -#[test] -fn elide_unnecessary_lines() { - let file_text = r#" -fn foo() { - let mut vec = vec![0, 1, 2]; - let mut vec2 = vec; - vec2.push(3); - vec2.push(4); - vec2.push(5); - vec2.push(6); - vec.push(7); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - let span_vec0 = cm.span_substr(&foo, file_text, "vec", 3); - let span_vec1 = cm.span_substr(&foo, file_text, "vec", 8); - - let mut snippet = SnippetData::new(cm, None); - snippet.push(span_vec0, false, Some(format!("`vec` moved here because it \ - has type `collections::vec::Vec<i32>`"))); - snippet.push(span_vec1, false, Some(format!("use of moved value: `vec`"))); - - let lines = snippet.render_lines(); - println!("{:#?}", lines); - let text: String = make_string(&lines); - println!("text=r#\"\n{}\".trim_left()", text); - assert_eq!(&text[..], &r#" - ::: foo.rs - |> -4 |> let mut vec2 = vec; - |> --- `vec` moved here because it has type `collections::vec::Vec<i32>` -... -9 |> vec.push(7); - |> --- use of moved value: `vec` -"#[1..]); -} - -#[test] -fn spans_without_labels() { - let file_text = r#" -fn foo() { - let mut vec = vec![0, 1, 2]; - let mut vec2 = vec; - vec2.push(3); - vec2.push(4); - vec2.push(5); - vec2.push(6); - vec.push(7); -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut snippet = SnippetData::new(cm.clone(), None); - for i in 0..4 { - let span_veci = cm.span_substr(&foo, file_text, "vec", i); - snippet.push(span_veci, false, None); - } - - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("text=&r#\"\n{}\n\"#[1..]", text); - assert_eq!(text, &r#" - ::: foo.rs - |> -3 |> let mut vec = vec![0, 1, 2]; - |> --- --- -4 |> let mut vec2 = vec; - |> --- --- -"#[1..]); -} - -#[test] -fn span_long_selection() { - let file_text = r#" -impl SomeTrait for () { - fn foo(x: u32) { - // impl 1 - // impl 2 - // impl 3 - } -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut snippet = SnippetData::new(cm.clone(), None); - let fn_span = cm.span_substr(&foo, file_text, "fn", 0); - let rbrace_span = cm.span_substr(&foo, file_text, "}", 0); - snippet.push(splice(fn_span, rbrace_span), false, None); - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("r#\"\n{}\"", text); - assert_eq!(text, &r#" - ::: foo.rs - |> -3 |> fn foo(x: u32) { - |> - -"#[1..]); -} - -#[test] -fn span_overlap_label() { - // Test that we don't put `x_span` to the right of its highlight, - // since there is another highlight that overlaps it. - - let file_text = r#" - fn foo(x: u32) { - } -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut snippet = SnippetData::new(cm.clone(), None); - let fn_span = cm.span_substr(&foo, file_text, "fn foo(x: u32)", 0); - let x_span = cm.span_substr(&foo, file_text, "x", 0); - snippet.push(fn_span, false, Some(format!("fn_span"))); - snippet.push(x_span, false, Some(format!("x_span"))); - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("r#\"\n{}\"", text); - assert_eq!(text, &r#" - ::: foo.rs - |> -2 |> fn foo(x: u32) { - |> -------------- - |> | | - |> | x_span - |> fn_span -"#[1..]); -} - -#[test] -fn span_overlap_label2() { - // Test that we don't put `x_span` to the right of its highlight, - // since there is another highlight that overlaps it. In this - // case, the overlap is only at the beginning, but it's still - // better to show the beginning more clearly. - - let file_text = r#" - fn foo(x: u32) { - } -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut snippet = SnippetData::new(cm.clone(), None); - let fn_span = cm.span_substr(&foo, file_text, "fn foo(x", 0); - let x_span = cm.span_substr(&foo, file_text, "x: u32)", 0); - snippet.push(fn_span, false, Some(format!("fn_span"))); - snippet.push(x_span, false, Some(format!("x_span"))); - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("r#\"\n{}\"", text); - assert_eq!(text, &r#" - ::: foo.rs - |> -2 |> fn foo(x: u32) { - |> -------------- - |> | | - |> | x_span - |> fn_span -"#[1..]); -} - -#[test] -fn span_overlap_label3() { - // Test that we don't put `x_span` to the right of its highlight, - // since there is another highlight that overlaps it. In this - // case, the overlap is only at the beginning, but it's still - // better to show the beginning more clearly. - - let file_text = r#" - fn foo() { - let closure = || { - inner - }; - } -} -"#; - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut snippet = SnippetData::new(cm.clone(), None); - - let closure_span = { - let closure_start_span = cm.span_substr(&foo, file_text, "||", 0); - let closure_end_span = cm.span_substr(&foo, file_text, "}", 0); - splice(closure_start_span, closure_end_span) - }; - - let inner_span = cm.span_substr(&foo, file_text, "inner", 0); - - snippet.push(closure_span, false, Some(format!("foo"))); - snippet.push(inner_span, false, Some(format!("bar"))); - - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("r#\"\n{}\"", text); - assert_eq!(text, &r#" - ::: foo.rs - |> -3 |> let closure = || { - |> - foo -4 |> inner - |> ----- bar -"#[1..]); -} - -#[test] -fn span_empty() { - // In one of the unit tests, we found that the parser sometimes - // gives empty spans, and in particular it supplied an EOF span - // like this one, which points at the very end. We want to - // fallback gracefully in this case. - - let file_text = r#" -fn main() { - struct Foo; - - impl !Sync for Foo {} - - unsafe impl Send for &'static Foo { - // error: cross-crate traits with a default impl, like `core::marker::Send`, - // can only be implemented for a struct/enum type, not - // `&'static Foo` -}"#; - - - let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); - - let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1); - rbrace_span.lo = rbrace_span.hi; - - let mut snippet = SnippetData::new(cm.clone(), Some(rbrace_span)); - snippet.push(rbrace_span, false, None); - let lines = snippet.render_lines(); - let text: String = make_string(&lines); - println!("r#\"\n{}\"", text); - assert_eq!(text, &r#" - --> foo.rs:11:2 - |> -11 |> } - |> - -"#[1..]); -} |
