Skip to content

Commit 03aae4b

Browse files
committed
Add in better unification errors
1 parent 1e13a41 commit 03aae4b

File tree

8 files changed

+308
-143
lines changed

8 files changed

+308
-143
lines changed

crates/sml-core/src/elaborate.rs

Lines changed: 252 additions & 136 deletions
Large diffs are not rendered by default.

crates/sml-core/src/pretty_print/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl<'a> Print for Type<'a> {
137137
}
138138

139139
impl<'a> Type<'a> {
140-
fn print_rename<'b, 'c>(
140+
pub fn print_rename<'b, 'c>(
141141
&self,
142142
pp: &'b mut PrettyPrinter<'c>,
143143
map: &mut HashMap<usize, String>,

crates/sml-core/src/pretty_print/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,47 @@ impl<'a> PrettyPrinter<'a> {
9898
Ok(())
9999
}
100100

101+
pub fn write_fmt<W: std::fmt::Write>(&mut self, w: &mut W) -> std::fmt::Result {
102+
while let Some(cmd) = self.commands.pop_front() {
103+
use Command::*;
104+
match cmd {
105+
Indent(w) => {
106+
self.indent += w;
107+
}
108+
Dedent(w) => {
109+
self.indent -= w;
110+
}
111+
Wrap(width) => {
112+
self.prev_max.push(self.max);
113+
self.max = width;
114+
}
115+
Unwrap => {
116+
// should never fail anyway
117+
self.max = self.prev_max.pop().unwrap_or(120);
118+
}
119+
Line => {
120+
if self.width == self.indent {
121+
continue;
122+
}
123+
let spaces = (0..self.indent).map(|_| ' ').collect::<String>();
124+
write!(w, "\n{}", spaces)?;
125+
self.width = self.indent;
126+
}
127+
Text(s) => {
128+
if self.width + s.len() >= self.max {
129+
let spaces = (0..self.indent).map(|_| ' ').collect::<String>();
130+
write!(w, "\n{}{}", spaces, s)?;
131+
self.width = self.indent + s.len();
132+
} else {
133+
self.width += s.len();
134+
write!(w, "{}", s)?;
135+
}
136+
}
137+
}
138+
}
139+
Ok(())
140+
}
141+
101142
pub fn wrap<F>(&mut self, width: usize, f: F) -> &mut Self
102143
where
103144
for<'b> F: Fn(&'b mut PrettyPrinter<'a>) -> &'b mut PrettyPrinter<'a>,

crates/sml-driver/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ impl<'a> Compiler<'a> {
7575
match res {
7676
Ok(d) => {
7777
let mut check = sml_core::check::Check::default();
78-
self.measure("checking", |c| check.check_decl(&d));
78+
self.measure("checking", |_| check.check_decl(&d));
7979
diags.extend(check.diags);
8080

8181
let decls = self.measure("elaboration", |c| c.elab.elaborate_decl(&d));
82-
diags.extend(std::mem::replace(&mut self.elab.diags, Vec::new()));
82+
diags.extend(self.elab.diagnostics(&self.interner));
8383

8484
match self.verbosity {
8585
0 => {}

crates/sml-driver/tests/integration.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
use goldentests::{TestConfig, TestResult};
22

33
#[test]
4+
#[cfg(target_family = "windows")]
5+
fn goldentests() -> TestResult<()> {
6+
let config = TestConfig::new("../../target/debug/sml-driver.exe", "../../tests/", "-- ")?;
7+
config.run_tests()
8+
}
9+
10+
#[test]
11+
#[cfg(target_family = "unix")]
412
fn goldentests() -> TestResult<()> {
513
let config = TestConfig::new("../../target/debug/sml-driver", "../../tests/", "-- ")?;
614
config.run_tests()

scratch.sml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fun merge xs [] = xs
5454
| merge (x::xs) (y::ys) = x::y::(merge xs ys);
5555

5656
(* example from Compiling Pattern Matching *)
57-
let
57+
val _ = let
5858
datatype u = T | F
5959
val x = (T, F, T)
6060
in

tests/typecheck/cantunify.sml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
-- expected stderr:
1212
-- Error
13-
-- 22,9 Can't unify type constructors interned symbol and interned symbol
13+
-- 22,9 Type unification: can't unify function with argument types. Type constructors differ: int, bool
1414
1515
*)
1616

tests/typecheck/cyclic.sml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
33
-- expected stderr:
44
-- Error
5-
-- 18,21 Cyclic type detected: 'i#1 interned symbol
5+
-- 18,21 Type unification: can't unify function with argument types. Cyclic type detected: 'a list, 'a
66
--
77
-- Error
8-
-- 18,5 Cyclic type detected: 'i#1 interned symbol
8+
-- 18,5 Type unification: function clause body doesn't match with return type. Cyclic type detected: 'a, 'a list
99
1010
-- expected stdout:
1111
-- 0 warnings, 2 errors

0 commit comments

Comments
 (0)