Merge remote-tracking branch 'origin/trunk' into builtins-in-roc-delayed-alias

This commit is contained in:
Folkert 2022-03-18 21:25:52 +01:00
commit 4e1197165b
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
181 changed files with 9495 additions and 2273 deletions

View file

@ -5,6 +5,7 @@ use roc_problem::can::{
BadPattern, ExtensionTypeKind, FloatErrorKind, IntErrorKind, Problem, RuntimeError,
};
use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Loc, Region};
use roc_types::types::AliasKind;
use std::path::PathBuf;
use crate::error::r#type::suggest;
@ -17,6 +18,7 @@ const UNRECOGNIZED_NAME: &str = "UNRECOGNIZED NAME";
const UNUSED_DEF: &str = "UNUSED DEFINITION";
const UNUSED_IMPORT: &str = "UNUSED IMPORT";
const UNUSED_ALIAS_PARAM: &str = "UNUSED TYPE ALIAS PARAMETER";
const UNBOUND_TYPE_VARIABLE: &str = "UNBOUND TYPE VARIABLE";
const UNUSED_ARG: &str = "UNUSED ARGUMENT";
const MISSING_DEFINITION: &str = "MISSING DEFINITION";
const UNKNOWN_GENERATES_WITH: &str = "UNKNOWN GENERATES FUNCTION";
@ -252,6 +254,43 @@ pub fn can_problem<'b>(
title = UNUSED_ALIAS_PARAM.to_string();
severity = Severity::RuntimeError;
}
Problem::UnboundTypeVariable {
typ: alias,
num_unbound,
one_occurrence,
kind,
} => {
let mut stack = Vec::with_capacity(4);
if num_unbound == 1 {
stack.push(alloc.concat(vec![
alloc.reflow("The definition of "),
alloc.symbol_unqualified(alias),
alloc.reflow(" has an unbound type variable:"),
]));
} else {
stack.push(alloc.concat(vec![
alloc.reflow("The definition of "),
alloc.symbol_unqualified(alias),
alloc.reflow(" has "),
alloc.text(format!("{}", num_unbound)),
alloc.reflow(" unbound type variables."),
]));
stack.push(alloc.reflow("Here is one occurrence:"));
}
stack.push(alloc.region(lines.convert_region(one_occurrence)));
stack.push(alloc.tip().append(alloc.concat(vec![
alloc.reflow("Type variables must be bound before the "),
alloc.keyword(match kind {
AliasKind::Structural => ":",
AliasKind::Opaque => ":=",
}),
alloc.reflow(". Perhaps you intended to add a type parameter to this type?"),
])));
doc = alloc.stack(stack);
title = UNBOUND_TYPE_VARIABLE.to_string();
severity = Severity::RuntimeError;
}
Problem::BadRecursion(entries) => {
doc = to_circular_def_doc(alloc, lines, &entries);
title = CIRCULAR_DEF.to_string();

View file

@ -540,6 +540,8 @@ fn to_expr_report<'a>(
to_malformed_number_literal_report(alloc, lines, filename, pos)
}
EExpr::Ability(err, pos) => to_ability_def_report(alloc, lines, filename, err, *pos),
_ => todo!("unhandled parse error: {:?}", parse_problem),
}
}
@ -3647,6 +3649,83 @@ fn to_space_report<'a>(
}
}
fn to_ability_def_report<'a>(
alloc: &'a RocDocAllocator<'a>,
lines: &LineInfo,
filename: PathBuf,
problem: &roc_parse::parser::EAbility<'a>,
start: Position,
) -> Report<'a> {
use roc_parse::parser::EAbility;
match problem {
EAbility::Space(error, pos) => to_space_report(alloc, lines, filename, error, *pos),
EAbility::Type(tipe, pos) => to_type_report(alloc, lines, filename, tipe, *pos),
EAbility::DemandAlignment(over_under_indent, pos) => {
let over_under_msg = if *over_under_indent > 0 {
alloc.reflow("indented too much")
} else {
alloc.reflow("not indented enough")
};
let msg = alloc.concat(vec![
alloc.reflow("I suspect this line is "),
over_under_msg,
alloc.reflow(" (by "),
alloc.string(over_under_indent.abs().to_string()),
alloc.reflow(" spaces)"),
]);
to_unfinished_ability_report(alloc, lines, filename, *pos, start, msg)
}
EAbility::DemandName(pos) => to_unfinished_ability_report(
alloc,
lines,
filename,
*pos,
start,
alloc.reflow("I was expecting to see a value signature next."),
),
EAbility::DemandColon(pos) => to_unfinished_ability_report(
alloc,
lines,
filename,
*pos,
start,
alloc.concat(vec![
alloc.reflow("I was expecting to see a "),
alloc.parser_suggestion(":"),
alloc.reflow(" annotating the signature of this value next."),
]),
),
}
}
fn to_unfinished_ability_report<'a>(
alloc: &'a RocDocAllocator<'a>,
lines: &LineInfo,
filename: PathBuf,
pos: Position,
start: Position,
message: RocDocBuilder<'a>,
) -> Report<'a> {
let surroundings = Region::new(start, pos);
let region = LineColumnRegion::from_pos(lines.convert_pos(pos));
let doc = alloc.stack(vec![
alloc.reflow(r"I was partway through parsing an ability definition, but I got stuck here:"),
alloc.region_with_subregion(lines.convert_region(surroundings), region),
message,
]);
Report {
filename,
doc,
title: "UNFINISHED ABILITY".to_string(),
severity: Severity::RuntimeError,
}
}
#[derive(Debug)]
enum Next<'a> {
Keyword(&'a str),

View file

@ -102,14 +102,6 @@ pub fn type_problem<'b>(
report(title, doc, filename)
}
CyclicAlias(..) => {
// We'll also report cyclic aliases as a canonicalization problem, no need to
// re-report them.
None
}
SolvedTypeError => None, // Don't re-report cascading errors - see https://github.com/rtfeldman/roc/pull/1711
Shadowed(original_region, shadow) => {
let doc = report_shadowing(alloc, lines, original_region, shadow);
let title = DUPLICATE_NAME.to_string();
@ -117,6 +109,12 @@ pub fn type_problem<'b>(
report(title, doc, filename)
}
SolvedTypeError => None, // Don't re-report cascading errors - see https://github.com/rtfeldman/roc/pull/1711
// We'll also report these as a canonicalization problem, no need to re-report them.
CyclicAlias(..) => None,
UnrecognizedIdent(..) => None,
other => panic!("unhandled bad type: {:?}", other),
}
}