diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs index 2bd683da63..c887b163fc 100644 --- a/base/src/types/mod.rs +++ b/base/src/types/mod.rs @@ -1768,24 +1768,29 @@ where }, Type::Variant(ref row) => { let mut first = true; - let mut doc = arena.nil(); - - match **row { - Type::EmptyRow => (), - Type::ExtendRow { ref fields, .. } => for field in fields.iter() { - if !first { - doc = doc.append(arena.space()); - } - first = false; - doc = doc.append("| ").append(field.name.as_ref()); - for arg in arg_iter(&field.typ) { - doc = chain![arena; - doc, - " ", - dt(Prec::Constructor, arg).pretty(printer) - ]; - } - }, + + let doc = match **row { + Type::EmptyRow => arena.nil(), + Type::ExtendRow { ref fields, .. } => { + arena.concat(fields.iter().map(|field| { + chain![arena; + if first { + first = false; + arena.nil() + } else { + arena.newline() + }, + "| ", + field.name.as_ref(), + arena.concat(arg_iter(&field.typ).map(|arg| { + chain![arena; + " ", + dt(Prec::Constructor, arg).pretty(printer) + ] + })) + ].group() + })) + } _ => ice!("Unexpected type in variant"), }; diff --git a/base/tests/types.rs b/base/tests/types.rs index 182f614225..3169a51ef8 100644 --- a/base/tests/types.rs +++ b/base/tests/types.rs @@ -267,7 +267,7 @@ fn show_variant() { Field::new("A", Type::function(vec![Type::int()], Type::ident("A"))), Field::new("B", Type::ident("A")), ]); - assert_eq_display!(format!("{}", typ), "| A Int | B"); + assert_eq_display!(format!("{}", typ), "| A Int\n| B"); } #[test] diff --git a/doc/src/lib.rs b/doc/src/lib.rs index 49ce4bfe6e..fc5db9f198 100644 --- a/doc/src/lib.rs +++ b/doc/src/lib.rs @@ -30,7 +30,7 @@ use handlebars::{Handlebars, Helper, Output, RenderContext, RenderError}; use serde::Deserialize; -use pretty::Arena; +use pretty::{Arena, DocAllocator}; use gluon::base::filename_to_module; use gluon::base::metadata::Metadata; @@ -73,11 +73,12 @@ fn print_type(typ: &ArcType) -> String { let mut doc = typ.pretty(&arena); match **typ { Type::Record(_) => (), + Type::Variant(_) => doc = arena.newline().append(doc).nest(4), _ => { doc = doc.nest(4); } } - doc.nest(4).1.pretty(80).to_string() + doc.group().1.pretty(80).to_string() } pub fn record(typ: &ArcType, meta: &Metadata) -> Record { diff --git a/format/src/pretty_print.rs b/format/src/pretty_print.rs index 3293a87c1a..c0043dd394 100644 --- a/format/src/pretty_print.rs +++ b/format/src/pretty_print.rs @@ -277,7 +277,7 @@ where }; let mut type_doc = types::pretty_print(self, typ); match **typ { - Type::Record(_) => (), + Type::Record(_) | Type::Variant(_) => (), _ => type_doc = type_doc.nest(INDENT), } chain![arena; @@ -302,10 +302,21 @@ where arena.space() ] })).group(), - chain![arena; - "= ", - type_doc - ].group() + match **typ { + Type::Variant(_) => { + chain![arena; + "=", + arena.newline(), + type_doc + ].nest(INDENT) + } + _ => { + chain![arena; + "= ", + type_doc + ].group() + } + } ].group() }).interleave(newlines_iter!(self, binds.iter().map(|bind| bind.span())))), self.pretty_expr_(binds.last().unwrap().alias.span.end(), body) diff --git a/format/tests/pretty_print.rs b/format/tests/pretty_print.rs index 4d2d820d23..2cd29c12c9 100644 --- a/format/tests/pretty_print.rs +++ b/format/tests/pretty_print.rs @@ -377,3 +377,19 @@ type Handler a = "#; assert_diff!(&format_expr(expr).unwrap(), expr, " ", 0); } + +#[test] +fn variant_type() { + let expr = r#" +type TestCase a = + | LoooooooooooooooooongTest String (() -> std.test.Test a) + | LoooooooooooooooooooooooongGroup String (Array (std.test.TestCase a)) +() +"#; + assert_diff!( + &format_expr(expr).unwrap_or_else(|err| panic!("{}", err)), + expr, + " ", + 0 + ); +} diff --git a/repl/src/repl.glu b/repl/src/repl.glu index 160a955ef8..c71e4d0aa9 100644 --- a/repl/src/repl.glu +++ b/repl/src/repl.glu @@ -56,7 +56,9 @@ let run_file cpu_pool filename : CpuPool -> String -> IO () = | Ok _ -> io.println "" | Err x -> io.println x -type ReplAction = | Continue | Quit +type ReplAction = + | Continue + | Quit type Cmd = { name : String, alias : String, info : String, action : String -> IO ReplAction } type Commands = Map String Cmd diff --git a/std/list.glu b/std/list.glu index 33c8cce64f..bdc586723b 100644 --- a/std/list.glu +++ b/std/list.glu @@ -11,7 +11,9 @@ let { (<*>), wrap } = import! std.applicative let { (<|>) } = import! std.applicative /// A linked list type -type List a = | Nil | Cons a (List a) +type List a = + | Nil + | Cons a (List a) /// Constructs a list from an array. Useful to emulate list literals /// @@ -147,7 +149,7 @@ let scan compare xs less equal greater : (a -> Ordering) -> List a -> List a -> List a - -> { _0 : List a, _1 : List a, _2 : List a } = + -> (List a, List a, List a) = match xs with | Nil -> (less, equal, greater) | Cons y ys -> diff --git a/std/map.glu b/std/map.glu index ac4295ad96..159f53323b 100644 --- a/std/map.glu +++ b/std/map.glu @@ -7,7 +7,9 @@ let { flip, const } = import! std.function let list @ { List } = import! std.list let { Option } = import! std.option -type Map k a = | Bin k a (Map k a) (Map k a) | Tip +type Map k a = + | Bin k a (Map k a) (Map k a) + | Tip let empty = Tip diff --git a/std/reference.glu b/std/reference.glu index 96cefa58bf..b60a769209 100644 --- a/std/reference.glu +++ b/std/reference.glu @@ -1,6 +1,6 @@ let reference = import! std.reference.prim #[infix(right, 9)] -let (<-) = reference.(<-) +let (<-) = reference.(<-) { (<-), .. diff --git a/std/stream.glu b/std/stream.glu index 15973f71b9..0aeed3bb35 100644 --- a/std/stream.glu +++ b/std/stream.glu @@ -4,7 +4,9 @@ let { Bool } = import! std.bool let { Option } = import! std.option let { lazy, force } = import! std.lazy -type Stream_ a = | Value a (Stream a) | Empty +type Stream_ a = + | Value a (Stream a) + | Empty and Stream a = Lazy (Stream_ a) let from f : (Int -> Option a) -> Stream a = diff --git a/std/test.glu b/std/test.glu index efc9f4979a..332d926460 100644 --- a/std/test.glu +++ b/std/test.glu @@ -10,7 +10,9 @@ let { (<>) } = import! std.semigroup type Test a = Writer (List String) a -type TestCase a = | Test String (() -> Test a) | Group String (Array (TestCase a)) +type TestCase a = + | Test String (() -> Test a) + | Group String (Array (TestCase a)) let testWriter = writer.make list.monoid diff --git a/std/types.glu b/std/types.glu index 839618c2a3..0542019516 100644 --- a/std/types.glu +++ b/std/types.glu @@ -3,15 +3,24 @@ // Definition of standard types separate from the prelude to allow primitives to use them /// `Bool` represents a value which can only be `True` or `False` -type Bool = | False | True +type Bool = + | False + | True /// `Option` represents a value which may not exist. -type Option a = | None | Some a +type Option a = + | None + | Some a /// `Result` represents either success (`Ok`) or an error (`Err`) -type Result e t = | Err e | Ok t +type Result e t = + | Err e + | Ok t /// `Ordering` represents the result of comparing two values -type Ordering = | LT | EQ | GT +type Ordering = + | LT + | EQ + | GT { Bool, Option, Result, Ordering } diff --git a/vm/src/api/typ.rs b/vm/src/api/typ.rs index 5db95ea177..ada3b1f35c 100644 --- a/vm/src/api/typ.rs +++ b/vm/src/api/typ.rs @@ -41,7 +41,8 @@ where type {0} = {1} {{ {0} }} "#, - name, typ + name, + typ.pretty(&::pretty::Arena::new()).nest(4).1.pretty(80) )) }