Tweak some error message reports

This commit is contained in:
Richard Feldman 2020-08-31 17:31:07 -04:00
parent e6cbfb1567
commit c611f1dfe8
2 changed files with 46 additions and 23 deletions

View file

@ -498,6 +498,14 @@ fn to_expr_report<'b>(
Reason::ElemInList { index } => { Reason::ElemInList { index } => {
let ith = index.ordinal(); let ith = index.ordinal();
// Don't say "the previous elements all have the type" if
// there was only 1 previous element!
let prev_elems_msg = if index.to_zero_based() == 1 {
"However, the 1st element has the type:"
} else {
"However, the preceding elements in the list all have the type:"
};
report_mismatch( report_mismatch(
alloc, alloc,
filename, filename,
@ -506,13 +514,10 @@ fn to_expr_report<'b>(
expected_type, expected_type,
region, region,
Some(expr_region), Some(expr_region),
alloc.string(format!( alloc.reflow("This list contains elements with different types:"),
"The {} element of this list does not match all the previous elements:", alloc.string(format!("Its {} element is", ith)),
ith alloc.reflow(prev_elems_msg),
)), Some(alloc.reflow("I need every element in a list to have the same type!")),
alloc.string(format!("The {} element is", ith)),
alloc.reflow("But all the previous elements in the list have type:"),
Some(alloc.reflow("I need all elements of a list to have the same type!")),
) )
} }
Reason::RecordUpdateValue(field) => report_mismatch( Reason::RecordUpdateValue(field) => report_mismatch(
@ -2387,11 +2392,11 @@ fn type_problem_to_pretty<'b>(
} }
} }
IntFloat => alloc.tip().append(alloc.concat(vec![ IntFloat => alloc.tip().append(alloc.concat(vec![
alloc.reflow("Convert between "), alloc.reflow("You can convert between "),
alloc.type_str("Int"), alloc.type_str("Int"),
alloc.reflow(" and "), alloc.reflow(" and "),
alloc.type_str("Float"), alloc.type_str("Float"),
alloc.reflow(" with "), alloc.reflow(" using functions like "),
alloc.symbol_qualified(Symbol::NUM_TO_FLOAT), alloc.symbol_qualified(Symbol::NUM_TO_FLOAT),
alloc.reflow(" and "), alloc.reflow(" and "),
alloc.symbol_qualified(Symbol::NUM_ROUND), alloc.symbol_qualified(Symbol::NUM_ROUND),

View file

@ -20,7 +20,12 @@ const CYCLE_LN: &str = ["| ", "│ "][!IS_WINDOWS as usize];
const CYCLE_MID: &str = ["| |", "│ ↓"][!IS_WINDOWS as usize]; const CYCLE_MID: &str = ["| |", "│ ↓"][!IS_WINDOWS as usize];
const CYCLE_END: &str = ["+-<---+", "└─────┘"][!IS_WINDOWS as usize]; const CYCLE_END: &str = ["+-<---+", "└─────┘"][!IS_WINDOWS as usize];
const GUTTER_BAR: &str = ""; const GUTTER_BAR: &str = "";
const UNDERLINE: &str = "";
/// The number of monospace spaces the gutter bar takes up.
/// (This is not necessarily the same as GUTTER_BAR.len()!)
const GUTTER_BAR_WIDTH: usize = 1;
pub fn cycle<'b>( pub fn cycle<'b>(
alloc: &'b RocDocAllocator<'b>, alloc: &'b RocDocAllocator<'b>,
@ -91,12 +96,15 @@ impl<'b> Report<'b> {
self.doc self.doc
} else { } else {
let header = format!( let header = format!(
"-- {} {}", "── {} {}",
self.title, self.title,
"-".repeat(80 - (self.title.len() + 4)) "".repeat(80 - (self.title.len() + 4))
); );
alloc.stack(vec![alloc.text(header), self.doc]) alloc.stack(vec![
alloc.text(header).annotate(Annotation::Header),
self.doc,
])
} }
} }
} }
@ -110,6 +118,7 @@ pub struct Palette<'a> {
pub alias: &'a str, pub alias: &'a str,
pub error: &'a str, pub error: &'a str,
pub line_number: &'a str, pub line_number: &'a str,
pub header: &'a str,
pub gutter_bar: &'a str, pub gutter_bar: &'a str,
pub module_name: &'a str, pub module_name: &'a str,
pub binop: &'a str, pub binop: &'a str,
@ -126,7 +135,8 @@ pub const DEFAULT_PALETTE: Palette = Palette {
alias: YELLOW_CODE, alias: YELLOW_CODE,
error: RED_CODE, error: RED_CODE,
line_number: CYAN_CODE, line_number: CYAN_CODE,
gutter_bar: MAGENTA_CODE, header: CYAN_CODE,
gutter_bar: CYAN_CODE,
module_name: GREEN_CODE, module_name: GREEN_CODE,
binop: GREEN_CODE, binop: GREEN_CODE,
typo: YELLOW_CODE, typo: YELLOW_CODE,
@ -390,13 +400,14 @@ impl<'a> RocDocAllocator<'a> {
let overlapping = sub_region2.start_col < sub_region1.end_col; let overlapping = sub_region2.start_col < sub_region1.end_col;
let highlight = if overlapping { let highlight = if overlapping {
self.text("^".repeat((sub_region2.end_col - sub_region1.start_col) as usize)) self.text(UNDERLINE.repeat((sub_region2.end_col - sub_region1.start_col) as usize))
} else { } else {
let highlight1 = "^".repeat((sub_region1.end_col - sub_region1.start_col) as usize); let highlight1 =
UNDERLINE.repeat((sub_region1.end_col - sub_region1.start_col) as usize);
let highlight2 = if sub_region1 == sub_region2 { let highlight2 = if sub_region1 == sub_region2 {
"".repeat(0) "".repeat(0)
} else { } else {
"^".repeat((sub_region2.end_col - sub_region2.start_col) as usize) UNDERLINE.repeat((sub_region2.end_col - sub_region2.start_col) as usize)
}; };
let inbetween = " " let inbetween = " "
.repeat((sub_region2.start_col.saturating_sub(sub_region1.end_col)) as usize); .repeat((sub_region2.start_col.saturating_sub(sub_region1.end_col)) as usize);
@ -408,8 +419,9 @@ impl<'a> RocDocAllocator<'a> {
let highlight_line = self let highlight_line = self
.line() .line()
.append(self.text(" ".repeat(max_line_number_length))) // Omit the gutter bar when we know there are no further
.append(self.text(GUTTER_BAR).annotate(Annotation::GutterBar)) // line numbers to be printed after this!
.append(self.text(" ".repeat(max_line_number_length + GUTTER_BAR_WIDTH)))
.append(if sub_region1.is_empty() && sub_region2.is_empty() { .append(if sub_region1.is_empty() && sub_region2.is_empty() {
self.nil() self.nil()
} else { } else {
@ -491,11 +503,13 @@ impl<'a> RocDocAllocator<'a> {
} }
if error_highlight_line { if error_highlight_line {
let highlight_text = "^".repeat((sub_region.end_col - sub_region.start_col) as usize); let highlight_text =
UNDERLINE.repeat((sub_region.end_col - sub_region.start_col) as usize);
let highlight_line = self let highlight_line = self
.line() .line()
.append(self.text(" ".repeat(max_line_number_length))) // Omit the gutter bar when we know there are no further
.append(self.text(GUTTER_BAR).annotate(Annotation::GutterBar)) // line numbers to be printed after this!
.append(self.text(" ".repeat(max_line_number_length + GUTTER_BAR_WIDTH)))
.append(if highlight_text.is_empty() { .append(if highlight_text.is_empty() {
self.nil() self.nil()
} else { } else {
@ -577,6 +591,7 @@ pub enum Annotation {
Typo, Typo,
TypoSuggestion, TypoSuggestion,
Tip, Tip,
Header,
} }
/// Render with minimal formatting /// Render with minimal formatting
@ -746,6 +761,9 @@ where
Error => { Error => {
self.write_str(self.palette.error)?; self.write_str(self.palette.error)?;
} }
Header => {
self.write_str(self.palette.header)?;
}
LineNumber => { LineNumber => {
self.write_str(self.palette.line_number)?; self.write_str(self.palette.line_number)?;
} }
@ -775,7 +793,7 @@ where
Some(annotation) => match annotation { Some(annotation) => match annotation {
Emphasized | Url | TypeVariable | Alias | Symbol | BinOp | Error | GutterBar Emphasized | Url | TypeVariable | Alias | Symbol | BinOp | Error | GutterBar
| Typo | TypoSuggestion | Structure | CodeBlock | PlainText | LineNumber | Tip | Typo | TypoSuggestion | Structure | CodeBlock | PlainText | LineNumber | Tip
| Module => { | Module | Header => {
self.write_str(RESET_CODE)?; self.write_str(RESET_CODE)?;
} }