Skip to content

Commit

Permalink
Auto merge of #37369 - estebank:multiline-span, r=nikomatsakis
Browse files Browse the repository at this point in the history
Show multiline spans in full if short enough

When dealing with multiline spans that span few lines, show the complete span instead of restricting to the first character of the first line.

For example, instead of:

```
% ./rustc file2.rs
error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied
  --> file2.rs:13:9
   |
13 |    foo(1 + bar(x,
   |        ^ trait `{integer}: std::ops::Add<()>` not satisfied
   |
```

show

```
% ./rustc file2.rs
error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied
  --> file2.rs:13:9
   |
13 |      foo(1 + bar(x,
   |  ________^ starting here...
14 | |            y),
   | |_____________^ ...ending here: trait `{integer}: std::ops::Add<()>` not satisfied
   |
```

The [proposal in internals](https://internals.rust-lang.org/t/proposal-for-multiline-span-comments/4242/6) outlines the reasoning behind this.
  • Loading branch information
bors authored Nov 29, 2016
2 parents f50dbd5 + b7982bb commit b30022a
Show file tree
Hide file tree
Showing 15 changed files with 1,158 additions and 144 deletions.
458 changes: 353 additions & 105 deletions src/librustc_errors/emitter.rs

Large diffs are not rendered by default.

107 changes: 104 additions & 3 deletions src/librustc_errors/snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,86 @@ pub struct Line {
pub annotations: Vec<Annotation>,
}


#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct MultilineAnnotation {
pub depth: usize,
pub line_start: usize,
pub line_end: usize,
pub start_col: usize,
pub end_col: usize,
pub is_primary: bool,
pub label: Option<String>,
}

impl MultilineAnnotation {
pub fn increase_depth(&mut self) {
self.depth += 1;
}

pub fn as_start(&self) -> Annotation {
Annotation {
start_col: self.start_col,
end_col: self.start_col + 1,
is_primary: self.is_primary,
label: Some("starting here...".to_owned()),
annotation_type: AnnotationType::MultilineStart(self.depth)
}
}

pub fn as_end(&self) -> Annotation {
Annotation {
start_col: self.end_col - 1,
end_col: self.end_col,
is_primary: self.is_primary,
label: match self.label {
Some(ref label) => Some(format!("...ending here: {}", label)),
None => Some("...ending here".to_owned()),
},
annotation_type: AnnotationType::MultilineEnd(self.depth)
}
}

pub fn as_line(&self) -> Annotation {
Annotation {
start_col: 0,
end_col: 0,
is_primary: self.is_primary,
label: None,
annotation_type: AnnotationType::MultilineLine(self.depth)
}
}
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub enum AnnotationType {
/// Annotation under a single line of code
Singleline,

/// Annotation under the first character of a multiline span
Minimized,

/// Annotation enclosing the first and last character of a multiline span
Multiline(MultilineAnnotation),

// The Multiline type above is replaced with the following three in order
// to reuse the current label drawing code.
//
// Each of these corresponds to one part of the following diagram:
//
// x | foo(1 + bar(x,
// | _________^ starting here... < MultilineStart
// x | | y), < MultilineLine
// | |______________^ ...ending here: label < MultilineEnd
// x | z);
/// Annotation marking the first character of a fully shown multiline span
MultilineStart(usize),
/// Annotation marking the last character of a fully shown multiline span
MultilineEnd(usize),
/// Line at the left enclosing the lines of a fully shown multiline span
MultilineLine(usize),
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Annotation {
/// Start column, 0-based indexing -- counting *characters*, not
Expand All @@ -55,11 +135,32 @@ pub struct Annotation {
/// Is this annotation derived from primary span
pub is_primary: bool,

/// Is this a large span minimized down to a smaller span
pub is_minimized: bool,

/// Optional label to display adjacent to the annotation.
pub label: Option<String>,

/// Is this a single line, multiline or multiline span minimized down to a
/// smaller span.
pub annotation_type: AnnotationType,
}

impl Annotation {
pub fn is_minimized(&self) -> bool {
match self.annotation_type {
AnnotationType::Minimized => true,
_ => false,
}
}

pub fn is_multiline(&self) -> bool {
match self.annotation_type {
AnnotationType::Multiline(_) |
AnnotationType::MultilineStart(_) |
AnnotationType::MultilineLine(_) |
AnnotationType::MultilineEnd(_) => true,
_ => false,
}
}

}

#[derive(Debug)]
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,7 @@ pub mod ext {
}
}

#[cfg(test)]
mod test_snippet;

// __build_diagnostic_array! { libsyntax, DIAGNOSTICS }
Loading

0 comments on commit b30022a

Please sign in to comment.