Skip to content

Commit a5b8851

Browse files
committed
Added consumption logic for external sources in FileMap
We now fetch source lines from the `external_src` member as a secondary fallback if no regular source is present, that is, if the file map belongs to an external crate and the source has been fetched from disk.
1 parent c04aa4e commit a5b8851

File tree

4 files changed

+39
-26
lines changed

4 files changed

+39
-26
lines changed

src/librustc_errors/emitter.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use RenderSpan::*;
1717
use snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
1818
use styled_buffer::StyledBuffer;
1919

20+
use std::borrow::Cow;
2021
use std::io::prelude::*;
2122
use std::io;
2223
use std::rc::Rc;
@@ -911,7 +912,8 @@ impl EmitterWriter {
911912
// Print out the annotate source lines that correspond with the error
912913
for annotated_file in annotated_files {
913914
// we can't annotate anything if the source is unavailable.
914-
if annotated_file.file.src.is_none() {
915+
if annotated_file.file.src.is_none()
916+
&& annotated_file.file.external_src.borrow().is_absent() {
915917
continue;
916918
}
917919

@@ -1012,7 +1014,7 @@ impl EmitterWriter {
10121014
} else if line_idx_delta == 2 {
10131015
let unannotated_line = annotated_file.file
10141016
.get_line(annotated_file.lines[line_idx].line_index)
1015-
.unwrap_or("");
1017+
.unwrap_or_else(|| Cow::from(""));
10161018

10171019
let last_buffer_line_num = buffer.num_lines();
10181020

src/librustc_errors/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use self::Level::*;
3737

3838
use emitter::{Emitter, EmitterWriter};
3939

40+
use std::borrow::Cow;
4041
use std::cell::{RefCell, Cell};
4142
use std::{error, fmt};
4243
use std::rc::Rc;
@@ -122,7 +123,7 @@ impl CodeSuggestion {
122123
use syntax_pos::{CharPos, Loc, Pos};
123124

124125
fn push_trailing(buf: &mut String,
125-
line_opt: Option<&str>,
126+
line_opt: Option<&Cow<str>>,
126127
lo: &Loc,
127128
hi_opt: Option<&Loc>) {
128129
let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi| hi.col.to_usize()));
@@ -184,13 +185,13 @@ impl CodeSuggestion {
184185
let cur_lo = cm.lookup_char_pos(sp.lo);
185186
for (buf, substitute) in bufs.iter_mut().zip(substitutes) {
186187
if prev_hi.line == cur_lo.line {
187-
push_trailing(buf, prev_line, &prev_hi, Some(&cur_lo));
188+
push_trailing(buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
188189
} else {
189-
push_trailing(buf, prev_line, &prev_hi, None);
190+
push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
190191
// push lines between the previous and current span (if any)
191192
for idx in prev_hi.line..(cur_lo.line - 1) {
192193
if let Some(line) = fm.get_line(idx) {
193-
buf.push_str(line);
194+
buf.push_str(line.as_ref());
194195
buf.push('\n');
195196
}
196197
}
@@ -206,7 +207,7 @@ impl CodeSuggestion {
206207
for buf in &mut bufs {
207208
// if the replacement already ends with a newline, don't print the next line
208209
if !buf.ends_with('\n') {
209-
push_trailing(buf, prev_line, &prev_hi, None);
210+
push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
210211
}
211212
// remove trailing newline
212213
buf.pop();

src/libsyntax/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl DiagnosticSpanLine {
314314
h_end: usize)
315315
-> DiagnosticSpanLine {
316316
DiagnosticSpanLine {
317-
text: fm.get_line(index).unwrap_or("").to_owned(),
317+
text: fm.get_line(index).map_or(String::new(), |l| l.into_owned()),
318318
highlight_start: h_start,
319319
highlight_end: h_end,
320320
}

src/libsyntax_pos/lib.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#![cfg_attr(stage0, feature(rustc_private))]
3434
#![cfg_attr(stage0, feature(staged_api))]
3535

36+
use std::borrow::Cow;
3637
use std::cell::{Cell, RefCell};
3738
use std::ops::{Add, Sub};
3839
use std::rc::Rc;
@@ -605,24 +606,33 @@ impl FileMap {
605606

606607
/// get a line from the list of pre-computed line-beginnings.
607608
/// line-number here is 0-based.
608-
pub fn get_line(&self, line_number: usize) -> Option<&str> {
609-
match self.src {
610-
Some(ref src) => {
611-
let lines = self.lines.borrow();
612-
lines.get(line_number).map(|&line| {
613-
let begin: BytePos = line - self.start_pos;
614-
let begin = begin.to_usize();
615-
// We can't use `lines.get(line_number+1)` because we might
616-
// be parsing when we call this function and thus the current
617-
// line is the last one we have line info for.
618-
let slice = &src[begin..];
619-
match slice.find('\n') {
620-
Some(e) => &slice[..e],
621-
None => slice
622-
}
623-
})
609+
pub fn get_line(&self, line_number: usize) -> Option<Cow<str>> {
610+
fn get_until_newline(src: &str, begin: usize) -> &str {
611+
// We can't use `lines.get(line_number+1)` because we might
612+
// be parsing when we call this function and thus the current
613+
// line is the last one we have line info for.
614+
let slice = &src[begin..];
615+
match slice.find('\n') {
616+
Some(e) => &slice[..e],
617+
None => slice
624618
}
625-
None => None
619+
}
620+
621+
let lines = self.lines.borrow();
622+
let line = if let Some(line) = lines.get(line_number) {
623+
line
624+
} else {
625+
return None;
626+
};
627+
let begin: BytePos = *line - self.start_pos;
628+
let begin = begin.to_usize();
629+
630+
if let Some(ref src) = self.src {
631+
Some(Cow::from(get_until_newline(src, begin)))
632+
} else if let Some(src) = self.external_src.borrow().get_source() {
633+
Some(Cow::Owned(String::from(get_until_newline(src, begin))))
634+
} else {
635+
None
626636
}
627637
}
628638

@@ -641,7 +651,7 @@ impl FileMap {
641651
}
642652

643653
pub fn is_imported(&self) -> bool {
644-
self.src.is_none() // TODO: change to something more sensible
654+
self.src.is_none()
645655
}
646656

647657
pub fn byte_length(&self) -> u32 {

0 commit comments

Comments
 (0)