From 7336787af41adc4dfe650f7c7f10f9c7c3c011db Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 15:41:17 +0200
Subject: Update dhall-lang submodule

---
 README.md                |  2 +-
 dhall-lang               |  2 +-
 dhall/tests/typecheck.rs | 72 ++++++++++++++++++++++++------------------------
 3 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/README.md b/README.md
index 148a57f..6ba1bfc 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ This language is defined by a [standard](https://github.com/dhall-lang/dhall-lan
 - Parsing: 100%
 - Imports: 0%
 - Normalization: 74%
-- Typechecking: 77%
+- Typechecking: 78%
 
 You can see what's missing from the commented out tests in `dhall/tests`.
 
diff --git a/dhall-lang b/dhall-lang
index c77f22c..1f87b02 160000
--- a/dhall-lang
+++ b/dhall-lang
@@ -1 +1 @@
-Subproject commit c77f22cb10f25d9c3e29801760849c81b8595407
+Subproject commit 1f87b0285ffc098a3ef05c93a8186c32736bd4a6
diff --git a/dhall/tests/typecheck.rs b/dhall/tests/typecheck.rs
index 875b14a..0cd6ddf 100644
--- a/dhall/tests/typecheck.rs
+++ b/dhall/tests/typecheck.rs
@@ -80,17 +80,17 @@ tc_success!(spec_typecheck_success_prelude_List_shifted_0, "prelude/List/shifted
 tc_success!(spec_typecheck_success_prelude_List_shifted_1, "prelude/List/shifted/1");
 tc_success!(spec_typecheck_success_prelude_List_unzip_0, "prelude/List/unzip/0");
 tc_success!(spec_typecheck_success_prelude_List_unzip_1, "prelude/List/unzip/1");
-// tc_success!(spec_typecheck_success_prelude_Monoid_00, "prelude/Monoid/00");
-// tc_success!(spec_typecheck_success_prelude_Monoid_01, "prelude/Monoid/01");
-// tc_success!(spec_typecheck_success_prelude_Monoid_02, "prelude/Monoid/02");
-// tc_success!(spec_typecheck_success_prelude_Monoid_03, "prelude/Monoid/03");
-// tc_success!(spec_typecheck_success_prelude_Monoid_04, "prelude/Monoid/04");
-// tc_success!(spec_typecheck_success_prelude_Monoid_05, "prelude/Monoid/05");
-// tc_success!(spec_typecheck_success_prelude_Monoid_06, "prelude/Monoid/06");
-// tc_success!(spec_typecheck_success_prelude_Monoid_07, "prelude/Monoid/07");
-// tc_success!(spec_typecheck_success_prelude_Monoid_08, "prelude/Monoid/08");
-// tc_success!(spec_typecheck_success_prelude_Monoid_09, "prelude/Monoid/09");
-// tc_success!(spec_typecheck_success_prelude_Monoid_10, "prelude/Monoid/10");
+tc_success!(spec_typecheck_success_prelude_Monoid_00, "prelude/Monoid/00");
+tc_success!(spec_typecheck_success_prelude_Monoid_01, "prelude/Monoid/01");
+tc_success!(spec_typecheck_success_prelude_Monoid_02, "prelude/Monoid/02");
+tc_success!(spec_typecheck_success_prelude_Monoid_03, "prelude/Monoid/03");
+tc_success!(spec_typecheck_success_prelude_Monoid_04, "prelude/Monoid/04");
+tc_success!(spec_typecheck_success_prelude_Monoid_05, "prelude/Monoid/05");
+tc_success!(spec_typecheck_success_prelude_Monoid_06, "prelude/Monoid/06");
+tc_success!(spec_typecheck_success_prelude_Monoid_07, "prelude/Monoid/07");
+tc_success!(spec_typecheck_success_prelude_Monoid_08, "prelude/Monoid/08");
+tc_success!(spec_typecheck_success_prelude_Monoid_09, "prelude/Monoid/09");
+tc_success!(spec_typecheck_success_prelude_Monoid_10, "prelude/Monoid/10");
 tc_success!(spec_typecheck_success_prelude_Natural_build_0, "prelude/Natural/build/0");
 tc_success!(spec_typecheck_success_prelude_Natural_build_1, "prelude/Natural/build/1");
 tc_success!(spec_typecheck_success_prelude_Natural_enumerate_0, "prelude/Natural/enumerate/0");
@@ -114,35 +114,35 @@ tc_success!(spec_typecheck_success_prelude_Natural_sum_1, "prelude/Natural/sum/1
 // tc_success!(spec_typecheck_success_prelude_Natural_toDouble_1, "prelude/Natural/toDouble/1");
 // tc_success!(spec_typecheck_success_prelude_Natural_toInteger_0, "prelude/Natural/toInteger/0");
 // tc_success!(spec_typecheck_success_prelude_Natural_toInteger_1, "prelude/Natural/toInteger/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_all_0, "prelude/Optional/all/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_all_1, "prelude/Optional/all/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_any_0, "prelude/Optional/any/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_any_1, "prelude/Optional/any/1");
+tc_success!(spec_typecheck_success_prelude_Optional_all_0, "prelude/Optional/all/0");
+tc_success!(spec_typecheck_success_prelude_Optional_all_1, "prelude/Optional/all/1");
+tc_success!(spec_typecheck_success_prelude_Optional_any_0, "prelude/Optional/any/0");
+tc_success!(spec_typecheck_success_prelude_Optional_any_1, "prelude/Optional/any/1");
 // tc_success!(spec_typecheck_success_prelude_Optional_build_0, "prelude/Optional/build/0");
 // tc_success!(spec_typecheck_success_prelude_Optional_build_1, "prelude/Optional/build/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_concat_0, "prelude/Optional/concat/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_concat_1, "prelude/Optional/concat/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_concat_2, "prelude/Optional/concat/2");
+tc_success!(spec_typecheck_success_prelude_Optional_concat_0, "prelude/Optional/concat/0");
+tc_success!(spec_typecheck_success_prelude_Optional_concat_1, "prelude/Optional/concat/1");
+tc_success!(spec_typecheck_success_prelude_Optional_concat_2, "prelude/Optional/concat/2");
 // tc_success!(spec_typecheck_success_prelude_Optional_filter_0, "prelude/Optional/filter/0");
 // tc_success!(spec_typecheck_success_prelude_Optional_filter_1, "prelude/Optional/filter/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_fold_0, "prelude/Optional/fold/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_fold_1, "prelude/Optional/fold/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_head_0, "prelude/Optional/head/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_head_1, "prelude/Optional/head/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_head_2, "prelude/Optional/head/2");
-// tc_success!(spec_typecheck_success_prelude_Optional_last_0, "prelude/Optional/last/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_last_1, "prelude/Optional/last/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_last_2, "prelude/Optional/last/2");
-// tc_success!(spec_typecheck_success_prelude_Optional_length_0, "prelude/Optional/length/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_length_1, "prelude/Optional/length/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_map_0, "prelude/Optional/map/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_map_1, "prelude/Optional/map/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_null_0, "prelude/Optional/null/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_null_1, "prelude/Optional/null/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_toList_0, "prelude/Optional/toList/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_toList_1, "prelude/Optional/toList/1");
-// tc_success!(spec_typecheck_success_prelude_Optional_unzip_0, "prelude/Optional/unzip/0");
-// tc_success!(spec_typecheck_success_prelude_Optional_unzip_1, "prelude/Optional/unzip/1");
+tc_success!(spec_typecheck_success_prelude_Optional_fold_0, "prelude/Optional/fold/0");
+tc_success!(spec_typecheck_success_prelude_Optional_fold_1, "prelude/Optional/fold/1");
+tc_success!(spec_typecheck_success_prelude_Optional_head_0, "prelude/Optional/head/0");
+tc_success!(spec_typecheck_success_prelude_Optional_head_1, "prelude/Optional/head/1");
+tc_success!(spec_typecheck_success_prelude_Optional_head_2, "prelude/Optional/head/2");
+tc_success!(spec_typecheck_success_prelude_Optional_last_0, "prelude/Optional/last/0");
+tc_success!(spec_typecheck_success_prelude_Optional_last_1, "prelude/Optional/last/1");
+tc_success!(spec_typecheck_success_prelude_Optional_last_2, "prelude/Optional/last/2");
+tc_success!(spec_typecheck_success_prelude_Optional_length_0, "prelude/Optional/length/0");
+tc_success!(spec_typecheck_success_prelude_Optional_length_1, "prelude/Optional/length/1");
+tc_success!(spec_typecheck_success_prelude_Optional_map_0, "prelude/Optional/map/0");
+tc_success!(spec_typecheck_success_prelude_Optional_map_1, "prelude/Optional/map/1");
+tc_success!(spec_typecheck_success_prelude_Optional_null_0, "prelude/Optional/null/0");
+tc_success!(spec_typecheck_success_prelude_Optional_null_1, "prelude/Optional/null/1");
+tc_success!(spec_typecheck_success_prelude_Optional_toList_0, "prelude/Optional/toList/0");
+tc_success!(spec_typecheck_success_prelude_Optional_toList_1, "prelude/Optional/toList/1");
+tc_success!(spec_typecheck_success_prelude_Optional_unzip_0, "prelude/Optional/unzip/0");
+tc_success!(spec_typecheck_success_prelude_Optional_unzip_1, "prelude/Optional/unzip/1");
 tc_success!(spec_typecheck_success_prelude_Text_concat_0, "prelude/Text/concat/0");
 tc_success!(spec_typecheck_success_prelude_Text_concat_1, "prelude/Text/concat/1");
 tc_success!(spec_typecheck_success_prelude_Text_concatMap_0, "prelude/Text/concatMap/0");
-- 
cgit v1.2.3


From 1ff7bffcbce7112b0491f7cd895ed3275fb68a1f Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 15:58:20 +0200
Subject: Commit script used for dhall-lang#442

---
 do.pl | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100755 do.pl

diff --git a/do.pl b/do.pl
new file mode 100755
index 0000000..276c399
--- /dev/null
+++ b/do.pl
@@ -0,0 +1,94 @@
+#!/usr/bin/env -S perl -i -p
+# next if /^ *;/; s/\b(?<!-)if\b(?!-)/if-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)then\b(?!-)/then-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)else\b(?!-)/else-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)let\b(?!-)/let-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)in\b(?!-)/in-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)as\b(?!-)/as-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)using\b(?!-)/using-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)merge\b(?!-)/merge-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)Some\b(?!-)/Some-raw nonempty-whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)Optional\b(?!-)/Optional whitespace/g;
+# next if /^ *;/; s/\b(?<!-)Text\b(?!-)/Text whitespace/g;
+# next if /^ *;/; s/\b(?<!-)List\b(?!-)/List whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)or\b(?!-)/"||" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)plus\b(?!-)/"+" nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)text-append\b(?!-)/"++" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)list-append\b(?!-)/"#" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)and\b(?!-)/"&&" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)times\b(?!-)/"*" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)double-equal\b(?!-)/"==" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)not-equal\b(?!-)/"!=" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)equal\b(?!-)/"=" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)dot\b(?!-)/"." whitespace/g;
+# next if /^ *;/; s/\b(?<!-)bar\b(?!-)/"|" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)comma\b(?!-)/"," whitespace/g;
+# next if /^ *;/; s/\b(?<!-)at\b(?!-)/"@" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)open-parens\b(?!-)/"(" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)close-parens\b(?!-)/")" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)open-brace\b(?!-)/"{" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)close-brace\b(?!-)/"}" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)open-bracket\b(?!-)/"[" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)close-bracket\b(?!-)/"]" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)open-angle\b(?!-)/"<" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)close-angle\b(?!-)/">" whitespace/g;
+# next if /^ *;/; s/\b(?<!-)colon\b(?!-)/":" nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import-alt\b(?!-)/"?" nonempty-whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)combine-types\b(?!-)/combine-types whitespace/g;
+# next if /^ *;/; s/\b(?<!-)combine\b(?!-)/combine whitespace/g;
+# next if /^ *;/; s/\b(?<!-)prefer\b(?!-)/prefer whitespace/g;
+# next if /^ *;/; s/\b(?<!-)lambda\b(?!-)/lambda whitespace/g;
+# next if /^ *;/; s/\b(?<!-)forall\b(?!-)/forall whitespace/g;
+# next if /^ *;/; s/\b(?<!-)arrow\b(?!-)/arrow whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)label\b(?!-)/label whitespace/g;
+# next if /^ *;/; s/\b(?<!-)identifier\b(?!-)/identifier whitespace/g;
+# next if /^ *;/; s/\b(?<!-)text-literal\b(?!-)/text-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)double-literal\b(?!-)/double-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)integer-literal\b(?!-)/integer-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)natural-literal\b(?!-)/natural-literal whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)import-hashed\b(?!-)/import-hashed whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import-type\b(?!-)/import-type whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import\b(?!-)/import whitespace/g;
+# next if /^ *;/; s/\b(?<!-)local\b(?!-)/local whitespace/g;
+# next if /^ *;/; s/\b(?<!-)env\b(?!-)/env whitespace/g;
+# next if /^ *;/; s/\b(?<!-)http\b(?!-)/http whitespace/g;
+# next if /^ *;/; s/\b(?<!-)missing\b(?!-)/missing whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)labels\b(?!-)/labels whitespace/g;
+# next if /^ *;/; s/\b(?<!-)record-type-or-literal\b(?!-)/record-type-or-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-type-or-literal\b(?!-)/non-empty-record-type-or-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-type\b(?!-)/non-empty-record-type whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-literal\b(?!-)/non-empty-record-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)union-type-or-literal\b(?!-)/union-type-or-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-union-type-or-literal\b(?!-)/non-empty-union-type-or-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-list-literal\b(?!-)/non-empty-list-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)expression\b(?!-)/expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)annotated-expression\b(?!-)/annotated-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)empty-collection\b(?!-)/empty-collection whitespace/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-optional\b(?!-)/non-empty-optional whitespace/g;
+# next if /^ *;/; s/\b(?<!-)operator-expression\b(?!-)/operator-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import-alt-expression\b(?!-)/import-alt-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)or-expression\b(?!-)/or-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)plus-expression\b(?!-)/plus-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)text-append-expression\b(?!-)/text-append-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)list-append-expression\b(?!-)/list-append-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)and-expression\b(?!-)/and-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)combine-expression\b(?!-)/combine-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)prefer-expression\b(?!-)/prefer-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)combine-types-expression\b(?!-)/combine-types-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)times-expression\b(?!-)/times-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)equal-expression\b(?!-)/equal-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)not-equal-expression\b(?!-)/not-equal-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)application-expression\b(?!-)/application-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import-expression\b(?!-)/import-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)selector-expression\b(?!-)/selector-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)primitive-expression\b(?!-)/primitive-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)complete-expression\b(?!-)/complete-expression whitespace/g;
+
+# next if /^ *;/; s/\b(?<!-)whitespace\b(?!-)/whsp/g;
+# next if /^ *;/; s/\b(?<!-)nonempty-whitespace\b(?!-)/whsp1/g;
-- 
cgit v1.2.3


From 170eebd7001153a849fbf84c52767240a33c4538 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 16:03:10 +0200
Subject: Rename whitespace rules

---
 dhall_parser/src/dhall.abnf            |  96 +++++++++----------
 dhall_parser/src/dhall.pest.visibility |   5 +-
 do.pl                                  | 168 ++++++++++++++++-----------------
 3 files changed, 134 insertions(+), 135 deletions(-)

diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 02edc84..025f53a 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -130,9 +130,9 @@ whitespace-chunk =
     / line-comment
     / block-comment
 
-whitespace = *whitespace-chunk
+whsp = *whitespace-chunk
 
-nonempty-whitespace = 1*whitespace-chunk
+whsp1 = 1*whitespace-chunk
 
 ; Uppercase or lowercase ASCII letter
 ALPHA = %x41-5A / %x61-7A
@@ -318,7 +318,7 @@ integer-literal = ( "+" / "-" ) natural-literal
 
 ; The implementation should recognize reserved names for builtins and treat them as special
 ; values instead of variables.
-identifier = any-label [ whitespace "@" whitespace natural-literal ]
+identifier = any-label [ whsp "@" whsp natural-literal ]
 
 ; Printable characters other than " ()[]{}<>/\,"
 ;
@@ -445,7 +445,7 @@ sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
 
 http =
     http-raw
-    [ whitespace using nonempty-whitespace (import-hashed / "(" whitespace import-hashed whitespace ")") ]
+    [ whsp using whsp1 (import-hashed / "(" whsp import-hashed whsp ")") ]
 
 ; Dhall supports unquoted environment variables that are Bash-compliant or
 ; quoted environment variables that are POSIX-compliant
@@ -515,12 +515,12 @@ import-type = missing / local / http / env
 
 hash = %x73.68.61.32.35.36.3a 64HEXDIG  ; "sha256:XXX...XXX"
 
-import-hashed = import-type [ whitespace hash ]
+import-hashed = import-type [ whsp hash ]
 
 ; "http://example.com"
 ; "./foo/bar"
 ; "env:FOO"
-import = import-hashed [ whitespace as nonempty-whitespace Text ]
+import = import-hashed [ whsp as whsp1 Text ]
 
 ; NOTE: Every rule past this point should only reference rules that end with
 ; whitespace.  This ensures consistent handling of whitespace in the absence of
@@ -543,58 +543,58 @@ expression =
     / annotated-expression
 
 ; "\(x : a) -> b"
-lambda-expression = lambda whitespace "(" whitespace unreserved-label whitespace ":" nonempty-whitespace expression ")" whitespace arrow whitespace expression
+lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression
 
 ; "if a then b else c"
-ifthenelse-expression = if nonempty-whitespace expression then nonempty-whitespace expression else nonempty-whitespace expression
+ifthenelse-expression = if whsp1 expression then whsp1 expression else whsp1 expression
 
 ; "let x : t = e1 in e2"
 ; "let x     = e1 in e2"
 ; "let x = e1 let y = e2 in e3"
-let-expression = 1*let-binding in nonempty-whitespace expression
-let-binding = let nonempty-whitespace unreserved-label whitespace [ ":" nonempty-whitespace expression ] "=" whitespace expression
+let-expression = 1*let-binding in whsp1 expression
+let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression ] "=" whsp expression
 
 ; "forall (x : a) -> b"
-forall-expression = forall whitespace "(" whitespace unreserved-label whitespace ":" nonempty-whitespace expression ")" whitespace arrow whitespace expression
+forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression
 
 ; "a -> b"
-arrow-expression = operator-expression arrow whitespace expression
+arrow-expression = operator-expression arrow whsp expression
 
 ; "merge e1 e2 : t"
 ; "merge e1 e2"
-merge-expression = merge nonempty-whitespace import-expression whitespace import-expression whitespace [ ":" nonempty-whitespace application-expression ]
+merge-expression = merge whsp1 import-expression whsp import-expression whsp [ ":" whsp1 application-expression ]
 
 ; "[]  : List     t"
 ; "[]  : Optional t"
 ; "[x] : Optional t"
-empty-list-or-optional = "[" whitespace (empty-collection / non-empty-optional)
-empty-collection = "]" whitespace ":" nonempty-whitespace (List whitespace / Optional whitespace) import-expression whitespace
-non-empty-optional = expression "]" whitespace ":" nonempty-whitespace Optional whitespace import-expression whitespace
+empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional)
+empty-collection = "]" whsp ":" whsp1 (List whsp / Optional whsp) import-expression whsp
+non-empty-optional = expression "]" whsp ":" whsp1 Optional whsp import-expression whsp
 
 ; "x : t"
-annotated-expression = operator-expression [ ":" nonempty-whitespace expression ]
+annotated-expression = operator-expression [ ":" whsp1 expression ]
 
 
 operator-expression = import-alt-expression
 
-import-alt-expression    = or-expression            *("?" nonempty-whitespace    or-expression)
-or-expression            = plus-expression          *("||" whitespace            plus-expression         )
-plus-expression          = text-append-expression   *("+" nonempty-whitespace          text-append-expression  )
-text-append-expression   = list-append-expression   *("++" whitespace   list-append-expression  )
-list-append-expression   = and-expression           *("#" whitespace   and-expression          )
-and-expression           = combine-expression       *("&&" whitespace           combine-expression      )
-combine-expression       = prefer-expression        *(combine whitespace       prefer-expression       )
-prefer-expression        = combine-types-expression *(prefer whitespace        combine-types-expression)
-combine-types-expression = times-expression         *(combine-types whitespace times-expression        )
-times-expression         = equal-expression         *("*" whitespace         equal-expression        )
-equal-expression         = not-equal-expression     *("==" whitespace  not-equal-expression    )
-not-equal-expression     = application-expression   *("!=" whitespace     application-expression  )
+import-alt-expression    = or-expression            *("?" whsp1    or-expression)
+or-expression            = plus-expression          *("||" whsp            plus-expression         )
+plus-expression          = text-append-expression   *("+" whsp1          text-append-expression  )
+text-append-expression   = list-append-expression   *("++" whsp   list-append-expression  )
+list-append-expression   = and-expression           *("#" whsp   and-expression          )
+and-expression           = combine-expression       *("&&" whsp           combine-expression      )
+combine-expression       = prefer-expression        *(combine whsp       prefer-expression       )
+prefer-expression        = combine-types-expression *(prefer whsp        combine-types-expression)
+combine-types-expression = times-expression         *(combine-types whsp times-expression        )
+times-expression         = equal-expression         *("*" whsp         equal-expression        )
+equal-expression         = not-equal-expression     *("==" whsp  not-equal-expression    )
+not-equal-expression     = application-expression   *("!=" whsp     application-expression  )
 
 ; Import expressions need to be separated by some whitespace, otherwise there
 ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`",
 ; or "apply the import `./a` to label `b`"
 application-expression =
-    import-expression *(nonempty-whitespace import-expression) whitespace
+    import-expression *(whsp1 import-expression) whsp
 
 import-expression =
       import
@@ -607,17 +607,17 @@ import-expression =
 ; can't tell from parsing just the period whether "foo." will become "foo.bar"
 ; (i.e. accessing field `bar` of the record `foo`) or `foo./bar` (i.e. applying
 ; the function `foo` to the relative path `./bar`)
-selector-expression = primitive-expression *(whitespace "." whitespace selector)
+selector-expression = primitive-expression *(whsp "." whsp selector)
 
 selector = any-label / labels
 
-labels = "{" whitespace [ any-label whitespace *("," whitespace any-label whitespace) ] "}"
+labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}"
 
 
 primitive-expression =
       literal-expression
-    / "{" whitespace record-type-or-literal "}"
-    / "<" whitespace union-type-or-literal ">"
+    / "{" whsp record-type-or-literal "}"
+    / "<" whsp union-type-or-literal ">"
     / non-empty-list-literal
     / parenthesized-expression
 
@@ -656,14 +656,14 @@ record-type-or-literal =
       empty-record-literal
     / non-empty-record-type-or-literal
     / empty-record-type
-empty-record-literal = "=" whitespace
+empty-record-literal = "=" whsp
 empty-record-type = ""
 non-empty-record-type-or-literal =
-    any-label whitespace (non-empty-record-literal / non-empty-record-type)
-non-empty-record-type    = ":" nonempty-whitespace expression *("," whitespace record-type-entry)
-record-type-entry = any-label whitespace ":" nonempty-whitespace expression
-non-empty-record-literal = "=" whitespace expression *("," whitespace record-literal-entry)
-record-literal-entry = any-label whitespace "=" whitespace expression
+    any-label whsp (non-empty-record-literal / non-empty-record-type)
+non-empty-record-type    = ":" whsp1 expression *("," whsp record-type-entry)
+record-type-entry = any-label whsp ":" whsp1 expression
+non-empty-record-literal = "=" whsp expression *("," whsp record-literal-entry)
+record-literal-entry = any-label whsp "=" whsp expression
 
 ; "< Foo : Integer | Bar : Bool >"
 ; "< Foo : Integer | Bar = True >"
@@ -672,21 +672,21 @@ union-type-or-literal =
     / empty-union-type
 empty-union-type = ""
 non-empty-union-type-or-literal =
-    any-label whitespace
-    ( "=" whitespace expression union-type-entries
-    / ":" nonempty-whitespace expression [ "|" whitespace non-empty-union-type-or-literal ]
+    any-label whsp
+    ( "=" whsp expression union-type-entries
+    / ":" whsp1 expression [ "|" whsp non-empty-union-type-or-literal ]
     )
-union-type-entries = *("|" whitespace union-type-entry)
-union-type-entry = any-label whitespace ":" nonempty-whitespace expression
+union-type-entries = *("|" whsp union-type-entry)
+union-type-entry = any-label whsp ":" whsp1 expression
 
 ; "[1, 2, 3]"
 ; `empty-list-or-optional` handles empty lists
-non-empty-list-literal = "[" whitespace expression *("," whitespace expression) "]"
+non-empty-list-literal = "[" whsp expression *("," whsp expression) "]"
 
 ; "( e )"
-parenthesized-expression = "(" whitespace expression ")"
+parenthesized-expression = "(" whsp expression ")"
 
 
 ; All expressions end with trailing whitespace.  This just adds a final
 ; whitespace prefix for the top-level of the program
-complete-expression = whitespace expression
+complete-expression = whsp expression
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index ee5ea2b..e95cd32 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -7,9 +7,8 @@ end_of_line
 # not_end_of_line
 # line_comment
 # whitespace_chunk
-# whitespace
-# whitespace_
-# nonempty_whitespace
+# whsp
+# whsp1
 # ALPHA
 # DIGIT
 # HEXDIG
diff --git a/do.pl b/do.pl
index 276c399..53004af 100755
--- a/do.pl
+++ b/do.pl
@@ -1,94 +1,94 @@
 #!/usr/bin/env -S perl -i -p
-# next if /^ *;/; s/\b(?<!-)if\b(?!-)/if-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)then\b(?!-)/then-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)else\b(?!-)/else-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)let\b(?!-)/let-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)in\b(?!-)/in-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)as\b(?!-)/as-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)using\b(?!-)/using-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)merge\b(?!-)/merge-raw nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)Some\b(?!-)/Some-raw nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)if\b(?!-)/if-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)then\b(?!-)/then-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)else\b(?!-)/else-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)let\b(?!-)/let-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)in\b(?!-)/in-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)as\b(?!-)/as-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)using\b(?!-)/using-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)merge\b(?!-)/merge-raw whsp1/g;
+# next if /^ *;/; s/\b(?<!-)Some\b(?!-)/Some-raw whsp1/g;
 
-# next if /^ *;/; s/\b(?<!-)Optional\b(?!-)/Optional whitespace/g;
-# next if /^ *;/; s/\b(?<!-)Text\b(?!-)/Text whitespace/g;
-# next if /^ *;/; s/\b(?<!-)List\b(?!-)/List whitespace/g;
+# next if /^ *;/; s/\b(?<!-)Optional\b(?!-)/Optional whsp/g;
+# next if /^ *;/; s/\b(?<!-)Text\b(?!-)/Text whsp/g;
+# next if /^ *;/; s/\b(?<!-)List\b(?!-)/List whsp/g;
 
-# next if /^ *;/; s/\b(?<!-)or\b(?!-)/"||" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)plus\b(?!-)/"+" nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)text-append\b(?!-)/"++" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)list-append\b(?!-)/"#" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)and\b(?!-)/"&&" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)times\b(?!-)/"*" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)double-equal\b(?!-)/"==" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)not-equal\b(?!-)/"!=" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)equal\b(?!-)/"=" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)dot\b(?!-)/"." whitespace/g;
-# next if /^ *;/; s/\b(?<!-)bar\b(?!-)/"|" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)comma\b(?!-)/"," whitespace/g;
-# next if /^ *;/; s/\b(?<!-)at\b(?!-)/"@" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)open-parens\b(?!-)/"(" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)close-parens\b(?!-)/")" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)open-brace\b(?!-)/"{" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)close-brace\b(?!-)/"}" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)open-bracket\b(?!-)/"[" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)close-bracket\b(?!-)/"]" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)open-angle\b(?!-)/"<" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)close-angle\b(?!-)/">" whitespace/g;
-# next if /^ *;/; s/\b(?<!-)colon\b(?!-)/":" nonempty-whitespace/g;
-# next if /^ *;/; s/\b(?<!-)import-alt\b(?!-)/"?" nonempty-whitespace/g;
+# next if /^ *;/; s/\b(?<!-)or\b(?!-)/"||" whsp/g;
+# next if /^ *;/; s/\b(?<!-)plus\b(?!-)/"+" whsp1/g;
+# next if /^ *;/; s/\b(?<!-)text-append\b(?!-)/"++" whsp/g;
+# next if /^ *;/; s/\b(?<!-)list-append\b(?!-)/"#" whsp/g;
+# next if /^ *;/; s/\b(?<!-)and\b(?!-)/"&&" whsp/g;
+# next if /^ *;/; s/\b(?<!-)times\b(?!-)/"*" whsp/g;
+# next if /^ *;/; s/\b(?<!-)double-equal\b(?!-)/"==" whsp/g;
+# next if /^ *;/; s/\b(?<!-)not-equal\b(?!-)/"!=" whsp/g;
+# next if /^ *;/; s/\b(?<!-)equal\b(?!-)/"=" whsp/g;
+# next if /^ *;/; s/\b(?<!-)dot\b(?!-)/"." whsp/g;
+# next if /^ *;/; s/\b(?<!-)bar\b(?!-)/"|" whsp/g;
+# next if /^ *;/; s/\b(?<!-)comma\b(?!-)/"," whsp/g;
+# next if /^ *;/; s/\b(?<!-)at\b(?!-)/"@" whsp/g;
+# next if /^ *;/; s/\b(?<!-)open-parens\b(?!-)/"(" whsp/g;
+# next if /^ *;/; s/\b(?<!-)close-parens\b(?!-)/")" whsp/g;
+# next if /^ *;/; s/\b(?<!-)open-brace\b(?!-)/"{" whsp/g;
+# next if /^ *;/; s/\b(?<!-)close-brace\b(?!-)/"}" whsp/g;
+# next if /^ *;/; s/\b(?<!-)open-bracket\b(?!-)/"[" whsp/g;
+# next if /^ *;/; s/\b(?<!-)close-bracket\b(?!-)/"]" whsp/g;
+# next if /^ *;/; s/\b(?<!-)open-angle\b(?!-)/"<" whsp/g;
+# next if /^ *;/; s/\b(?<!-)close-angle\b(?!-)/">" whsp/g;
+# next if /^ *;/; s/\b(?<!-)colon\b(?!-)/":" whsp1/g;
+# next if /^ *;/; s/\b(?<!-)import-alt\b(?!-)/"?" whsp1/g;
 
-# next if /^ *;/; s/\b(?<!-)combine-types\b(?!-)/combine-types whitespace/g;
-# next if /^ *;/; s/\b(?<!-)combine\b(?!-)/combine whitespace/g;
-# next if /^ *;/; s/\b(?<!-)prefer\b(?!-)/prefer whitespace/g;
-# next if /^ *;/; s/\b(?<!-)lambda\b(?!-)/lambda whitespace/g;
-# next if /^ *;/; s/\b(?<!-)forall\b(?!-)/forall whitespace/g;
-# next if /^ *;/; s/\b(?<!-)arrow\b(?!-)/arrow whitespace/g;
+# next if /^ *;/; s/\b(?<!-)combine-types\b(?!-)/combine-types whsp/g;
+# next if /^ *;/; s/\b(?<!-)combine\b(?!-)/combine whsp/g;
+# next if /^ *;/; s/\b(?<!-)prefer\b(?!-)/prefer whsp/g;
+# next if /^ *;/; s/\b(?<!-)lambda\b(?!-)/lambda whsp/g;
+# next if /^ *;/; s/\b(?<!-)forall\b(?!-)/forall whsp/g;
+# next if /^ *;/; s/\b(?<!-)arrow\b(?!-)/arrow whsp/g;
 
-# next if /^ *;/; s/\b(?<!-)label\b(?!-)/label whitespace/g;
-# next if /^ *;/; s/\b(?<!-)identifier\b(?!-)/identifier whitespace/g;
-# next if /^ *;/; s/\b(?<!-)text-literal\b(?!-)/text-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)double-literal\b(?!-)/double-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)integer-literal\b(?!-)/integer-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)natural-literal\b(?!-)/natural-literal whitespace/g;
+# next if /^ *;/; s/\b(?<!-)label\b(?!-)/label whsp/g;
+# next if /^ *;/; s/\b(?<!-)identifier\b(?!-)/identifier whsp/g;
+# next if /^ *;/; s/\b(?<!-)text-literal\b(?!-)/text-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)double-literal\b(?!-)/double-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)integer-literal\b(?!-)/integer-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)natural-literal\b(?!-)/natural-literal whsp/g;
 
-# next if /^ *;/; s/\b(?<!-)import-hashed\b(?!-)/import-hashed whitespace/g;
-# next if /^ *;/; s/\b(?<!-)import-type\b(?!-)/import-type whitespace/g;
-# next if /^ *;/; s/\b(?<!-)import\b(?!-)/import whitespace/g;
-# next if /^ *;/; s/\b(?<!-)local\b(?!-)/local whitespace/g;
-# next if /^ *;/; s/\b(?<!-)env\b(?!-)/env whitespace/g;
-# next if /^ *;/; s/\b(?<!-)http\b(?!-)/http whitespace/g;
-# next if /^ *;/; s/\b(?<!-)missing\b(?!-)/missing whitespace/g;
+# next if /^ *;/; s/\b(?<!-)import-hashed\b(?!-)/import-hashed whsp/g;
+# next if /^ *;/; s/\b(?<!-)import-type\b(?!-)/import-type whsp/g;
+# next if /^ *;/; s/\b(?<!-)import\b(?!-)/import whsp/g;
+# next if /^ *;/; s/\b(?<!-)local\b(?!-)/local whsp/g;
+# next if /^ *;/; s/\b(?<!-)env\b(?!-)/env whsp/g;
+# next if /^ *;/; s/\b(?<!-)http\b(?!-)/http whsp/g;
+# next if /^ *;/; s/\b(?<!-)missing\b(?!-)/missing whsp/g;
 
-# next if /^ *;/; s/\b(?<!-)labels\b(?!-)/labels whitespace/g;
-# next if /^ *;/; s/\b(?<!-)record-type-or-literal\b(?!-)/record-type-or-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-type-or-literal\b(?!-)/non-empty-record-type-or-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-type\b(?!-)/non-empty-record-type whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-literal\b(?!-)/non-empty-record-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)union-type-or-literal\b(?!-)/union-type-or-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-union-type-or-literal\b(?!-)/non-empty-union-type-or-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-list-literal\b(?!-)/non-empty-list-literal whitespace/g;
-# next if /^ *;/; s/\b(?<!-)expression\b(?!-)/expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)annotated-expression\b(?!-)/annotated-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)empty-collection\b(?!-)/empty-collection whitespace/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-optional\b(?!-)/non-empty-optional whitespace/g;
-# next if /^ *;/; s/\b(?<!-)operator-expression\b(?!-)/operator-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)import-alt-expression\b(?!-)/import-alt-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)or-expression\b(?!-)/or-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)plus-expression\b(?!-)/plus-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)text-append-expression\b(?!-)/text-append-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)list-append-expression\b(?!-)/list-append-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)and-expression\b(?!-)/and-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)combine-expression\b(?!-)/combine-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)prefer-expression\b(?!-)/prefer-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)combine-types-expression\b(?!-)/combine-types-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)times-expression\b(?!-)/times-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)equal-expression\b(?!-)/equal-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)not-equal-expression\b(?!-)/not-equal-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)application-expression\b(?!-)/application-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)import-expression\b(?!-)/import-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)selector-expression\b(?!-)/selector-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)primitive-expression\b(?!-)/primitive-expression whitespace/g;
-# next if /^ *;/; s/\b(?<!-)complete-expression\b(?!-)/complete-expression whitespace/g;
+# next if /^ *;/; s/\b(?<!-)labels\b(?!-)/labels whsp/g;
+# next if /^ *;/; s/\b(?<!-)record-type-or-literal\b(?!-)/record-type-or-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-type-or-literal\b(?!-)/non-empty-record-type-or-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-type\b(?!-)/non-empty-record-type whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-record-literal\b(?!-)/non-empty-record-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)union-type-or-literal\b(?!-)/union-type-or-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-union-type-or-literal\b(?!-)/non-empty-union-type-or-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-list-literal\b(?!-)/non-empty-list-literal whsp/g;
+# next if /^ *;/; s/\b(?<!-)expression\b(?!-)/expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)annotated-expression\b(?!-)/annotated-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)empty-collection\b(?!-)/empty-collection whsp/g;
+# next if /^ *;/; s/\b(?<!-)non-empty-optional\b(?!-)/non-empty-optional whsp/g;
+# next if /^ *;/; s/\b(?<!-)operator-expression\b(?!-)/operator-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)import-alt-expression\b(?!-)/import-alt-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)or-expression\b(?!-)/or-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)plus-expression\b(?!-)/plus-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)text-append-expression\b(?!-)/text-append-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)list-append-expression\b(?!-)/list-append-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)and-expression\b(?!-)/and-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)combine-expression\b(?!-)/combine-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)prefer-expression\b(?!-)/prefer-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)combine-types-expression\b(?!-)/combine-types-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)times-expression\b(?!-)/times-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)equal-expression\b(?!-)/equal-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)not-equal-expression\b(?!-)/not-equal-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)application-expression\b(?!-)/application-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)import-expression\b(?!-)/import-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)selector-expression\b(?!-)/selector-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)primitive-expression\b(?!-)/primitive-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)complete-expression\b(?!-)/complete-expression whsp/g;
 
 # next if /^ *;/; s/\b(?<!-)whitespace\b(?!-)/whsp/g;
 # next if /^ *;/; s/\b(?<!-)nonempty-whitespace\b(?!-)/whsp1/g;
-- 
cgit v1.2.3


From ecc39e26a7cf211a5312da468e11f828917e669d Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 16:46:39 +0200
Subject: Remove trailing whitespace from expression rules

---
 dhall_parser/src/dhall.abnf | 66 +++++++++++++++++++++++----------------------
 do.pl                       |  9 +++++++
 2 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 025f53a..640a422 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -543,58 +543,60 @@ expression =
     / annotated-expression
 
 ; "\(x : a) -> b"
-lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression
+lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
 
 ; "if a then b else c"
-ifthenelse-expression = if whsp1 expression then whsp1 expression else whsp1 expression
+ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression
 
 ; "let x : t = e1 in e2"
 ; "let x     = e1 in e2"
 ; "let x = e1 let y = e2 in e3"
 let-expression = 1*let-binding in whsp1 expression
-let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression ] "=" whsp expression
+let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp
 
 ; "forall (x : a) -> b"
-forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression ")" whsp arrow whsp expression
+forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
 
 ; "a -> b"
-arrow-expression = operator-expression arrow whsp expression
+arrow-expression = operator-expression whsp arrow whsp expression
 
 ; "merge e1 e2 : t"
 ; "merge e1 e2"
-merge-expression = merge whsp1 import-expression whsp import-expression whsp [ ":" whsp1 application-expression ]
+merge-expression = merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ]
 
 ; "[]  : List     t"
 ; "[]  : Optional t"
 ; "[x] : Optional t"
 empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional)
-empty-collection = "]" whsp ":" whsp1 (List whsp / Optional whsp) import-expression whsp
-non-empty-optional = expression "]" whsp ":" whsp1 Optional whsp import-expression whsp
+empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression
+non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression
 
 ; "x : t"
-annotated-expression = operator-expression [ ":" whsp1 expression ]
+annotated-expression = operator-expression [ whsp ":" whsp1 expression ]
 
 
 operator-expression = import-alt-expression
 
-import-alt-expression    = or-expression            *("?" whsp1    or-expression)
-or-expression            = plus-expression          *("||" whsp            plus-expression         )
-plus-expression          = text-append-expression   *("+" whsp1          text-append-expression  )
-text-append-expression   = list-append-expression   *("++" whsp   list-append-expression  )
-list-append-expression   = and-expression           *("#" whsp   and-expression          )
-and-expression           = combine-expression       *("&&" whsp           combine-expression      )
-combine-expression       = prefer-expression        *(combine whsp       prefer-expression       )
-prefer-expression        = combine-types-expression *(prefer whsp        combine-types-expression)
-combine-types-expression = times-expression         *(combine-types whsp times-expression        )
-times-expression         = equal-expression         *("*" whsp         equal-expression        )
-equal-expression         = not-equal-expression     *("==" whsp  not-equal-expression    )
-not-equal-expression     = application-expression   *("!=" whsp     application-expression  )
+; Nonempty-whitespace to disambiguate `http://a/a?a`
+import-alt-expression    = or-expression            *(whsp "?" whsp1 or-expression)
+or-expression            = plus-expression          *(whsp "||" whsp plus-expression)
+; Nonempty-whitespace to disambiguate `f +2`
+plus-expression          = text-append-expression   *(whsp "+" whsp1 text-append-expression)
+text-append-expression   = list-append-expression   *(whsp "++" whsp list-append-expression)
+list-append-expression   = and-expression           *(whsp "#" whsp and-expression)
+and-expression           = combine-expression       *(whsp "&&" whsp combine-expression)
+combine-expression       = prefer-expression        *(whsp combine whsp prefer-expression)
+prefer-expression        = combine-types-expression *(whsp prefer whsp combine-types-expression)
+combine-types-expression = times-expression         *(whsp combine-types whsp times-expression)
+times-expression         = equal-expression         *(whsp "*" whsp equal-expression)
+equal-expression         = not-equal-expression     *(whsp "==" whsp not-equal-expression)
+not-equal-expression     = application-expression   *(whsp "!=" whsp application-expression)
 
 ; Import expressions need to be separated by some whitespace, otherwise there
 ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`",
 ; or "apply the import `./a` to label `b`"
 application-expression =
-    import-expression *(whsp1 import-expression) whsp
+    import-expression *(whsp1 import-expression)
 
 import-expression =
       import
@@ -660,10 +662,10 @@ empty-record-literal = "=" whsp
 empty-record-type = ""
 non-empty-record-type-or-literal =
     any-label whsp (non-empty-record-literal / non-empty-record-type)
-non-empty-record-type    = ":" whsp1 expression *("," whsp record-type-entry)
-record-type-entry = any-label whsp ":" whsp1 expression
-non-empty-record-literal = "=" whsp expression *("," whsp record-literal-entry)
-record-literal-entry = any-label whsp "=" whsp expression
+non-empty-record-type    = ":" whsp1 expression whsp *("," whsp record-type-entry)
+record-type-entry = any-label whsp ":" whsp1 expression whsp
+non-empty-record-literal = "=" whsp expression whsp *("," whsp record-literal-entry)
+record-literal-entry = any-label whsp "=" whsp expression whsp
 
 ; "< Foo : Integer | Bar : Bool >"
 ; "< Foo : Integer | Bar = True >"
@@ -673,20 +675,20 @@ union-type-or-literal =
 empty-union-type = ""
 non-empty-union-type-or-literal =
     any-label whsp
-    ( "=" whsp expression union-type-entries
-    / ":" whsp1 expression [ "|" whsp non-empty-union-type-or-literal ]
+    ( "=" whsp expression whsp union-type-entries
+    / ":" whsp1 expression whsp [ "|" whsp non-empty-union-type-or-literal ]
     )
 union-type-entries = *("|" whsp union-type-entry)
-union-type-entry = any-label whsp ":" whsp1 expression
+union-type-entry = any-label whsp ":" whsp1 expression whsp
 
 ; "[1, 2, 3]"
 ; `empty-list-or-optional` handles empty lists
-non-empty-list-literal = "[" whsp expression *("," whsp expression) "]"
+non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]"
 
 ; "( e )"
-parenthesized-expression = "(" whsp expression ")"
+parenthesized-expression = "(" whsp expression whsp ")"
 
 
 ; All expressions end with trailing whitespace.  This just adds a final
 ; whitespace prefix for the top-level of the program
-complete-expression = whsp expression
+complete-expression = whsp expression whsp
diff --git a/do.pl b/do.pl
index 53004af..d7a7484 100755
--- a/do.pl
+++ b/do.pl
@@ -67,8 +67,16 @@
 # next if /^ *;/; s/\b(?<!-)union-type-or-literal\b(?!-)/union-type-or-literal whsp/g;
 # next if /^ *;/; s/\b(?<!-)non-empty-union-type-or-literal\b(?!-)/non-empty-union-type-or-literal whsp/g;
 # next if /^ *;/; s/\b(?<!-)non-empty-list-literal\b(?!-)/non-empty-list-literal whsp/g;
+#
 # next if /^ *;/; s/\b(?<!-)expression\b(?!-)/expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)lambda-expression\b(?!-)/lambda-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)ifthenelse-expression\b(?!-)/ifthenelse-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)let-expression\b(?!-)/let-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)forall-expression\b(?!-)/forall-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)arrow-expression\b(?!-)/arrow-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)merge-expression\b(?!-)/merge-expression whsp/g;
 # next if /^ *;/; s/\b(?<!-)annotated-expression\b(?!-)/annotated-expression whsp/g;
+# next if /^ *;/; s/\b(?<!-)empty-list-or-optional\b(?!-)/empty-list-or-optional whsp/g;
 # next if /^ *;/; s/\b(?<!-)empty-collection\b(?!-)/empty-collection whsp/g;
 # next if /^ *;/; s/\b(?<!-)non-empty-optional\b(?!-)/non-empty-optional whsp/g;
 # next if /^ *;/; s/\b(?<!-)operator-expression\b(?!-)/operator-expression whsp/g;
@@ -85,6 +93,7 @@
 # next if /^ *;/; s/\b(?<!-)equal-expression\b(?!-)/equal-expression whsp/g;
 # next if /^ *;/; s/\b(?<!-)not-equal-expression\b(?!-)/not-equal-expression whsp/g;
 # next if /^ *;/; s/\b(?<!-)application-expression\b(?!-)/application-expression whsp/g;
+#
 # next if /^ *;/; s/\b(?<!-)import-expression\b(?!-)/import-expression whsp/g;
 # next if /^ *;/; s/\b(?<!-)selector-expression\b(?!-)/selector-expression whsp/g;
 # next if /^ *;/; s/\b(?<!-)primitive-expression\b(?!-)/primitive-expression whsp/g;
-- 
cgit v1.2.3


From 2930da578e6a7847a33aee0d7145552b299e783d Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 17:23:36 +0200
Subject: rename

---
 dhall_core/src/parser.rs    | 10 +++++-----
 dhall_parser/src/dhall.abnf | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index b7ac3f6..7cbe880 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -265,7 +265,7 @@ make_parser! {
         [simple_label(l)] => l,
         [quoted_label(l)] => l,
     ));
-    rule!(unreserved_label<Label>; children!(
+    rule!(nonreserved_label<Label>; children!(
         [label(l)] => {
             if Builtin::parse(&String::from(&l)).is_some() {
                 Err(
@@ -540,7 +540,7 @@ make_parser! {
     ));
 
     rule!(lambda_expression<ParsedExpr> as expression; children!(
-        [unreserved_label(l), expression(typ), expression(body)] => {
+        [nonreserved_label(l), expression(typ), expression(body)] => {
             bx(Expr::Lam(l, typ, body))
         }
     ));
@@ -561,14 +561,14 @@ make_parser! {
     ));
 
     rule!(let_binding<(Label, Option<ParsedExpr>, ParsedExpr)>; children!(
-        [unreserved_label(name), expression(annot), expression(expr)] =>
+        [nonreserved_label(name), expression(annot), expression(expr)] =>
             (name, Some(annot), expr),
-        [unreserved_label(name), expression(expr)] =>
+        [nonreserved_label(name), expression(expr)] =>
             (name, None, expr),
     ));
 
     rule!(forall_expression<ParsedExpr> as expression; children!(
-        [unreserved_label(l), expression(typ), expression(body)] => {
+        [nonreserved_label(l), expression(typ), expression(body)] => {
             bx(Expr::Pi(l, typ, body))
         }
     ));
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 640a422..8964f44 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -170,11 +170,11 @@ quoted-label = 1*quoted-label-char
 ; for code obfuscation
 label = ("`" quoted-label "`" / simple-label)
 
-; An unreserved-label cannot not be any of the reserved identifiers for builtins (unless quoted).
+; A nonreserved-label cannot not be any of the reserved identifiers for builtins (unless quoted).
 ; Their list can be found in semantics.md. This is not enforced by the grammar but
 ; should be checked by implementations. The only place where this restriction applies
 ; is bound variables.
-unreserved-label = label
+nonreserved-label = label
 
 ; An any-label is allowed to be one of the reserved identifiers.
 any-label = label
@@ -543,7 +543,7 @@ expression =
     / annotated-expression
 
 ; "\(x : a) -> b"
-lambda-expression = lambda whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
+lambda-expression = lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
 
 ; "if a then b else c"
 ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression
@@ -552,10 +552,10 @@ ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else
 ; "let x     = e1 in e2"
 ; "let x = e1 let y = e2 in e3"
 let-expression = 1*let-binding in whsp1 expression
-let-binding = let whsp1 unreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp
+let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp
 
 ; "forall (x : a) -> b"
-forall-expression = forall whsp "(" whsp unreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
+forall-expression = forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
 
 ; "a -> b"
 arrow-expression = operator-expression whsp arrow whsp expression
-- 
cgit v1.2.3


From 4fe44eea36eaf3cc21ef46740825e9aae4d1ea9e Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 18:01:47 +0200
Subject: Roll rc through parser to enable matching

---
 dhall_core/src/parser.rs | 188 ++++++++++++++++++++++++-----------------------
 1 file changed, 95 insertions(+), 93 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 7cbe880..a0e4397 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -13,6 +13,8 @@ use crate::*;
 // their own crate because they are quite general and useful. For now they
 // are here and hopefully you can figure out how they work.
 
+type ParsedExpr = Expr<X, Import>;
+type ParsedSubExpr = SubExpr<X, Import>;
 type ParsedText = InterpolatedText<X, Import>;
 type ParsedTextContents = InterpolatedTextContents<X, Import>;
 
@@ -284,7 +286,7 @@ make_parser! {
 
     rule!(double_quote_chunk<ParsedTextContents>; children!(
         [interpolation(e)] => {
-            InterpolatedTextContents::Expr(e)
+            InterpolatedTextContents::Expr(rc(e))
         },
         [double_quote_escaped(s)] => {
             InterpolatedTextContents::Text(s)
@@ -357,7 +359,7 @@ make_parser! {
 
     rule!(single_quote_continue<Vec<Vec<ParsedTextContents>>>; children!(
         [interpolation(c), single_quote_continue(lines)] => {
-            let c = InterpolatedTextContents::Expr(c);
+            let c = InterpolatedTextContents::Expr(rc(c));
             let mut lines = lines;
             lines.last_mut().unwrap().push(c);
             lines
@@ -526,28 +528,28 @@ make_parser! {
 
     rule!(import<ParsedExpr> as expression; children!(
         [import_hashed(location_hashed)] => {
-            bx(Expr::Embed(Import {
+            Expr::Embed(Import {
                 mode: ImportMode::Code,
                 location_hashed
-            }))
+            })
         },
         [import_hashed(location_hashed), Text(_)] => {
-            bx(Expr::Embed(Import {
+            Expr::Embed(Import {
                 mode: ImportMode::RawText,
                 location_hashed
-            }))
+            })
         },
     ));
 
     rule!(lambda_expression<ParsedExpr> as expression; children!(
         [nonreserved_label(l), expression(typ), expression(body)] => {
-            bx(Expr::Lam(l, typ, body))
+            Expr::Lam(l, rc(typ), rc(body))
         }
     ));
 
     rule!(ifthenelse_expression<ParsedExpr> as expression; children!(
         [expression(cond), expression(left), expression(right)] => {
-            bx(Expr::BoolIf(cond, left, right))
+            Expr::BoolIf(rc(cond), rc(left), rc(right))
         }
     ));
 
@@ -555,35 +557,35 @@ make_parser! {
         [let_binding(bindings).., expression(final_expr)] => {
             bindings.fold(
                 final_expr,
-                |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc))
+                |acc, x| Expr::Let(x.0, x.1, x.2, rc(acc))
             )
         }
     ));
 
-    rule!(let_binding<(Label, Option<ParsedExpr>, ParsedExpr)>; children!(
+    rule!(let_binding<(Label, Option<ParsedSubExpr>, ParsedSubExpr)>; children!(
         [nonreserved_label(name), expression(annot), expression(expr)] =>
-            (name, Some(annot), expr),
+            (name, Some(rc(annot)), rc(expr)),
         [nonreserved_label(name), expression(expr)] =>
-            (name, None, expr),
+            (name, None, rc(expr)),
     ));
 
     rule!(forall_expression<ParsedExpr> as expression; children!(
         [nonreserved_label(l), expression(typ), expression(body)] => {
-            bx(Expr::Pi(l, typ, body))
+            Expr::Pi(l, rc(typ), rc(body))
         }
     ));
 
     rule!(arrow_expression<ParsedExpr> as expression; children!(
         [expression(typ), expression(body)] => {
-            bx(Expr::Pi("_".into(), typ, body))
+            Expr::Pi("_".into(), rc(typ), rc(body))
         }
     ));
 
     rule!(merge_expression<ParsedExpr> as expression; children!(
         [expression(x), expression(y), expression(z)] =>
-            bx(Expr::Merge(x, y, Some(z))),
+            Expr::Merge(rc(x), rc(y), Some(rc(z))),
         [expression(x), expression(y)] =>
-            bx(Expr::Merge(x, y, None)),
+            Expr::Merge(rc(x), rc(y), None),
     ));
 
     rule!(List<()>; captured_str!(_) => ());
@@ -591,16 +593,16 @@ make_parser! {
 
     rule!(empty_collection<ParsedExpr> as expression; children!(
         [List(_), expression(t)] => {
-            bx(Expr::EmptyListLit(t))
+            Expr::EmptyListLit(rc(t))
         },
         [Optional(_), expression(t)] => {
-            bx(Expr::EmptyOptionalLit(t))
+            Expr::EmptyOptionalLit(rc(t))
         },
     ));
 
     rule!(non_empty_optional<ParsedExpr> as expression; children!(
         [expression(x), Optional(_), expression(t)] => {
-            rc(Expr::Annot(rc(Expr::NEOptionalLit(x)), t))
+            Expr::Annot(rc(Expr::NEOptionalLit(rc(x))), rc(t))
         }
     ));
 
@@ -608,117 +610,117 @@ make_parser! {
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::ImportAlt;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(or_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::BoolOr;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(plus_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::NaturalPlus;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(text_append_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::TextAppend;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(list_append_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::ListAppend;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(and_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::BoolAnd;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(combine_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::Combine;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(prefer_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::Prefer;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(combine_types_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::CombineTypes;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(times_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::NaturalTimes;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(equal_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::BoolEQ;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
     rule!(not_equal_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(rest)..] => {
             let o = BinOp::BoolNE;
-            rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e)))
+            rest.fold(first, |acc, e| Expr::BinOp(o, rc(acc), rc(e)))
         },
     ));
 
     rule!(annotated_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(e), expression(annot)] => {
-            bx(Expr::Annot(e, annot))
+            Expr::Annot(rc(e), rc(annot))
         },
     ));
 
     rule!(application_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(first), expression(second)] => {
-            match first.as_ref() {
+            match first {
                 Expr::Builtin(Builtin::OptionalNone) =>
-                    bx(Expr::EmptyOptionalLit(second)),
+                    Expr::EmptyOptionalLit(rc(second)),
                 Expr::Builtin(Builtin::OptionalSome) =>
-                    bx(Expr::NEOptionalLit(second)),
-                _ => bx(Expr::App(first, vec![second])),
+                    Expr::NEOptionalLit(rc(second)),
+                _ => Expr::App(rc(first), vec![rc(second)]),
             }
         },
         [expression(first), expression(second), expression(rest)..] => {
-            match first.as_ref() {
+            match first {
                 Expr::Builtin(Builtin::OptionalNone) =>
-                    bx(Expr::App(bx(Expr::EmptyOptionalLit(second)),
-                                 rest.collect())),
+                    Expr::App(rc(Expr::EmptyOptionalLit(rc(second))),
+                                 rest.map(rc).collect()),
                 Expr::Builtin(Builtin::OptionalSome) =>
-                    bx(Expr::App(bx(Expr::NEOptionalLit(second)),
-                                 rest.collect())),
-                _ => bx(Expr::App(first,
-                                  std::iter::once(second)
-                                    .chain(rest)
-                                    .collect())),
+                    Expr::App(rc(Expr::NEOptionalLit(rc(second))),
+                                 rest.map(rc).collect()),
+                _ => Expr::App(rc(first),
+                                  std::iter::once(rc(second))
+                                    .chain(rest.map(rc))
+                                    .collect()),
             }
         },
     ));
@@ -727,8 +729,8 @@ make_parser! {
         [expression(e)] => e,
         [expression(first), selector(rest)..] => {
             rest.fold(first, |acc, e| match e {
-                Either::Left(l) => bx(Expr::Field(acc, l)),
-                Either::Right(ls) => bx(Expr::Projection(acc, ls)),
+                Either::Left(l) => Expr::Field(rc(acc), l),
+                Either::Right(ls) => Expr::Projection(rc(acc), ls),
             })
         }
     ));
@@ -743,16 +745,16 @@ make_parser! {
     ));
 
     rule!(literal_expression<ParsedExpr> as expression; children!(
-        [double_literal(n)] => bx(Expr::DoubleLit(n)),
+        [double_literal(n)] => Expr::DoubleLit(n),
         [minus_infinity_literal(n)] =>
-            bx(Expr::DoubleLit(std::f64::NEG_INFINITY.into())),
+            Expr::DoubleLit(std::f64::NEG_INFINITY.into()),
         [plus_infinity_literal(n)] =>
-            bx(Expr::DoubleLit(std::f64::INFINITY.into())),
-        [NaN(n)] => bx(Expr::DoubleLit(std::f64::NAN.into())),
-        [natural_literal(n)] => bx(Expr::NaturalLit(n)),
-        [integer_literal(n)] => bx(Expr::IntegerLit(n)),
-        [double_quote_literal(s)] => bx(Expr::TextLit(s)),
-        [single_quote_literal(s)] => bx(Expr::TextLit(s)),
+            Expr::DoubleLit(std::f64::INFINITY.into()),
+        [NaN(n)] => Expr::DoubleLit(std::f64::NAN.into()),
+        [natural_literal(n)] => Expr::NaturalLit(n),
+        [integer_literal(n)] => Expr::IntegerLit(n),
+        [double_quote_literal(s)] => Expr::TextLit(s),
+        [single_quote_literal(s)] => Expr::TextLit(s),
         [expression(e)] => e,
     ));
 
@@ -760,116 +762,116 @@ make_parser! {
         [label(l), natural_literal(idx)] => {
             let name = String::from(&l);
             match Builtin::parse(name.as_str()) {
-                Some(b) => bx(Expr::Builtin(b)),
+                Some(b) => Expr::Builtin(b),
                 None => match name.as_str() {
-                    "True" => bx(Expr::BoolLit(true)),
-                    "False" => bx(Expr::BoolLit(false)),
-                    "Type" => bx(Expr::Const(Const::Type)),
-                    "Kind" => bx(Expr::Const(Const::Kind)),
-                    _ => bx(Expr::Var(V(l, idx))),
+                    "True" => Expr::BoolLit(true),
+                    "False" => Expr::BoolLit(false),
+                    "Type" => Expr::Const(Const::Type),
+                    "Kind" => Expr::Const(Const::Kind),
+                    _ => Expr::Var(V(l, idx)),
                 }
             }
         },
         [label(l)] => {
             let name = String::from(&l);
             match Builtin::parse(name.as_str()) {
-                Some(b) => bx(Expr::Builtin(b)),
+                Some(b) => Expr::Builtin(b),
                 None => match name.as_str() {
-                    "True" => bx(Expr::BoolLit(true)),
-                    "False" => bx(Expr::BoolLit(false)),
-                    "Type" => bx(Expr::Const(Const::Type)),
-                    "Kind" => bx(Expr::Const(Const::Kind)),
-                    _ => bx(Expr::Var(V(l, 0))),
+                    "True" => Expr::BoolLit(true),
+                    "False" => Expr::BoolLit(false),
+                    "Type" => Expr::Const(Const::Type),
+                    "Kind" => Expr::Const(Const::Kind),
+                    _ => Expr::Var(V(l, 0)),
                 }
             }
         },
     ));
 
     rule!(empty_record_literal<ParsedExpr> as expression;
-        captured_str!(_) => bx(Expr::RecordLit(BTreeMap::new()))
+        captured_str!(_) => Expr::RecordLit(BTreeMap::new())
     );
 
     rule!(empty_record_type<ParsedExpr> as expression;
-        captured_str!(_) => bx(Expr::RecordType(BTreeMap::new()))
+        captured_str!(_) => Expr::RecordType(BTreeMap::new())
     );
 
     rule!(non_empty_record_type_or_literal<ParsedExpr> as expression; children!(
         [label(first_label), non_empty_record_type(rest)] => {
             let (first_expr, mut map) = rest;
-            map.insert(first_label, first_expr);
-            bx(Expr::RecordType(map))
+            map.insert(first_label, rc(first_expr));
+            Expr::RecordType(map)
         },
         [label(first_label), non_empty_record_literal(rest)] => {
             let (first_expr, mut map) = rest;
-            map.insert(first_label, first_expr);
-            bx(Expr::RecordLit(map))
+            map.insert(first_label, rc(first_expr));
+            Expr::RecordLit(map)
         },
     ));
 
     rule!(non_empty_record_type
-          <(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!(
+          <(ParsedExpr, BTreeMap<Label, ParsedSubExpr>)>; children!(
         [expression(expr), record_type_entry(entries)..] => {
             (expr, entries.collect())
         }
     ));
 
-    rule!(record_type_entry<(Label, ParsedExpr)>; children!(
-        [label(name), expression(expr)] => (name, expr)
+    rule!(record_type_entry<(Label, ParsedSubExpr)>; children!(
+        [label(name), expression(expr)] => (name, rc(expr))
     ));
 
     rule!(non_empty_record_literal
-          <(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!(
+          <(ParsedExpr, BTreeMap<Label, ParsedSubExpr>)>; children!(
         [expression(expr), record_literal_entry(entries)..] => {
             (expr, entries.collect())
         }
     ));
 
-    rule!(record_literal_entry<(Label, ParsedExpr)>; children!(
-        [label(name), expression(expr)] => (name, expr)
+    rule!(record_literal_entry<(Label, ParsedSubExpr)>; children!(
+        [label(name), expression(expr)] => (name, rc(expr))
     ));
 
     rule!(union_type_or_literal<ParsedExpr> as expression; children!(
         [empty_union_type(_)] => {
-            bx(Expr::UnionType(BTreeMap::new()))
+            Expr::UnionType(BTreeMap::new())
         },
         [non_empty_union_type_or_literal((Some((l, e)), entries))] => {
-            bx(Expr::UnionLit(l, e, entries))
+            Expr::UnionLit(l, e, entries)
         },
         [non_empty_union_type_or_literal((None, entries))] => {
-            bx(Expr::UnionType(entries))
+            Expr::UnionType(entries)
         },
     ));
 
     rule!(empty_union_type<()>; captured_str!(_) => ());
 
     rule!(non_empty_union_type_or_literal
-          <(Option<(Label, ParsedExpr)>, BTreeMap<Label, ParsedExpr>)>;
+          <(Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>)>;
             children!(
         [label(l), expression(e), union_type_entries(entries)] => {
-            (Some((l, e)), entries)
+            (Some((l, rc(e))), entries)
         },
         [label(l), expression(e), non_empty_union_type_or_literal(rest)] => {
             let (x, mut entries) = rest;
-            entries.insert(l, e);
+            entries.insert(l, rc(e));
             (x, entries)
         },
         [label(l), expression(e)] => {
             let mut entries = BTreeMap::new();
-            entries.insert(l, e);
+            entries.insert(l, rc(e));
             (None, entries)
         },
     ));
 
-    rule!(union_type_entries<BTreeMap<Label, ParsedExpr>>; children!(
+    rule!(union_type_entries<BTreeMap<Label, ParsedSubExpr>>; children!(
         [union_type_entry(entries)..] => entries.collect()
     ));
 
-    rule!(union_type_entry<(Label, ParsedExpr)>; children!(
-        [label(name), expression(expr)] => (name, expr)
+    rule!(union_type_entry<(Label, ParsedSubExpr)>; children!(
+        [label(name), expression(expr)] => (name, rc(expr))
     ));
 
     rule!(non_empty_list_literal<ParsedExpr> as expression; children!(
-        [expression(items)..] => bx(Expr::NEListLit(items.collect()))
+        [expression(items)..] => Expr::NEListLit(items.map(rc).collect())
     ));
 
     rule!(final_expression<ParsedExpr> as expression; children!(
@@ -877,15 +879,15 @@ make_parser! {
     ));
 }
 
-pub fn parse_expr(s: &str) -> ParseResult<ParsedExpr> {
+pub fn parse_expr(s: &str) -> ParseResult<ParsedSubExpr> {
     let mut pairs = DhallParser::parse(Rule::final_expression, s)?;
     let expr = do_parse(pairs.next().unwrap())?;
     assert_eq!(pairs.next(), None);
     match expr {
-        ParsedValue::expression(e) => Ok(e),
+        ParsedValue::expression(e) => Ok(rc(e)),
         _ => unreachable!(),
     }
-    // Ok(bx(Expr::BoolLit(false)))
+    // Ok(rc(Expr::BoolLit(false)))
 }
 
 #[test]
-- 
cgit v1.2.3


From 04c6cd248aff1cbce68ae2fb997705e921d21809 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 18:12:19 +0200
Subject: Tweak matching on Some/None

---
 dhall_core/src/core.rs   | 19 +++++++++++++++++++
 dhall_core/src/parser.rs | 30 +++++++++---------------------
 2 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs
index 0ea8c83..afa3d3f 100644
--- a/dhall_core/src/core.rs
+++ b/dhall_core/src/core.rs
@@ -324,6 +324,25 @@ pub fn rc<T>(x: T) -> Rc<T> {
     Rc::new(x)
 }
 
+pub fn app<N, E>(f: Expr<N, E>, args: Vec<SubExpr<N, E>>) -> Expr<N, E> {
+    if args.is_empty() {
+        f
+    } else {
+        Expr::App(rc(f), args)
+    }
+}
+
+pub fn app_rc<N, E>(
+    f: SubExpr<N, E>,
+    args: Vec<SubExpr<N, E>>,
+) -> SubExpr<N, E> {
+    if args.is_empty() {
+        f
+    } else {
+        rc(Expr::App(f, args))
+    }
+}
+
 fn add_ui(u: usize, i: isize) -> usize {
     if i < 0 {
         u.checked_sub(i.checked_neg().unwrap() as usize).unwrap()
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index a0e4397..68796c4 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -700,28 +700,16 @@ make_parser! {
 
     rule!(application_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
-        [expression(first), expression(second)] => {
-            match first {
-                Expr::Builtin(Builtin::OptionalNone) =>
-                    Expr::EmptyOptionalLit(rc(second)),
-                Expr::Builtin(Builtin::OptionalSome) =>
-                    Expr::NEOptionalLit(rc(second)),
-                _ => Expr::App(rc(first), vec![rc(second)]),
-            }
+        [expression(Expr::Builtin(Builtin::OptionalNone)),
+                expression(e), expression(rest)..] => {
+            app(Expr::EmptyOptionalLit(rc(e)), rest.map(rc).collect())
         },
-        [expression(first), expression(second), expression(rest)..] => {
-            match first {
-                Expr::Builtin(Builtin::OptionalNone) =>
-                    Expr::App(rc(Expr::EmptyOptionalLit(rc(second))),
-                                 rest.map(rc).collect()),
-                Expr::Builtin(Builtin::OptionalSome) =>
-                    Expr::App(rc(Expr::NEOptionalLit(rc(second))),
-                                 rest.map(rc).collect()),
-                _ => Expr::App(rc(first),
-                                  std::iter::once(rc(second))
-                                    .chain(rest.map(rc))
-                                    .collect()),
-            }
+        [expression(Expr::Builtin(Builtin::OptionalSome)),
+                expression(e), expression(rest)..] => {
+            app(Expr::NEOptionalLit(rc(e)), rest.map(rc).collect())
+        },
+        [expression(first), expression(rest)..] => {
+            app(first, rest.map(rc).collect())
         },
     ));
 
-- 
cgit v1.2.3


From a342f45f820e28638e4a73a7b3a577ebf2396b0d Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 18:48:42 +0200
Subject: Factor back in some rule branches

---
 dhall_core/src/parser.rs               | 93 ++++++++++++++++++----------------
 dhall_parser/src/dhall.abnf            | 64 +++++++++++------------
 dhall_parser/src/dhall.pest.visibility | 22 +++-----
 3 files changed, 84 insertions(+), 95 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 68796c4..f888f94 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -116,8 +116,10 @@ fn debug_pair(pair: Pair<Rule>) -> String {
 
 macro_rules! make_parser {
     (@pattern, rule, $name:ident) => (Rule::$name);
+    (@pattern, token_rule, $name:ident) => (Rule::$name);
     (@pattern, rule_group, $name:ident) => (_);
     (@filter, rule) => (true);
+    (@filter, token_rule) => (true);
     (@filter, rule_group) => (false);
 
     (@body,
@@ -164,6 +166,13 @@ macro_rules! make_parser {
         ).ok_or_else(|| -> String { unreachable!() })?;
         Ok(ParsedValue::$group(res))
     });
+    (@body,
+        $pair:expr,
+        $children:expr,
+        token_rule!($name:ident<$o:ty>)
+    ) => ({
+        Ok(ParsedValue::$name(()))
+    });
     (@body, $pair:expr, $children:expr, rule_group!( $name:ident<$o:ty> )) => (
         unreachable!()
     );
@@ -235,7 +244,8 @@ fn do_parse<'a>(initial_pair: Pair<'a, Rule>) -> ParseResult<ParsedValue<'a>> {
 fn can_be_shortcutted(rule: Rule) -> bool {
     use Rule::*;
     match rule {
-        import_alt_expression
+        expression
+        | import_alt_expression
         | or_expression
         | plus_expression
         | text_append_expression
@@ -255,7 +265,7 @@ fn can_be_shortcutted(rule: Rule) -> bool {
 }
 
 make_parser! {
-    rule!(EOI<()>; captured_str!(_) => ());
+    token_rule!(EOI<()>);
 
     rule!(simple_label<Label>;
         captured_str!(s) => Label::from(s.trim().to_owned())
@@ -321,7 +331,7 @@ make_parser! {
         captured_str!(s) => s
     );
 
-    rule!(end_of_line<()>; captured_str!(_) => ());
+    token_rule!(end_of_line<()>);
 
     rule!(single_quote_literal<ParsedText>; children!(
         [end_of_line(eol), single_quote_continue(lines)] => {
@@ -392,9 +402,9 @@ make_parser! {
         },
     ));
 
-    rule!(NaN<()>; captured_str!(_) => ());
-    rule!(minus_infinity_literal<()>; captured_str!(_) => ());
-    rule!(plus_infinity_literal<()>; captured_str!(_) => ());
+    token_rule!(NaN<()>);
+    token_rule!(minus_infinity_literal<()>);
+    token_rule!(plus_infinity_literal<()>);
 
     rule!(double_literal<core::Double>;
         captured_str!(s) => {
@@ -491,7 +501,7 @@ make_parser! {
     rule!(bash_environment_variable<String>; captured_str!(s) => s.to_owned());
     rule!(posix_environment_variable<String>; captured_str!(s) => s.to_owned());
 
-    rule!(missing<()>; captured_str!(_) => ());
+    token_rule!(missing<()>);
 
     rule!(import_type<ImportLocation>; children!(
         [missing(_)] => {
@@ -522,9 +532,7 @@ make_parser! {
             ImportHashed { location, hash: Some(h) },
     ));
 
-    rule_group!(expression<ParsedExpr>);
-
-    rule!(Text<()>; captured_str!(_) => ());
+    token_rule!(Text<()>);
 
     rule!(import<ParsedExpr> as expression; children!(
         [import_hashed(location_hashed)] => {
@@ -541,25 +549,39 @@ make_parser! {
         },
     ));
 
-    rule!(lambda_expression<ParsedExpr> as expression; children!(
-        [nonreserved_label(l), expression(typ), expression(body)] => {
-            Expr::Lam(l, rc(typ), rc(body))
-        }
-    ));
+    token_rule!(lambda<()>);
+    token_rule!(forall<()>);
+    token_rule!(arrow<()>);
+    token_rule!(merge<()>);
+    token_rule!(if_<()>);
+    token_rule!(in_<()>);
 
-    rule!(ifthenelse_expression<ParsedExpr> as expression; children!(
-        [expression(cond), expression(left), expression(right)] => {
+    rule!(expression<ParsedExpr> as expression; children!(
+        [lambda(()), nonreserved_label(l), expression(typ), arrow(()), expression(body)] => {
+            Expr::Lam(l, rc(typ), rc(body))
+        },
+        [if_(()), expression(cond), expression(left), expression(right)] => {
             Expr::BoolIf(rc(cond), rc(left), rc(right))
-        }
-    ));
-
-    rule!(let_expression<ParsedExpr> as expression; children!(
-        [let_binding(bindings).., expression(final_expr)] => {
+        },
+        [let_binding(bindings).., in_(()), expression(final_expr)] => {
             bindings.fold(
                 final_expr,
                 |acc, x| Expr::Let(x.0, x.1, x.2, rc(acc))
             )
-        }
+        },
+        [forall(()), nonreserved_label(l), expression(typ), arrow(()), expression(body)] => {
+            Expr::Pi(l, rc(typ), rc(body))
+        },
+        [expression(typ), arrow(()), expression(body)] => {
+            Expr::Pi("_".into(), rc(typ), rc(body))
+        },
+        [merge(()), expression(x), expression(y), expression(z)] => {
+            Expr::Merge(rc(x), rc(y), Some(rc(z)))
+        },
+        [merge(()), expression(x), expression(y)] => {
+            Expr::Merge(rc(x), rc(y), None)
+        },
+        [expression(e)] => e,
     ));
 
     rule!(let_binding<(Label, Option<ParsedSubExpr>, ParsedSubExpr)>; children!(
@@ -569,27 +591,8 @@ make_parser! {
             (name, None, rc(expr)),
     ));
 
-    rule!(forall_expression<ParsedExpr> as expression; children!(
-        [nonreserved_label(l), expression(typ), expression(body)] => {
-            Expr::Pi(l, rc(typ), rc(body))
-        }
-    ));
-
-    rule!(arrow_expression<ParsedExpr> as expression; children!(
-        [expression(typ), expression(body)] => {
-            Expr::Pi("_".into(), rc(typ), rc(body))
-        }
-    ));
-
-    rule!(merge_expression<ParsedExpr> as expression; children!(
-        [expression(x), expression(y), expression(z)] =>
-            Expr::Merge(rc(x), rc(y), Some(rc(z))),
-        [expression(x), expression(y)] =>
-            Expr::Merge(rc(x), rc(y), None),
-    ));
-
-    rule!(List<()>; captured_str!(_) => ());
-    rule!(Optional<()>; captured_str!(_) => ());
+    token_rule!(List<()>);
+    token_rule!(Optional<()>);
 
     rule!(empty_collection<ParsedExpr> as expression; children!(
         [List(_), expression(t)] => {
@@ -830,7 +833,7 @@ make_parser! {
         },
     ));
 
-    rule!(empty_union_type<()>; captured_str!(_) => ());
+    token_rule!(empty_union_type<()>);
 
     rule!(non_empty_union_type_or_literal
           <(Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>)>;
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 8964f44..2fad4d4 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -529,52 +529,46 @@ import = import-hashed [ whsp as whsp1 Text ]
 ; This is important to avoid the need for sequential backtracking in application-expression.
 
 expression =
-    lambda-expression
-    / ifthenelse-expression
-    / let-expression
-    / forall-expression
+    ; "\(x : a) -> b"
+      lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
+    
+    ; "if a then b else c"
+    / if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression
+    
+    ; "let x : t = e1 in e2"
+    ; "let x     = e1 in e2"
+    ; "let x = e1 let y = e2 in e3"
+    / 1*let-binding in whsp1 expression
+    
+    ; "forall (x : a) -> b"
+    / forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
+    
+    ; "a -> b"
     ; NOTE: Backtrack if parsing this alternative fails
-    / arrow-expression
-    / merge-expression
+    / operator-expression whsp arrow whsp expression
+    
+    ; "merge e1 e2 : t"
+    ; "merge e1 e2"
+    / merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ]
+    
+    ; "[]  : List     t"
+    ; "[]  : Optional t"
+    ; "[x] : Optional t"
     ; NOTE: Backtrack if parsing this alternative fails since we can't tell
     ; from the opening bracket whether or not this will be an empty list or
     ; a non-empty list
-    / empty-list-or-optional
+    / "[" whsp (empty-collection / non-empty-optional)
+    
+    ; "x : t"
     / annotated-expression
 
-; "\(x : a) -> b"
-lambda-expression = lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
-
-; "if a then b else c"
-ifthenelse-expression = if whsp1 expression whsp then whsp1 expression whsp else whsp1 expression
+; "x : t"
+annotated-expression = operator-expression [ whsp ":" whsp1 expression ]
 
-; "let x : t = e1 in e2"
-; "let x     = e1 in e2"
-; "let x = e1 let y = e2 in e3"
-let-expression = 1*let-binding in whsp1 expression
 let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp
-
-; "forall (x : a) -> b"
-forall-expression = forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
-
-; "a -> b"
-arrow-expression = operator-expression whsp arrow whsp expression
-
-; "merge e1 e2 : t"
-; "merge e1 e2"
-merge-expression = merge whsp1 import-expression whsp import-expression [ whsp ":" whsp1 application-expression ]
-
-; "[]  : List     t"
-; "[]  : Optional t"
-; "[x] : Optional t"
-empty-list-or-optional = "[" whsp (empty-collection / non-empty-optional)
 empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression
 non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression
 
-; "x : t"
-annotated-expression = operator-expression [ whsp ":" whsp1 expression ]
-
-
 operator-expression = import-alt-expression
 
 ; Nonempty-whitespace to disambiguate `http://a/a?a`
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index e95cd32..ac3ea30 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -34,16 +34,15 @@ single_quote_literal
 # in
 # as
 # using
-# merge
 missing
-# if_
+if_
 # then
 # else_
 # let_
-# in_
+in_
 # as_
 # using
-# merge
+merge
 # Infinity
 Optional
 Text
@@ -78,9 +77,9 @@ List
 # combine
 # combine_types
 # prefer
-# lambda
-# forall
-# arrow
+lambda
+forall
+arrow
 # exponent
 double_literal
 natural_literal
@@ -120,14 +119,7 @@ import_type
 hash
 import_hashed
 import
-# expression
-lambda_expression
-ifthenelse_expression
-let_expression
-forall_expression
-arrow_expression
-merge_expression
-# empty_list_or_optional
+expression
 empty_collection
 non_empty_optional
 annotated_expression
-- 
cgit v1.2.3


From f385e9dabfe3d923a841dc6d99542683cbbbb77a Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 19:46:17 +0200
Subject: Import many trivial changes from upstream

---
 dhall_parser/src/dhall.abnf | 90 ++++++++++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 46 deletions(-)

diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 2fad4d4..ca54215 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -132,6 +132,7 @@ whitespace-chunk =
 
 whsp = *whitespace-chunk
 
+; nonempty whitespace
 whsp1 = 1*whitespace-chunk
 
 ; Uppercase or lowercase ASCII letter
@@ -142,19 +143,13 @@ DIGIT = %x30-39  ; 0-9
 
 HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
 
-; A simple label cannot be one of the following reserved keywords:
-;
-; * if
-; * then
-; * else
-; * let
-; * in
-; * as
-; * using
-; * merge
-; * missing
-; * Infinity
-; * Some
+; A simple label cannot be one of the reserved keywords
+; listed in the `keyword` rule.
+; A PEG parser could use negative lookahead to
+; enforce this, e.g. as follows:
+; simple-label =
+;       keyword 1*simple-label-next-char
+;     / !keyword (simple-label-first-char *simple-label-next-char)
 simple-label-first-char = ALPHA / "_"
 simple-label-next-char = ALPHA / DIGIT / "-" / "/" / "_"
 simple-label = simple-label-first-char *simple-label-next-char
@@ -174,6 +169,7 @@ label = ("`" quoted-label "`" / simple-label)
 ; Their list can be found in semantics.md. This is not enforced by the grammar but
 ; should be checked by implementations. The only place where this restriction applies
 ; is bound variables.
+; A PEG parser could use negative lookahead to avoid parsing those identifiers.
 nonreserved-label = label
 
 ; An any-label is allowed to be one of the reserved identifiers.
@@ -216,8 +212,8 @@ any-label = label
 ; > "\uD834\uDD1E".
 double-quote-chunk =
       interpolation
-      ; '\'
-    / %x5C double-quote-escaped 
+      ; '\'    Beginning of escape sequence
+    / %x5C double-quote-escaped
     / double-quote-char
 
 double-quote-escaped =
@@ -273,7 +269,6 @@ single-quote-char =
 
 single-quote-literal = "''" end-of-line single-quote-continue
 
-; Interpolation
 interpolation = "${" complete-expression "}"
 
 text-literal = (double-quote-literal / single-quote-literal)
@@ -281,25 +276,25 @@ text-literal = (double-quote-literal / single-quote-literal)
 ; RFC 5234 interprets string literals as case-insensitive and recommends using
 ; hex instead for case-sensitive strings
 ;
-; If you don't feel like reading hex, these are all the same as the rule name,
-; except without the '' ending.
+; If you don't feel like reading hex, these are all the same as the rule name.
 ; Keywords that should never be parsed as identifiers
-if                = %x69.66
-then              = %x74.68.65.6e
-else              = %x65.6c.73.65
-let               = %x6c.65.74
-in                = %x69.6e
-as                = %x61.73
-using             = %x75.73.69.6e.67
-merge             = %x6d.65.72.67.65
-missing           = %x6d.69.73.73.69.6e.67
-Infinity          = %x49.6e.66.69.6e.69.74.79
+if                    = %x69.66
+then                  = %x74.68.65.6e
+else                  = %x65.6c.73.65
+let                   = %x6c.65.74
+in                    = %x69.6e
+as                    = %x61.73
+using                 = %x75.73.69.6e.67
+merge                 = %x6d.65.72.67.65
+missing               = %x6d.69.73.73.69.6e.67
+Infinity              = %x49.6e.66.69.6e.69.74.79
+NaN                   = %x4e.61.4e
+Some                  = %x53.6f.6d.65
+
 ; Reserved identifiers, only needed for some special cases of parsing
 Optional              = %x4f.70.74.69.6f.6e.61.6c
 Text                  = %x54.65.78.74
 List                  = %x4c.69.73.74
-NaN               = %x4e.61.4e
-Some              = %x53.6f.6d.65
 
 combine       = %x2227 / "/\"
 combine-types = %x2A53 / "//\\"
@@ -363,6 +358,8 @@ quoted-path-component = 1*quoted-path-character
 
 path-component = "/" ( unquoted-path-component / %x22 quoted-path-component %x22 )
 
+; The last path-component matched by this rule is referred to as "file" in the semantics,
+; and the other path-components as "directory".
 path = 1*path-component
 
 local =
@@ -513,7 +510,7 @@ posix-environment-variable-character =
 
 import-type = missing / local / http / env
 
-hash = %x73.68.61.32.35.36.3a 64HEXDIG  ; "sha256:XXX...XXX"
+hash = %x73.68.61.32.35.36.3a 64HEXDIG ; "sha256:XXX...XXX"
 
 import-hashed = import-type [ whsp hash ]
 
@@ -522,12 +519,6 @@ import-hashed = import-type [ whsp hash ]
 ; "env:FOO"
 import = import-hashed [ whsp as whsp1 Text ]
 
-; NOTE: Every rule past this point should only reference rules that end with
-; whitespace.  This ensures consistent handling of whitespace in the absence of
-; a separate lexing step.
-; The exception is the rules ending in , which should _not_ end in whitespace.
-; This is important to avoid the need for sequential backtracking in application-expression.
-
 expression =
     ; "\(x : a) -> b"
       lambda whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
@@ -544,6 +535,7 @@ expression =
     / forall whsp "(" whsp nonreserved-label whsp ":" whsp1 expression whsp ")" whsp arrow whsp expression
     
     ; "a -> b"
+    ;
     ; NOTE: Backtrack if parsing this alternative fails
     / operator-expression whsp arrow whsp expression
     
@@ -554,6 +546,7 @@ expression =
     ; "[]  : List     t"
     ; "[]  : Optional t"
     ; "[x] : Optional t"
+    ;
     ; NOTE: Backtrack if parsing this alternative fails since we can't tell
     ; from the opening bracket whether or not this will be an empty list or
     ; a non-empty list
@@ -562,11 +555,17 @@ expression =
     ; "x : t"
     / annotated-expression
 
-; "x : t"
+; Nonempty-whitespace to disambiguate `env:VARIABLE` from type annotations
 annotated-expression = operator-expression [ whsp ":" whsp1 expression ]
 
+; "let x = e1"
 let-binding = let whsp1 nonreserved-label whsp [ ":" whsp1 expression whsp ] "=" whsp expression whsp
+
+; "]  : List     t"
+; "]  : Optional t"
 empty-collection = "]" whsp ":" whsp1 (List / Optional) whsp import-expression
+
+; "x] : Optional t"
 non-empty-optional = expression whsp "]" whsp ":" whsp1 Optional whsp import-expression
 
 operator-expression = import-alt-expression
@@ -592,14 +591,13 @@ not-equal-expression     = application-expression   *(whsp "!=" whsp application
 application-expression =
     import-expression *(whsp1 import-expression)
 
-import-expression =
-      import
-    / selector-expression
+import-expression = import / selector-expression
 
 ; `record.field` extracts one field of a record
+;
 ; `record.{ field0, field1, field2 }` projects out several fields of a record
 ;
-; NOTE: Backtrack when parsing the `*(dot ...)`.  The reason why is that you
+; NOTE: Backtrack when parsing the `*("." ...)`.  The reason why is that you
 ; can't tell from parsing just the period whether "foo." will become "foo.bar"
 ; (i.e. accessing field `bar` of the record `foo`) or `foo./bar` (i.e. applying
 ; the function `foo` to the relative path `./bar`)
@@ -646,14 +644,13 @@ literal-expression =
 minus-infinity-literal = "-" Infinity
 plus-infinity-literal = Infinity
 
-; "{ foo = 1      , bar = True }"
-; "{ foo : Integer, bar : Bool }"
 record-type-or-literal =
       empty-record-literal
     / non-empty-record-type-or-literal
     / empty-record-type
 empty-record-literal = "=" whsp
 empty-record-type = ""
+
 non-empty-record-type-or-literal =
     any-label whsp (non-empty-record-literal / non-empty-record-type)
 non-empty-record-type    = ":" whsp1 expression whsp *("," whsp record-type-entry)
@@ -666,7 +663,9 @@ record-literal-entry = any-label whsp "=" whsp expression whsp
 union-type-or-literal =
       non-empty-union-type-or-literal
     / empty-union-type
+
 empty-union-type = ""
+
 non-empty-union-type-or-literal =
     any-label whsp
     ( "=" whsp expression whsp union-type-entries
@@ -683,6 +682,5 @@ non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]
 parenthesized-expression = "(" whsp expression whsp ")"
 
 
-; All expressions end with trailing whitespace.  This just adds a final
-; whitespace prefix for the top-level of the program
+; This just adds surrounding whitespace for the top-level of the program
 complete-expression = whsp expression whsp
-- 
cgit v1.2.3


From 2ef0951c45e3c9c87990ab7e334059aa9b21f540 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 19:51:12 +0200
Subject: Tweak double literals

---
 dhall_core/src/parser.rs    | 14 ++++++++------
 dhall_parser/src/dhall.abnf | 22 ++++++++++++++--------
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index f888f94..55fb177 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -406,7 +406,7 @@ make_parser! {
     token_rule!(minus_infinity_literal<()>);
     token_rule!(plus_infinity_literal<()>);
 
-    rule!(double_literal<core::Double>;
+    rule!(numeric_double_literal<core::Double>;
         captured_str!(s) => {
             let s = s.trim();
             match s.parse::<f64>() {
@@ -418,6 +418,13 @@ make_parser! {
         }
     );
 
+    rule!(double_literal<core::Double>; children!(
+        [numeric_double_literal(n)] => n,
+        [minus_infinity_literal(n)] => std::f64::NEG_INFINITY.into(),
+        [plus_infinity_literal(n)] => std::f64::INFINITY.into(),
+        [NaN(n)] => std::f64::NAN.into(),
+    ));
+
     rule!(natural_literal<core::Natural>;
         captured_str!(s) => {
             s.trim()
@@ -737,11 +744,6 @@ make_parser! {
 
     rule!(literal_expression<ParsedExpr> as expression; children!(
         [double_literal(n)] => Expr::DoubleLit(n),
-        [minus_infinity_literal(n)] =>
-            Expr::DoubleLit(std::f64::NEG_INFINITY.into()),
-        [plus_infinity_literal(n)] =>
-            Expr::DoubleLit(std::f64::INFINITY.into()),
-        [NaN(n)] => Expr::DoubleLit(std::f64::NAN.into()),
         [natural_literal(n)] => Expr::NaturalLit(n),
         [integer_literal(n)] => Expr::IntegerLit(n),
         [double_quote_literal(s)] => Expr::TextLit(s),
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index ca54215..15fd898 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -305,7 +305,20 @@ arrow         = %x2192 / "->"
 
 exponent = "e" [ "+" / "-" ] 1*DIGIT
 
-double-literal = [ "+" / "-" ] 1*DIGIT ( "." 1*DIGIT [ exponent ] / exponent)
+numeric-double-literal = [ "+" / "-" ] 1*DIGIT ( "." 1*DIGIT [ exponent ] / exponent)
+
+minus-infinity-literal = "-" Infinity
+plus-infinity-literal = Infinity
+
+double-literal =
+    ; "2.0"
+      numeric-double-literal
+    ; "-Infinity"
+    / minus-infinity-literal
+    ; "Infinity"
+    / plus-infinity-literal
+    ; "NaN"
+    / NaN
 
 natural-literal = 1*DIGIT
 
@@ -627,13 +640,6 @@ literal-expression =
     ; "+2"
     / integer-literal
     
-    ; "-Infinity"
-    / minus-infinity-literal
-    ; "Infinity"
-    / plus-infinity-literal
-    ; "NaN"
-    / NaN
-    
     ; '"ABC"'
     / text-literal
     
-- 
cgit v1.2.3


From e05299d3d84dcbba79887f1dc5b42d689b714edc Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 20:07:51 +0200
Subject: Factor literal-expression back in

---
 dhall_core/src/parser.rs               |  2 +-
 dhall_parser/src/dhall.abnf            | 16 ++++------------
 dhall_parser/src/dhall.pest.visibility |  3 +--
 3 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 55fb177..0f6978d 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -742,7 +742,7 @@ make_parser! {
         [label(ls)..] => ls.collect(),
     ));
 
-    rule!(literal_expression<ParsedExpr> as expression; children!(
+    rule!(primitive_expression<ParsedExpr> as expression; children!(
         [double_literal(n)] => Expr::DoubleLit(n),
         [natural_literal(n)] => Expr::NaturalLit(n),
         [integer_literal(n)] => Expr::IntegerLit(n),
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 15fd898..52d5b91 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -622,15 +622,6 @@ labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}"
 
 
 primitive-expression =
-      literal-expression
-    / "{" whsp record-type-or-literal "}"
-    / "<" whsp union-type-or-literal ">"
-    / non-empty-list-literal
-    / parenthesized-expression
-
-; NOTE: Backtrack when parsing the first three alternatives (i.e. the numeric
-; literals).  This is because they share leading characters in common
-literal-expression =
     ; "2.0"
       double-literal
     
@@ -646,9 +637,10 @@ literal-expression =
     ; "x"
     ; "x@2"
     / identifier
-
-minus-infinity-literal = "-" Infinity
-plus-infinity-literal = Infinity
+    / "{" whsp record-type-or-literal "}"
+    / "<" whsp union-type-or-literal ">"
+    / non-empty-list-literal
+    / parenthesized-expression
 
 record-type-or-literal =
       empty-record-literal
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index ac3ea30..63a4179 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -142,8 +142,7 @@ application_expression
 selector_expression
 selector
 labels
-# primitive_expression
-literal_expression
+primitive_expression
 # record_type_or_literal
 empty_record_literal
 empty_record_type
-- 
cgit v1.2.3


From 7b8c64a754bbd2f9c55cf8992d5bcc8c7a460327 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 20:18:19 +0200
Subject: Whitespace

---
 dhall_parser/src/dhall.abnf | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 52d5b91..9456036 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -620,7 +620,8 @@ selector = any-label / labels
 
 labels = "{" whsp [ any-label whsp *("," whsp any-label whsp) ] "}"
 
-
+; NOTE: Backtrack when parsing the first three alternatives (i.e. the numeric
+; literals).  This is because they share leading characters in common
 primitive-expression =
     ; "2.0"
       double-literal
@@ -634,27 +635,27 @@ primitive-expression =
     ; '"ABC"'
     / text-literal
     
+    / "{" whsp record-type-or-literal whsp "}"
+    / "<" whsp union-type-or-literal whsp ">"
+    / non-empty-list-literal
     ; "x"
     ; "x@2"
     / identifier
-    / "{" whsp record-type-or-literal "}"
-    / "<" whsp union-type-or-literal ">"
-    / non-empty-list-literal
-    / parenthesized-expression
+    / "(" whsp expression whsp ")"
 
 record-type-or-literal =
       empty-record-literal
     / non-empty-record-type-or-literal
     / empty-record-type
-empty-record-literal = "=" whsp
+empty-record-literal = "="
 empty-record-type = ""
 
 non-empty-record-type-or-literal =
     any-label whsp (non-empty-record-literal / non-empty-record-type)
-non-empty-record-type    = ":" whsp1 expression whsp *("," whsp record-type-entry)
-record-type-entry = any-label whsp ":" whsp1 expression whsp
-non-empty-record-literal = "=" whsp expression whsp *("," whsp record-literal-entry)
-record-literal-entry = any-label whsp "=" whsp expression whsp
+non-empty-record-type    = ":" whsp1 expression *(whsp "," whsp record-type-entry)
+record-type-entry = any-label whsp ":" whsp1 expression
+non-empty-record-literal = "=" whsp expression *(whsp "," whsp record-literal-entry)
+record-literal-entry = any-label whsp "=" whsp expression
 
 ; "< Foo : Integer | Bar : Bool >"
 ; "< Foo : Integer | Bar = True >"
@@ -666,19 +667,16 @@ empty-union-type = ""
 
 non-empty-union-type-or-literal =
     any-label whsp
-    ( "=" whsp expression whsp union-type-entries
-    / ":" whsp1 expression whsp [ "|" whsp non-empty-union-type-or-literal ]
+    ( "=" whsp expression union-type-entries
+    / ":" whsp1 expression [ whsp "|" whsp non-empty-union-type-or-literal ]
     )
-union-type-entries = *("|" whsp union-type-entry)
-union-type-entry = any-label whsp ":" whsp1 expression whsp
+union-type-entries = *(whsp "|" whsp union-type-entry)
+union-type-entry = any-label whsp ":" whsp1 expression
 
 ; "[1, 2, 3]"
 ; `empty-list-or-optional` handles empty lists
 non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]"
 
-; "( e )"
-parenthesized-expression = "(" whsp expression whsp ")"
-
 
 ; This just adds surrounding whitespace for the top-level of the program
 complete-expression = whsp expression whsp
-- 
cgit v1.2.3


From ebbd660008dc783ae6c8bc57ca764309ea463a5e Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 20:20:43 +0200
Subject: Import more trivial changes from upstream

---
 dhall_parser/src/dhall.abnf | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 9456036..0f07a20 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -635,30 +635,43 @@ primitive-expression =
     ; '"ABC"'
     / text-literal
     
+    ; "{ foo = 1      , bar = True }"
+    ; "{ foo : Integer, bar : Bool }"
     / "{" whsp record-type-or-literal whsp "}"
+    
+    ; "< Foo : Integer | Bar : Bool >"
+    ; "< Foo : Integer | Bar = True | Baz : Bool >"
+    ; "< Foo | Bar : Bool >"
     / "<" whsp union-type-or-literal whsp ">"
+    
+    ; "[1, 2, 3]"
+    ; `empty-collection` handles empty lists
     / non-empty-list-literal
+    
     ; "x"
     ; "x@2"
     / identifier
-    / "(" whsp expression whsp ")"
+    
+    ; "( e )"
+    / "(" complete-expression ")"
 
 record-type-or-literal =
       empty-record-literal
     / non-empty-record-type-or-literal
     / empty-record-type
+
 empty-record-literal = "="
 empty-record-type = ""
 
 non-empty-record-type-or-literal =
     any-label whsp (non-empty-record-literal / non-empty-record-type)
-non-empty-record-type    = ":" whsp1 expression *(whsp "," whsp record-type-entry)
+
+non-empty-record-type = ":" whsp1 expression *(whsp "," whsp record-type-entry)
 record-type-entry = any-label whsp ":" whsp1 expression
+
 non-empty-record-literal = "=" whsp expression *(whsp "," whsp record-literal-entry)
 record-literal-entry = any-label whsp "=" whsp expression
 
-; "< Foo : Integer | Bar : Bool >"
-; "< Foo : Integer | Bar = True >"
 union-type-or-literal =
       non-empty-union-type-or-literal
     / empty-union-type
-- 
cgit v1.2.3


From 08596e55a3e71f2fd636494aaa232e1cf476e4ac Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 21:35:11 +0200
Subject: Handle Some as in upstream grammar

---
 dhall_core/src/parser.rs    | 43 ++++++++++++++++++++++---------------------
 dhall_parser/src/dhall.abnf |  2 +-
 iter_patterns/src/lib.rs    | 14 +++++++-------
 3 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 0f6978d..60ab6ef 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -479,15 +479,15 @@ make_parser! {
             scheme: sch,
             authority: auth,
             path: p,
-            query: None,
-            headers: None,
+            query: Option::None,
+            headers: Option::None,
         },
         [scheme(sch), authority(auth), path(p), query(q)] => URL {
             scheme: sch,
             authority: auth,
             path: p,
-            query: Some(q),
-            headers: None,
+            query: Option::Some(q),
+            headers: Option::None,
         },
     ));
 
@@ -498,7 +498,7 @@ make_parser! {
     rule!(http<URL>; children!(
         [http_raw(url)] => url,
         [http_raw(url), import_hashed(ih)] =>
-            URL { headers: Some(Box::new(ih)), ..url },
+            URL { headers: Option::Some(Box::new(ih)), ..url },
     ));
 
     rule!(env<String>; children!(
@@ -534,9 +534,9 @@ make_parser! {
 
     rule!(import_hashed<ImportHashed>; children!(
         [import_type(location)] =>
-            ImportHashed { location, hash: None },
+            ImportHashed { location, hash: Option::None },
         [import_type(location), hash(h)] =>
-            ImportHashed { location, hash: Some(h) },
+            ImportHashed { location, hash: Option::Some(h) },
     ));
 
     token_rule!(Text<()>);
@@ -583,19 +583,19 @@ make_parser! {
             Expr::Pi("_".into(), rc(typ), rc(body))
         },
         [merge(()), expression(x), expression(y), expression(z)] => {
-            Expr::Merge(rc(x), rc(y), Some(rc(z)))
+            Expr::Merge(rc(x), rc(y), Option::Some(rc(z)))
         },
         [merge(()), expression(x), expression(y)] => {
-            Expr::Merge(rc(x), rc(y), None)
+            Expr::Merge(rc(x), rc(y), Option::None)
         },
         [expression(e)] => e,
     ));
 
     rule!(let_binding<(Label, Option<ParsedSubExpr>, ParsedSubExpr)>; children!(
         [nonreserved_label(name), expression(annot), expression(expr)] =>
-            (name, Some(rc(annot)), rc(expr)),
+            (name, Option::Some(rc(annot)), rc(expr)),
         [nonreserved_label(name), expression(expr)] =>
-            (name, None, rc(expr)),
+            (name, Option::None, rc(expr)),
     ));
 
     token_rule!(List<()>);
@@ -708,14 +708,15 @@ make_parser! {
         },
     ));
 
+    token_rule!(Some<()>);
+
     rule!(application_expression<ParsedExpr> as expression; children!(
         [expression(e)] => e,
         [expression(Expr::Builtin(Builtin::OptionalNone)),
                 expression(e), expression(rest)..] => {
             app(Expr::EmptyOptionalLit(rc(e)), rest.map(rc).collect())
         },
-        [expression(Expr::Builtin(Builtin::OptionalSome)),
-                expression(e), expression(rest)..] => {
+        [Some(()), expression(e), expression(rest)..] => {
             app(Expr::NEOptionalLit(rc(e)), rest.map(rc).collect())
         },
         [expression(first), expression(rest)..] => {
@@ -755,8 +756,8 @@ make_parser! {
         [label(l), natural_literal(idx)] => {
             let name = String::from(&l);
             match Builtin::parse(name.as_str()) {
-                Some(b) => Expr::Builtin(b),
-                None => match name.as_str() {
+                Option::Some(b) => Expr::Builtin(b),
+                Option::None => match name.as_str() {
                     "True" => Expr::BoolLit(true),
                     "False" => Expr::BoolLit(false),
                     "Type" => Expr::Const(Const::Type),
@@ -768,8 +769,8 @@ make_parser! {
         [label(l)] => {
             let name = String::from(&l);
             match Builtin::parse(name.as_str()) {
-                Some(b) => Expr::Builtin(b),
-                None => match name.as_str() {
+                Option::Some(b) => Expr::Builtin(b),
+                Option::None => match name.as_str() {
                     "True" => Expr::BoolLit(true),
                     "False" => Expr::BoolLit(false),
                     "Type" => Expr::Const(Const::Type),
@@ -827,10 +828,10 @@ make_parser! {
         [empty_union_type(_)] => {
             Expr::UnionType(BTreeMap::new())
         },
-        [non_empty_union_type_or_literal((Some((l, e)), entries))] => {
+        [non_empty_union_type_or_literal((Option::Some((l, e)), entries))] => {
             Expr::UnionLit(l, e, entries)
         },
-        [non_empty_union_type_or_literal((None, entries))] => {
+        [non_empty_union_type_or_literal((Option::None, entries))] => {
             Expr::UnionType(entries)
         },
     ));
@@ -841,7 +842,7 @@ make_parser! {
           <(Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>)>;
             children!(
         [label(l), expression(e), union_type_entries(entries)] => {
-            (Some((l, rc(e))), entries)
+            (Option::Some((l, rc(e))), entries)
         },
         [label(l), expression(e), non_empty_union_type_or_literal(rest)] => {
             let (x, mut entries) = rest;
@@ -851,7 +852,7 @@ make_parser! {
         [label(l), expression(e)] => {
             let mut entries = BTreeMap::new();
             entries.insert(l, rc(e));
-            (None, entries)
+            (Option::None, entries)
         },
     ));
 
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 0f07a20..4aa3fec 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -602,7 +602,7 @@ not-equal-expression     = application-expression   *(whsp "!=" whsp application
 ; would be ambiguity: `./ab` could be interpreted as "import the file `./ab`",
 ; or "apply the import `./a` to label `b`"
 application-expression =
-    import-expression *(whsp1 import-expression)
+    [ Some whsp1 ] import-expression *(whsp1 import-expression)
 
 import-expression = import / selector-expression
 
diff --git a/iter_patterns/src/lib.rs b/iter_patterns/src/lib.rs
index a4be783..6d3649e 100644
--- a/iter_patterns/src/lib.rs
+++ b/iter_patterns/src/lib.rs
@@ -60,23 +60,23 @@ macro_rules! destructure_iter {
     };
     // Single item pattern
     (@match_forwards, $iter:expr, ($body:expr), $x:pat, $($rest:tt)*) => {
-        if let Some($x) = $iter.next() {
+        if let std::option::Option::Some($x) = $iter.next() {
             $crate::destructure_iter!(@match_forwards,
                 $iter,
                 ($body),
                 $($rest)*
             )
         } else {
-            None
+            std::option::Option::None
         }
     };
     // Single item pattern after a variable length one: declare reversed and take from the end
     (@match_backwards, $iter:expr, ($body:expr), $x:pat, $($rest:tt)*) => {
         $crate::destructure_iter!(@match_backwards, $iter, (
-            if let Some($x) = $iter.next_back() {
+            if let std::option::Option::Some($x) = $iter.next_back() {
                 $body
             } else {
-                None
+                std::option::Option::None
             }
         ), $($rest)*)
     };
@@ -84,7 +84,7 @@ macro_rules! destructure_iter {
     // Check no elements remain
     (@match_forwards, $iter:expr, ($body:expr) $(,)*) => {
         if $iter.next().is_some() {
-            None
+            std::option::Option::None
         } else {
             $body
         }
@@ -100,7 +100,7 @@ macro_rules! destructure_iter {
             let mut iter = $iter;
             $crate::destructure_iter!(@match_forwards,
                 iter,
-                (Some($body)),
+                (std::option::Option::Some($body)),
                 $($args)*,
             )
         }
@@ -216,7 +216,7 @@ macro_rules! match_vec {
                         $crate::destructure_iter!(iter; [$($args)*] => $body)
                     }
                 )*
-                _ => None,
+                _ => std::option::Option::None,
             }
         }
     };
-- 
cgit v1.2.3


From 3e4b2dcb8c371045737901c0d49f9d9403109ea0 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 21:43:41 +0200
Subject: Get keyword rule from upstream

---
 dhall/src/normalize.rs                 | 2 +-
 dhall_parser/build.rs                  | 7 -------
 dhall_parser/src/dhall.abnf            | 9 +++++++++
 dhall_parser/src/dhall.pest.visibility | 1 +
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index a3a2318..d9bd08a 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -107,7 +107,7 @@ where
                 break dhall_expr!(
                     g
                     (List a0)
-                    (λ(a : a0) -> λ(as : List a1) -> [ a ] # as)
+                    (λ(x : a0) -> λ(xs : List a1) -> [ x ] # xs)
                     ([] : List a0)
                 );
             }
diff --git a/dhall_parser/build.rs b/dhall_parser/build.rs
index 4e75181..615a55c 100644
--- a/dhall_parser/build.rs
+++ b/dhall_parser/build.rs
@@ -40,13 +40,6 @@ fn main() -> std::io::Result<()> {
             | !keyword ~ simple_label_first_char ~ simple_label_next_char*
     }}"
     )?;
-    writeln!(
-        &mut file,
-        "keyword = _{{
-            let_ | in_ | if_ | then
-                | else_ | Infinity | NaN
-    }}"
-    )?;
     writeln!(
         &mut file,
         "final_expression = ${{ SOI ~ complete_expression ~ EOI }}"
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 4aa3fec..01ec6d8 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -291,6 +291,15 @@ Infinity              = %x49.6e.66.69.6e.69.74.79
 NaN                   = %x4e.61.4e
 Some                  = %x53.6f.6d.65
 
+; Unused rule that could be used as negative lookahead in the
+; `simple-label` rule for parsers that support this.
+keyword =
+      if / then / else
+    / let / in
+    / using / missing / as
+    / Infinity / NaN
+    / merge / Some
+
 ; Reserved identifiers, only needed for some special cases of parsing
 Optional              = %x4f.70.74.69.6f.6e.61.6c
 Text                  = %x54.65.78.74
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index 63a4179..8205cc8 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -44,6 +44,7 @@ in_
 # using
 merge
 # Infinity
+# keyword
 Optional
 Text
 List
-- 
cgit v1.2.3


From e7a58d09748bd333f755a06090f378e31dc6617a Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 22:28:00 +0200
Subject: Import union rules from upstream grammar

---
 dhall_core/src/parser.rs    | 30 +++++++++++++++++++++---------
 dhall_parser/src/dhall.abnf | 17 +++++++++--------
 2 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 60ab6ef..c569918 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -841,29 +841,41 @@ make_parser! {
     rule!(non_empty_union_type_or_literal
           <(Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>)>;
             children!(
-        [label(l), expression(e), union_type_entries(entries)] => {
+        [label(l), union_literal_variant_value((e, entries))] => {
             (Option::Some((l, rc(e))), entries)
         },
-        [label(l), expression(e), non_empty_union_type_or_literal(rest)] => {
+        [label(l), union_type_or_literal_variant_type((e, rest))] => {
             let (x, mut entries) = rest;
             entries.insert(l, rc(e));
             (x, entries)
         },
-        [label(l), expression(e)] => {
-            let mut entries = BTreeMap::new();
-            entries.insert(l, rc(e));
-            (Option::None, entries)
-        },
     ));
 
-    rule!(union_type_entries<BTreeMap<Label, ParsedSubExpr>>; children!(
-        [union_type_entry(entries)..] => entries.collect()
+    rule!(union_literal_variant_value
+          <(ParsedExpr, BTreeMap<Label, ParsedSubExpr>)>;
+            children!(
+        [expression(e), union_type_entry(entries)..] => {
+            (e, entries.collect())
+        },
     ));
 
     rule!(union_type_entry<(Label, ParsedSubExpr)>; children!(
         [label(name), expression(expr)] => (name, rc(expr))
     ));
 
+    // TODO: unary union variants
+    rule!(union_type_or_literal_variant_type
+          <(ParsedExpr,
+            (Option<(Label, ParsedSubExpr)>, BTreeMap<Label, ParsedSubExpr>))>;
+                children!(
+        [expression(e), non_empty_union_type_or_literal(rest)] => {
+            (e, rest)
+        },
+        [expression(e)] => {
+            (e, (Option::None, BTreeMap::new()))
+        },
+    ));
+
     rule!(non_empty_list_literal<ParsedExpr> as expression; children!(
         [expression(items)..] => Expr::NEListLit(items.map(rc).collect())
     ));
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 01ec6d8..7ad0b24 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -688,17 +688,18 @@ union-type-or-literal =
 empty-union-type = ""
 
 non-empty-union-type-or-literal =
-    any-label whsp
-    ( "=" whsp expression union-type-entries
-    / ":" whsp1 expression [ whsp "|" whsp non-empty-union-type-or-literal ]
-    )
-union-type-entries = *(whsp "|" whsp union-type-entry)
+    any-label [ whsp ( union-literal-variant-value / union-type-or-literal-variant-type) ]
+
+; = True | ...
+union-literal-variant-value = "=" whsp expression *(whsp "|" whsp union-type-entry)
 union-type-entry = any-label whsp ":" whsp1 expression
 
-; "[1, 2, 3]"
-; `empty-list-or-optional` handles empty lists
-non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]"
+; : Integer | ...
+; | ...
+union-type-or-literal-variant-type = [ ":" whsp1 expression ] [ whsp "|" whsp non-empty-union-type-or-literal ]
 
 
+non-empty-list-literal = "[" whsp expression whsp *("," whsp expression whsp) "]"
+
 ; This just adds surrounding whitespace for the top-level of the program
 complete-expression = whsp expression whsp
-- 
cgit v1.2.3


From af968c9e72ef5c2ea1ee965776879d9c903bd1aa Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 22:32:04 +0200
Subject: Revert end_of_line handling to upstream

---
 dhall_core/src/parser.rs               | 4 +---
 dhall_parser/src/dhall.abnf            | 9 ++++-----
 dhall_parser/src/dhall.pest.visibility | 3 +--
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index c569918..b0d80c0 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -331,10 +331,8 @@ make_parser! {
         captured_str!(s) => s
     );
 
-    token_rule!(end_of_line<()>);
-
     rule!(single_quote_literal<ParsedText>; children!(
-        [end_of_line(eol), single_quote_continue(lines)] => {
+        [single_quote_continue(lines)] => {
             let space = InterpolatedTextContents::Text(" ".to_owned());
             let newline = InterpolatedTextContents::Text("\n".to_owned());
             let min_indent = lines
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index 7ad0b24..847da02 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -100,10 +100,9 @@
 ;
 ; For simplicity this supports Unix and Windows line-endings, which are the most
 ; common
-end-of-line-silent =
+end-of-line =
       %x0A     ; "\n"
     / %x0D.0A  ; "\r\n"
-end-of-line = end-of-line-silent
 
 tab = %x09  ; "\t"
 
@@ -113,7 +112,7 @@ block-comment-chunk =
       block-comment
     / %x20-10FFFF
     / tab
-    / end-of-line-silent
+    / end-of-line
 
 block-comment-continue = "-}" / block-comment-chunk block-comment-continue
 
@@ -121,12 +120,12 @@ not-end-of-line = %x20-10FFFF / tab
 
 ; NOTE: Slightly different from Haskell-style single-line comments because this
 ; does not require a space after the dashes
-line-comment = "--" *not-end-of-line end-of-line-silent
+line-comment = "--" *not-end-of-line end-of-line
 
 whitespace-chunk =
       " "
     / tab
-    / end-of-line-silent
+    / end-of-line
     / line-comment
     / block-comment
 
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index 8205cc8..d02298e 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -1,5 +1,4 @@
-end_of_line
-# end_of_line_silent
+# end_of_line
 # tab
 # block_comment
 # block_comment_chunk
-- 
cgit v1.2.3


From 74eb88c42d938672137771fab33ef0118903b5e1 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Thu, 4 Apr 2019 22:46:27 +0200
Subject: Regen visibility list

---
 dhall_parser/src/dhall.pest.visibility | 66 +++++++++++++---------------------
 1 file changed, 25 insertions(+), 41 deletions(-)

diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index d02298e..f881a50 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -12,28 +12,24 @@
 # DIGIT
 # HEXDIG
 # simple_label_first_char
-# simple_label_next_other_char
 # simple_label_next_char
-# simple_label_start
 simple_label
 # quoted_label_char
 quoted_label
 label
+nonreserved_label
 # any_label
 double_quote_chunk
 double_quote_escaped
+double_quote_char
 double_quote_literal
 single_quote_continue
+escaped_quote_pair
+escaped_interpolation
+single_quote_char
 single_quote_literal
+interpolation
 # text_literal
-# if
-# then
-# else
-# let
-# in
-# as
-# using
-missing
 if_
 # then
 # else_
@@ -42,38 +38,14 @@ in_
 # as_
 # using
 merge
+missing
 # Infinity
+NaN
+Some
 # keyword
 Optional
 Text
 List
-# equal
-# or
-# plus
-# text_append
-# list_append
-# and
-# times
-# double_equal
-# not_equal
-# dot
-# bar
-# comma
-# at
-# colon
-# import_alt
-# open_parens
-# close_parens
-# close_parens
-# open_brace
-# close_brace
-# close_brace
-# open_bracket
-# close_bracket
-# close_bracket
-# open_angle
-# close_angle
-# close_angle
 # combine
 # combine_types
 # prefer
@@ -81,15 +53,24 @@ lambda
 forall
 arrow
 # exponent
+numeric_double_literal
+minus_infinity_literal
+plus_infinity_literal
 double_literal
 natural_literal
 integer_literal
 identifier
 # path_character
 # quoted_path_character
+unquoted_path_component
+quoted_path_component
 path_component
 path
 # local
+parent_path
+here_path
+home_path
+absolute_path
 scheme
 http_raw
 authority
@@ -106,7 +87,6 @@ authority
 # reg_name
 # pchar
 query
-fragment
 # pct_encoded
 # unreserved
 # sub_delims
@@ -120,9 +100,10 @@ hash
 import_hashed
 import
 expression
+annotated_expression
+let_binding
 empty_collection
 non_empty_optional
-annotated_expression
 # operator_expression
 import_alt_expression
 or_expression
@@ -137,7 +118,6 @@ times_expression
 equal_expression
 not_equal_expression
 application_expression
-# atomic_expression
 # import_expression
 selector_expression
 selector
@@ -148,10 +128,14 @@ empty_record_literal
 empty_record_type
 non_empty_record_type_or_literal
 non_empty_record_type
+record_type_entry
 non_empty_record_literal
+record_literal_entry
 union_type_or_literal
 empty_union_type
 non_empty_union_type_or_literal
+union_literal_variant_value
+union_type_entry
+union_type_or_literal_variant_type
 non_empty_list_literal
-# parenthesized_expression
 # complete_expression
-- 
cgit v1.2.3


From f78af6d1e7f6c1dc39bde6cf97138327004ddb06 Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Fri, 5 Apr 2019 00:09:07 +0200
Subject: Update dhall-lang submodule

---
 dhall-lang     | 2 +-
 dhall/build.rs | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/dhall-lang b/dhall-lang
index 1f87b02..3084134 160000
--- a/dhall-lang
+++ b/dhall-lang
@@ -1 +1 @@
-Subproject commit 1f87b0285ffc098a3ef05c93a8186c32736bd4a6
+Subproject commit 30841349fd02fd4eb965cba23a8dc557e99fbd15
diff --git a/dhall/build.rs b/dhall/build.rs
index f7a31c0..e80115f 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -23,6 +23,7 @@ fn dhall_files_in_dir<'a>(dir: &'a Path) -> impl Iterator<Item = String> + 'a {
 
 fn main() -> std::io::Result<()> {
     println!("cargo:rerun-if-changed=../dhall-lang/.git");
+    println!("cargo:rerun-if-changed=../.git/modules/dhall-lang/refs/heads/master");
     let out_dir = env::var("OUT_DIR").unwrap();
     let tests_dir = Path::new("../dhall-lang/tests/");
 
-- 
cgit v1.2.3


From 305a2ee7dcd3b3f61bf6877312e3c34767e8bc0c Mon Sep 17 00:00:00 2001
From: Nadrieril
Date: Fri, 5 Apr 2019 22:41:55 +0200
Subject: Remove some unused files

---
 dhall/compare.fish |   9 -----
 do.pl              | 103 -----------------------------------------------------
 2 files changed, 112 deletions(-)
 delete mode 100755 dhall/compare.fish
 delete mode 100755 do.pl

diff --git a/dhall/compare.fish b/dhall/compare.fish
deleted file mode 100755
index 154f06a..0000000
--- a/dhall/compare.fish
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env fish
-
-set dhall_hs_path ../dhall
-set dhall_hs $dhall_hs_path/.stack-work/install/**/bin/dhall
-set dhall_rs target/debug/dhall
-set input_file $argv[1]
-diff -u \
-    --label "dhall-hs < $input_file" (eval $dhall_hs < $input_file ^&1 | psub) \
-    --label "dhall-rs < $input_file" (eval $dhall_rs < $input_file ^&1 | psub)
diff --git a/do.pl b/do.pl
deleted file mode 100755
index d7a7484..0000000
--- a/do.pl
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/env -S perl -i -p
-# next if /^ *;/; s/\b(?<!-)if\b(?!-)/if-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)then\b(?!-)/then-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)else\b(?!-)/else-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)let\b(?!-)/let-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)in\b(?!-)/in-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)as\b(?!-)/as-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)using\b(?!-)/using-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)merge\b(?!-)/merge-raw whsp1/g;
-# next if /^ *;/; s/\b(?<!-)Some\b(?!-)/Some-raw whsp1/g;
-
-# next if /^ *;/; s/\b(?<!-)Optional\b(?!-)/Optional whsp/g;
-# next if /^ *;/; s/\b(?<!-)Text\b(?!-)/Text whsp/g;
-# next if /^ *;/; s/\b(?<!-)List\b(?!-)/List whsp/g;
-
-# next if /^ *;/; s/\b(?<!-)or\b(?!-)/"||" whsp/g;
-# next if /^ *;/; s/\b(?<!-)plus\b(?!-)/"+" whsp1/g;
-# next if /^ *;/; s/\b(?<!-)text-append\b(?!-)/"++" whsp/g;
-# next if /^ *;/; s/\b(?<!-)list-append\b(?!-)/"#" whsp/g;
-# next if /^ *;/; s/\b(?<!-)and\b(?!-)/"&&" whsp/g;
-# next if /^ *;/; s/\b(?<!-)times\b(?!-)/"*" whsp/g;
-# next if /^ *;/; s/\b(?<!-)double-equal\b(?!-)/"==" whsp/g;
-# next if /^ *;/; s/\b(?<!-)not-equal\b(?!-)/"!=" whsp/g;
-# next if /^ *;/; s/\b(?<!-)equal\b(?!-)/"=" whsp/g;
-# next if /^ *;/; s/\b(?<!-)dot\b(?!-)/"." whsp/g;
-# next if /^ *;/; s/\b(?<!-)bar\b(?!-)/"|" whsp/g;
-# next if /^ *;/; s/\b(?<!-)comma\b(?!-)/"," whsp/g;
-# next if /^ *;/; s/\b(?<!-)at\b(?!-)/"@" whsp/g;
-# next if /^ *;/; s/\b(?<!-)open-parens\b(?!-)/"(" whsp/g;
-# next if /^ *;/; s/\b(?<!-)close-parens\b(?!-)/")" whsp/g;
-# next if /^ *;/; s/\b(?<!-)open-brace\b(?!-)/"{" whsp/g;
-# next if /^ *;/; s/\b(?<!-)close-brace\b(?!-)/"}" whsp/g;
-# next if /^ *;/; s/\b(?<!-)open-bracket\b(?!-)/"[" whsp/g;
-# next if /^ *;/; s/\b(?<!-)close-bracket\b(?!-)/"]" whsp/g;
-# next if /^ *;/; s/\b(?<!-)open-angle\b(?!-)/"<" whsp/g;
-# next if /^ *;/; s/\b(?<!-)close-angle\b(?!-)/">" whsp/g;
-# next if /^ *;/; s/\b(?<!-)colon\b(?!-)/":" whsp1/g;
-# next if /^ *;/; s/\b(?<!-)import-alt\b(?!-)/"?" whsp1/g;
-
-# next if /^ *;/; s/\b(?<!-)combine-types\b(?!-)/combine-types whsp/g;
-# next if /^ *;/; s/\b(?<!-)combine\b(?!-)/combine whsp/g;
-# next if /^ *;/; s/\b(?<!-)prefer\b(?!-)/prefer whsp/g;
-# next if /^ *;/; s/\b(?<!-)lambda\b(?!-)/lambda whsp/g;
-# next if /^ *;/; s/\b(?<!-)forall\b(?!-)/forall whsp/g;
-# next if /^ *;/; s/\b(?<!-)arrow\b(?!-)/arrow whsp/g;
-
-# next if /^ *;/; s/\b(?<!-)label\b(?!-)/label whsp/g;
-# next if /^ *;/; s/\b(?<!-)identifier\b(?!-)/identifier whsp/g;
-# next if /^ *;/; s/\b(?<!-)text-literal\b(?!-)/text-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)double-literal\b(?!-)/double-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)integer-literal\b(?!-)/integer-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)natural-literal\b(?!-)/natural-literal whsp/g;
-
-# next if /^ *;/; s/\b(?<!-)import-hashed\b(?!-)/import-hashed whsp/g;
-# next if /^ *;/; s/\b(?<!-)import-type\b(?!-)/import-type whsp/g;
-# next if /^ *;/; s/\b(?<!-)import\b(?!-)/import whsp/g;
-# next if /^ *;/; s/\b(?<!-)local\b(?!-)/local whsp/g;
-# next if /^ *;/; s/\b(?<!-)env\b(?!-)/env whsp/g;
-# next if /^ *;/; s/\b(?<!-)http\b(?!-)/http whsp/g;
-# next if /^ *;/; s/\b(?<!-)missing\b(?!-)/missing whsp/g;
-
-# next if /^ *;/; s/\b(?<!-)labels\b(?!-)/labels whsp/g;
-# next if /^ *;/; s/\b(?<!-)record-type-or-literal\b(?!-)/record-type-or-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-type-or-literal\b(?!-)/non-empty-record-type-or-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-type\b(?!-)/non-empty-record-type whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-record-literal\b(?!-)/non-empty-record-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)union-type-or-literal\b(?!-)/union-type-or-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-union-type-or-literal\b(?!-)/non-empty-union-type-or-literal whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-list-literal\b(?!-)/non-empty-list-literal whsp/g;
-#
-# next if /^ *;/; s/\b(?<!-)expression\b(?!-)/expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)lambda-expression\b(?!-)/lambda-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)ifthenelse-expression\b(?!-)/ifthenelse-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)let-expression\b(?!-)/let-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)forall-expression\b(?!-)/forall-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)arrow-expression\b(?!-)/arrow-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)merge-expression\b(?!-)/merge-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)annotated-expression\b(?!-)/annotated-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)empty-list-or-optional\b(?!-)/empty-list-or-optional whsp/g;
-# next if /^ *;/; s/\b(?<!-)empty-collection\b(?!-)/empty-collection whsp/g;
-# next if /^ *;/; s/\b(?<!-)non-empty-optional\b(?!-)/non-empty-optional whsp/g;
-# next if /^ *;/; s/\b(?<!-)operator-expression\b(?!-)/operator-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)import-alt-expression\b(?!-)/import-alt-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)or-expression\b(?!-)/or-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)plus-expression\b(?!-)/plus-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)text-append-expression\b(?!-)/text-append-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)list-append-expression\b(?!-)/list-append-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)and-expression\b(?!-)/and-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)combine-expression\b(?!-)/combine-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)prefer-expression\b(?!-)/prefer-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)combine-types-expression\b(?!-)/combine-types-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)times-expression\b(?!-)/times-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)equal-expression\b(?!-)/equal-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)not-equal-expression\b(?!-)/not-equal-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)application-expression\b(?!-)/application-expression whsp/g;
-#
-# next if /^ *;/; s/\b(?<!-)import-expression\b(?!-)/import-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)selector-expression\b(?!-)/selector-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)primitive-expression\b(?!-)/primitive-expression whsp/g;
-# next if /^ *;/; s/\b(?<!-)complete-expression\b(?!-)/complete-expression whsp/g;
-
-# next if /^ *;/; s/\b(?<!-)whitespace\b(?!-)/whsp/g;
-# next if /^ *;/; s/\b(?<!-)nonempty-whitespace\b(?!-)/whsp1/g;
-- 
cgit v1.2.3