summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril Feneanar2019-08-07 23:12:47 +0200
committerGitHub2019-08-07 23:12:47 +0200
commit674fbdc33c788156f76d263b044dccc48c810870 (patch)
tree725eaa49a4f2236d44470279296969b66ba0bbc8
parent8ec422f2319360f986950fcb9aae4bcf65a9c1e2 (diff)
parente81ab9a553bf82f20fa0b0344926258176a21dac (diff)
Merge pull request #95 from Nadrieril/catchup-spec
A lot more catching up on the spec
m---------dhall-lang0
-rw-r--r--dhall/build.rs192
-rw-r--r--dhall/src/core/value.rs23
-rw-r--r--dhall/src/error/mod.rs2
-rw-r--r--dhall/src/phase/binary.rs158
-rw-r--r--dhall/src/phase/normalize.rs50
-rw-r--r--dhall/src/phase/resolve.rs19
-rw-r--r--dhall/src/phase/typecheck.rs503
-rw-r--r--dhall/src/tests.rs47
-rw-r--r--dhall_generated_parser/build.rs37
-rw-r--r--dhall_generated_parser/src/dhall.pest.visibility17
-rw-r--r--dhall_syntax/src/core/expr.rs52
-rw-r--r--dhall_syntax/src/core/import.rs2
-rw-r--r--dhall_syntax/src/core/map.rs95
-rw-r--r--dhall_syntax/src/core/visitor.rs32
-rw-r--r--dhall_syntax/src/parser.rs134
-rw-r--r--dhall_syntax/src/printer.rs23
-rw-r--r--tests_buffer7
18 files changed, 695 insertions, 698 deletions
diff --git a/dhall-lang b/dhall-lang
-Subproject ee528e5a89f78bce2c28167b5dfb7e7ea6b3d6c
+Subproject 9f259cd68870b912fbf2f2a08cd63dc3ccba9dc
diff --git a/dhall/build.rs b/dhall/build.rs
index 3f09d47..b6df3d0 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -15,11 +15,15 @@ fn dhall_files_in_dir<'a>(
.filter_map(move |path| {
let path = path.path();
let path = path.strip_prefix(dir).unwrap();
- if path.extension() != Some(&OsString::from("dhall")) {
+ let ext = path.extension();
+ if ext != Some(&OsString::from("dhall"))
+ && ext != Some(&OsString::from("dhallb"))
+ {
return None;
}
+ let ext = ext.unwrap();
let path = path.to_string_lossy();
- let path = &path[..path.len() - 6];
+ let path = &path[..path.len() - 1 - ext.len()];
let path = if take_a_suffix {
if &path[path.len() - 1..] != "A" {
return None;
@@ -37,29 +41,37 @@ fn dhall_files_in_dir<'a>(
fn make_test_module(
w: &mut impl Write, // Where to output the generated code
mod_name: &str, // Name of the module, used in the output of `cargo test`
- dir: &Path, // Directory containing the tests files
+ subdir: &str, // Directory containing the tests files
feature: &str, // Relevant variant of `dhall::tests::Feature`
mut exclude: impl FnMut(&str) -> bool, // Given a file name, whether to exclude it
) -> std::io::Result<()> {
+ let all_tests_dir = Path::new("../dhall-lang/tests/");
+ let tests_dir = all_tests_dir.join(subdir);
writeln!(w, "mod {} {{", mod_name)?;
- for (name, path) in dhall_files_in_dir(&dir.join("success/"), true) {
+ for (name, path) in dhall_files_in_dir(&tests_dir.join("success/"), true) {
if exclude(&("success/".to_owned() + &path)) {
continue;
}
writeln!(
w,
- r#"make_spec_test!({}, Success, success_{}, "success/{}");"#,
- feature, name, path
+ r#"make_spec_test!({}, Success, success_{}, "{}/success/{}");"#,
+ feature,
+ name,
+ tests_dir.to_string_lossy(),
+ path
)?;
}
- for (name, path) in dhall_files_in_dir(&dir.join("failure/"), false) {
+ for (name, path) in dhall_files_in_dir(&tests_dir.join("failure/"), false) {
if exclude(&("failure/".to_owned() + &path)) {
continue;
}
writeln!(
w,
- r#"make_spec_test!({}, Failure, failure_{}, "failure/{}");"#,
- feature, name, path
+ r#"make_spec_test!({}, Failure, failure_{}, "{}/failure/{}");"#,
+ feature,
+ name,
+ tests_dir.to_string_lossy(),
+ path
)?;
}
writeln!(w, "}}")?;
@@ -67,46 +79,61 @@ fn make_test_module(
}
fn main() -> std::io::Result<()> {
- // Tries to detect when the submodule gets updated; doesn't really work.
+ // Tries to detect when the submodule gets updated.
// To force regeneration of the test list, just `touch dhall-lang/.git`
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/");
let parser_tests_path = Path::new(&out_dir).join("spec_tests.rs");
let mut file = File::create(parser_tests_path)?;
- make_test_module(
- &mut file,
- "parse",
- &tests_dir.join("parser/"),
- "Parser",
- |path| {
- // Too slow in debug mode
- path == "success/largeExpression"
- },
- )?;
+ make_test_module(&mut file, "parse", "parser/", "Parser", |path| {
+ // Too slow in debug mode
+ path == "success/largeExpression"
+ // TODO: Inline headers
+ || path == "success/unit/import/parenthesizeUsing"
+ || path == "success/unit/import/inlineUsing"
+ // TODO: projection by expression
+ || path == "success/recordProjectionByExpression"
+ || path == "success/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByTypeEmpty"
+ || path == "success/unit/RecordProjectFields"
+ // TODO: RFC3986 URLs
+ || path == "success/unit/import/urls/emptyPath0"
+ || path == "success/unit/import/urls/emptyPath1"
+ || path == "success/unit/import/urls/emptyPathSegment"
+ // TODO: toMap
+ || path == "success/toMap"
+ })?;
- make_test_module(
- &mut file,
- "printer",
- &tests_dir.join("parser/"),
- "Printer",
- |path| {
- // Failure tests are only for the parser
- path.starts_with("failure/")
+ make_test_module(&mut file, "printer", "parser/", "Printer", |path| {
+ // Failure tests are only for the parser
+ path.starts_with("failure/")
// Too slow in debug mode
|| path == "success/largeExpression"
- },
- )?;
+ // TODO: Inline headers
+ || path == "success/unit/import/inlineUsing"
+ // TODO: projection by expression
+ || path == "success/recordProjectionByExpression"
+ || path == "success/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByTypeEmpty"
+ // TODO: RFC3986 URLs
+ || path == "success/unit/import/urls/emptyPath0"
+ || path == "success/unit/import/urls/emptyPath1"
+ || path == "success/unit/import/urls/emptyPathSegment"
+ // TODO: toMap
+ || path == "success/toMap"
+ })?;
make_test_module(
&mut file,
"binary_encoding",
- &tests_dir.join("parser/"),
+ "parser/",
"BinaryEncoding",
|path| {
// Failure tests are only for the parser
@@ -118,32 +145,123 @@ fn main() -> std::io::Result<()> {
|| path == "success/multilet"
// See https://github.com/pyfisch/cbor/issues/109
|| path == "success/double"
+ // TODO: Inline headers
+ || path == "success/unit/import/inlineUsing"
+ // TODO: projection by expression
+ || path == "success/recordProjectionByExpression"
+ || path == "success/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByTypeEmpty"
+ // TODO: RFC3986 URLs
+ || path == "success/unit/import/urls/emptyPath0"
+ || path == "success/unit/import/urls/emptyPath1"
+ || path == "success/unit/import/urls/emptyPathSegment"
+ // TODO: toMap
+ || path == "success/toMap"
+ },
+ )?;
+
+ make_test_module(
+ &mut file,
+ "binary_decoding",
+ "binary-decode/",
+ "BinaryDecoding",
+ |path| {
+ false
+ // TODO: projection by expression
+ || path == "success/unit/RecordProjectFields"
+ || path == "success/unit/recordProjectionByExpression"
+ // TODO: test is wrong
+ || path == "success/unit/BuiltinNaturalSubtract"
+ // TODO: toMap
+ || path == "success/unit/ToMap"
+ || path == "success/unit/ToMapAnnotated"
},
)?;
make_test_module(
&mut file,
"beta_normalize",
- &tests_dir.join("normalization/"),
+ "normalization/",
"Normalization",
|path| {
// We don't support bignums
path == "success/simple/integerToDouble"
// Too slow
|| path == "success/remoteSystems"
- // TODO: selection by expression
- || path == "success/unit/RecordProjectionTypeEmpty"
- || path == "success/unit/RecordProjectionTypeNonEmpty"
+ // TODO: projection by expression
+ || path == "success/unit/RecordProjectionByTypeEmpty"
+ || path == "success/unit/RecordProjectionByTypeNonEmpty"
+ || path == "success/unit/RecordProjectionByTypeNormalizeProjection"
+ // TODO: fix Double/show
+ || path == "success/prelude/JSON/number/1"
+ // TODO: toMap
+ || path == "success/unit/EmptyToMap"
+ || path == "success/unit/ToMap"
+ || path == "success/unit/ToMapWithType"
+ // Normalize field selection further by inspecting the argument
+ || path == "success/simplifications/rightBiasedMergeWithinRecordProjectionWithinFieldSelection0"
+ || path == "success/simplifications/rightBiasedMergeWithinRecordProjectionWithinFieldSelection1"
+ || path == "success/simplifications/rightBiasedMergeWithinRecursiveRecordMergeWithinFieldselection"
+ || path == "success/unit/RecordProjectionByTypeWithinFieldSelection"
+ || path == "success/unit/RecordProjectionWithinFieldSelection"
+ || path == "success/unit/RecursiveRecordMergeWithinFieldSelection0"
+ || path == "success/unit/RecursiveRecordMergeWithinFieldSelection1"
+ || path == "success/unit/RecursiveRecordMergeWithinFieldSelection2"
+ || path == "success/unit/RightBiasedMergeWithinFieldSelection0"
+ || path == "success/unit/RightBiasedMergeWithinFieldSelection1"
+ || path == "success/unit/RightBiasedMergeWithinFieldSelection2"
},
)?;
make_test_module(
&mut file,
"alpha_normalize",
- &tests_dir.join("alpha-normalization/"),
+ "alpha-normalization/",
"AlphaNormalization",
|_| false,
)?;
+ make_test_module(
+ &mut file,
+ "typecheck",
+ "typecheck/",
+ "Typecheck",
+ |path| {
+ false
+ || path == "failure/importBoundary"
+ // TODO: Inline headers
+ || path == "failure/customHeadersUsingBoundVariable"
+ // TODO: projection by expression
+ || path == "failure/unit/RecordProjectionByTypeFieldTypeMismatch"
+ || path == "failure/unit/RecordProjectionByTypeNotPresent"
+ // TODO: toMap
+ || path == "failure/unit/EmptyToMap"
+ || path == "failure/unit/HeterogenousToMap"
+ || path == "failure/unit/MistypedToMap1"
+ || path == "failure/unit/MistypedToMap2"
+ || path == "failure/unit/MistypedToMap3"
+ || path == "failure/unit/MistypedToMap4"
+ || path == "failure/unit/NonRecordToMap"
+ },
+ )?;
+
+ make_test_module(
+ &mut file,
+ "type_inference",
+ "type-inference/",
+ "TypeInference",
+ |path| {
+ false
+ // TODO: projection by expression
+ || path == "success/unit/RecordProjectionByType"
+ || path == "success/unit/RecordProjectionByTypeEmpty"
+ || path == "success/unit/RecordProjectionByTypeJudgmentalEquality"
+ // TODO: toMap
+ || path == "success/unit/ToMap"
+ || path == "success/unit/ToMapAnnotated"
+ },
+ )?;
+
Ok(())
}
diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs
index bc8fa34..d7b9149 100644
--- a/dhall/src/core/value.rs
+++ b/dhall/src/core/value.rs
@@ -47,6 +47,7 @@ pub enum Value {
DoubleLit(NaiveDouble),
EmptyOptionalLit(TypeThunk),
NEOptionalLit(Thunk),
+ // EmptyListLit(t) means `[] : List t`
EmptyListLit(TypeThunk),
NEListLit(Vec<Thunk>),
RecordLit(HashMap<Label, Thunk>),
@@ -128,9 +129,10 @@ impl Value {
Value::NEOptionalLit(n) => {
rc(ExprF::SomeLit(n.normalize_to_expr_maybe_alpha(alpha)))
}
- Value::EmptyListLit(n) => {
- rc(ExprF::EmptyListLit(n.normalize_to_expr_maybe_alpha(alpha)))
- }
+ Value::EmptyListLit(n) => rc(ExprF::EmptyListLit(rc(ExprF::App(
+ rc(ExprF::Builtin(Builtin::List)),
+ n.normalize_to_expr_maybe_alpha(alpha),
+ )))),
Value::NEListLit(elts) => rc(ExprF::NEListLit(
elts.iter()
.map(|n| n.normalize_to_expr_maybe_alpha(alpha))
@@ -176,19 +178,10 @@ impl Value {
.collect();
rc(ExprF::Field(rc(ExprF::UnionType(kts)), l.clone()))
}
- Value::UnionLit(l, v, kts) => rc(ExprF::UnionLit(
- l.clone(),
+ Value::UnionLit(l, v, kts) => rc(ExprF::App(
+ Value::UnionConstructor(l.clone(), kts.clone())
+ .normalize_to_expr_maybe_alpha(alpha),
v.normalize_to_expr_maybe_alpha(alpha),
- kts.iter()
- .map(|(k, v)| {
- (
- k.clone(),
- v.as_ref().map(|v| {
- v.normalize_to_expr_maybe_alpha(alpha)
- }),
- )
- })
- .collect(),
)),
Value::TextLit(elts) => {
use InterpolatedTextContents::{Expr, Text};
diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs
index aed6ccd..a0ee30a 100644
--- a/dhall/src/error/mod.rs
+++ b/dhall/src/error/mod.rs
@@ -86,7 +86,7 @@ pub(crate) enum TypeMessage {
RecordTypeMergeRequiresRecordType(Type),
RecordTypeMismatch(Type, Type, Type, Type),
UnionTypeDuplicateField,
- Unimplemented,
+ // Unimplemented,
}
impl TypeError {
diff --git a/dhall/src/phase/binary.rs b/dhall/src/phase/binary.rs
index 1812131..5e7eb40 100644
--- a/dhall/src/phase/binary.rs
+++ b/dhall/src/phase/binary.rs
@@ -48,10 +48,21 @@ fn cbor_value_to_dhall(
Bool(b) => BoolLit(*b),
Array(vec) => match vec.as_slice() {
[String(l), U64(n)] => {
+ if l.as_str() == "_" {
+ Err(DecodeError::WrongFormatError(
+ "`_` variable was encoded incorrectly".to_owned(),
+ ))?
+ }
let l = Label::from(l.as_str());
Var(V(l, *n as usize))
}
[U64(0), f, args..] => {
+ if args.is_empty() {
+ Err(DecodeError::WrongFormatError(
+ "Function application must have at least one argument"
+ .to_owned(),
+ ))?
+ }
let mut f = cbor_value_to_dhall(&f)?;
for a in args {
let a = cbor_value_to_dhall(&a)?;
@@ -65,6 +76,11 @@ fn cbor_value_to_dhall(
Lam(Label::from("_"), x, y)
}
[U64(1), String(l), x, y] => {
+ if l.as_str() == "_" {
+ Err(DecodeError::WrongFormatError(
+ "`_` variable was encoded incorrectly".to_owned(),
+ ))?
+ }
let x = cbor_value_to_dhall(&x)?;
let y = cbor_value_to_dhall(&y)?;
let l = Label::from(l.as_str());
@@ -76,6 +92,11 @@ fn cbor_value_to_dhall(
Pi(Label::from("_"), x, y)
}
[U64(2), String(l), x, y] => {
+ if l.as_str() == "_" {
+ Err(DecodeError::WrongFormatError(
+ "`_` variable was encoded incorrectly".to_owned(),
+ ))?
+ }
let x = cbor_value_to_dhall(&x)?;
let y = cbor_value_to_dhall(&y)?;
let l = Label::from(l.as_str());
@@ -106,7 +127,7 @@ fn cbor_value_to_dhall(
}
[U64(4), t] => {
let t = cbor_value_to_dhall(&t)?;
- EmptyListLit(t)
+ EmptyListLit(rc(App(rc(ExprF::Builtin(Builtin::List)), t)))
}
[U64(4), Null, rest..] => {
let rest = rest
@@ -115,18 +136,22 @@ fn cbor_value_to_dhall(
.collect::<Result<Vec<_>, _>>()?;
NEListLit(rest)
}
- [U64(5), t] => {
- let t = cbor_value_to_dhall(&t)?;
- OldOptionalLit(None, t)
- }
[U64(5), Null, x] => {
let x = cbor_value_to_dhall(&x)?;
SomeLit(x)
}
+ // Old-style optional literals
+ [U64(5), t] => {
+ let t = cbor_value_to_dhall(&t)?;
+ App(rc(ExprF::Builtin(Builtin::OptionalNone)), t)
+ }
[U64(5), t, x] => {
let x = cbor_value_to_dhall(&x)?;
let t = cbor_value_to_dhall(&t)?;
- OldOptionalLit(Some(x), t)
+ Annot(
+ rc(SomeLit(x)),
+ rc(App(rc(ExprF::Builtin(Builtin::Optional)), t)),
+ )
}
[U64(6), x, y] => {
let x = cbor_value_to_dhall(&x)?;
@@ -156,12 +181,9 @@ fn cbor_value_to_dhall(
let map = cbor_map_to_dhall_opt_map(map)?;
UnionType(map)
}
- [U64(12), String(l), x, Object(map)] => {
- let map = cbor_map_to_dhall_opt_map(map)?;
- let x = cbor_value_to_dhall(&x)?;
- let l = Label::from(l.as_str());
- UnionLit(l, x, map)
- }
+ [U64(12), ..] => Err(DecodeError::WrongFormatError(
+ "Union literals are not supported anymore".to_owned(),
+ ))?,
[U64(14), x, y, z] => {
let x = cbor_value_to_dhall(&x)?;
let y = cbor_value_to_dhall(&y)?;
@@ -191,8 +213,13 @@ fn cbor_value_to_dhall(
}
[U64(24), hash, U64(mode), U64(scheme), rest..] => {
let mode = match mode {
+ 0 => ImportMode::Code,
1 => ImportMode::RawText,
- _ => ImportMode::Code,
+ 2 => ImportMode::Location,
+ _ => Err(DecodeError::WrongFormatError(format!(
+ "import/mode/unknown_mode: {:?}",
+ mode
+ )))?,
};
let hash = match hash {
Null => None,
@@ -216,18 +243,20 @@ fn cbor_value_to_dhall(
};
let headers = match rest.next() {
Some(Null) => None,
- Some(x) => {
- match cbor_value_to_dhall(&x)?.as_ref() {
- Embed(import) => Some(Box::new(
- import.location_hashed.clone(),
- )),
- _ => Err(DecodeError::WrongFormatError(
- "import/remote/headers".to_owned(),
- ))?,
- }
- }
+ // TODO
+ // Some(x) => {
+ // match cbor_value_to_dhall(&x)?.as_ref() {
+ // Embed(import) => Some(Box::new(
+ // import.location_hashed.clone(),
+ // )),
+ // _ => Err(DecodeError::WrongFormatError(
+ // "import/remote/headers".to_owned(),
+ // ))?,
+ // }
+ // }
_ => Err(DecodeError::WrongFormatError(
- "import/remote/headers".to_owned(),
+ "import/remote/headers is unimplemented"
+ .to_owned(),
))?,
};
let authority = match rest.next() {
@@ -330,6 +359,10 @@ fn cbor_value_to_dhall(
let y = cbor_value_to_dhall(&y)?;
Annot(x, y)
}
+ [U64(28), x] => {
+ let x = cbor_value_to_dhall(&x)?;
+ EmptyListLit(x)
+ }
_ => Err(DecodeError::WrongFormatError(format!("{:?}", data)))?,
},
_ => Err(DecodeError::WrongFormatError(format!("{:?}", data)))?,
@@ -378,7 +411,6 @@ enum Serialize<'a> {
CBOR(cbor::Value),
RecordMap(&'a DupTreeMap<Label, ParsedSubExpr>),
UnionMap(&'a DupTreeMap<Label, Option<ParsedSubExpr>>),
- Import(&'a Import),
}
macro_rules! count {
@@ -403,6 +435,7 @@ where
S: serde::ser::Serializer,
{
use cbor::Value::{String, I64, U64};
+ use dhall_syntax::Builtin;
use dhall_syntax::ExprF::*;
use std::iter::once;
@@ -444,12 +477,23 @@ where
ser_seq!(ser; tag(2), expr(x), expr(y))
}
Pi(l, x, y) => ser_seq!(ser; tag(2), label(l), expr(x), expr(y)),
- // TODO: multilet
- Let(l, None, x, y) => {
- ser_seq!(ser; tag(25), label(l), null(), expr(x), expr(y))
- }
- Let(l, Some(t), x, y) => {
- ser_seq!(ser; tag(25), label(l), expr(t), expr(x), expr(y))
+ Let(_, _, _, _) => {
+ let (bound_e, bindings) = collect_nested_lets(e);
+ let count = 1 + 3 * bindings.len() + 1;
+
+ use serde::ser::SerializeSeq;
+ let mut ser_seq = ser.serialize_seq(Some(count))?;
+ ser_seq.serialize_element(&tag(25))?;
+ for (l, t, v) in bindings {
+ ser_seq.serialize_element(&label(l))?;
+ match t {
+ Some(t) => ser_seq.serialize_element(&expr(t))?,
+ None => ser_seq.serialize_element(&null())?,
+ }
+ ser_seq.serialize_element(&expr(v))?;
+ }
+ ser_seq.serialize_element(&expr(bound_e))?;
+ ser_seq.end()
}
App(_, _) => {
let (f, args) = collect_nested_applications(e);
@@ -460,10 +504,14 @@ where
)
}
Annot(x, y) => ser_seq!(ser; tag(26), expr(x), expr(y)),
- OldOptionalLit(None, t) => ser_seq!(ser; tag(5), expr(t)),
- OldOptionalLit(Some(x), t) => ser_seq!(ser; tag(5), expr(t), expr(x)),
SomeLit(x) => ser_seq!(ser; tag(5), null(), expr(x)),
- EmptyListLit(x) => ser_seq!(ser; tag(4), expr(x)),
+ EmptyListLit(x) => match x.as_ref() {
+ App(f, a) => match f.as_ref() {
+ ExprF::Builtin(Builtin::List) => ser_seq!(ser; tag(4), expr(a)),
+ _ => ser_seq!(ser; tag(28), expr(x)),
+ },
+ _ => ser_seq!(ser; tag(28), expr(x)),
+ },
NEListLit(xs) => ser.collect_seq(
once(tag(4)).chain(once(null())).chain(xs.iter().map(expr)),
),
@@ -477,9 +525,6 @@ where
RecordType(map) => ser_seq!(ser; tag(7), RecordMap(map)),
RecordLit(map) => ser_seq!(ser; tag(8), RecordMap(map)),
UnionType(map) => ser_seq!(ser; tag(11), UnionMap(map)),
- UnionLit(l, x, map) => {
- ser_seq!(ser; tag(12), label(l), expr(x), UnionMap(map))
- }
Field(x, l) => ser_seq!(ser; tag(9), expr(x), label(l)),
BinOp(op, x, y) => {
use dhall_syntax::BinOp::*;
@@ -542,6 +587,7 @@ where
let mode = match import.mode {
ImportMode::Code => 0,
ImportMode::RawText => 1,
+ ImportMode::Location => 2,
};
ser_seq.serialize_element(&U64(mode))?;
@@ -565,12 +611,14 @@ where
ImportLocation::Remote(url) => {
match &url.headers {
None => ser_seq.serialize_element(&Null)?,
- Some(location_hashed) => ser_seq.serialize_element(
- &self::Serialize::Import(&Import {
- mode: ImportMode::Code,
- location_hashed: location_hashed.as_ref().clone(),
- }),
- )?,
+ Some(location_hashed) => {
+ ser_seq.serialize_element(&self::Serialize::Expr(
+ &SubExpr::from_expr_no_note(ExprF::Embed(Import {
+ mode: ImportMode::Code,
+ location_hashed: location_hashed.as_ref().clone(),
+ })),
+ ))?
+ }
};
ser_seq.serialize_element(&url.authority)?;
for p in &url.path {
@@ -617,7 +665,6 @@ impl<'a> serde::ser::Serialize for Serialize<'a> {
(cbor::Value::String(k.into()), v)
}))
}
- Serialize::Import(import) => serialize_import(ser, import),
}
}
}
@@ -641,3 +688,26 @@ fn collect_nested_applications<'a, N, E>(
let e = go(e, &mut vec);
(e, vec)
}
+
+type LetBinding<'a, N, E> =
+ (&'a Label, &'a Option<SubExpr<N, E>>, &'a SubExpr<N, E>);
+
+fn collect_nested_lets<'a, N, E>(
+ e: &'a SubExpr<N, E>,
+) -> (&'a SubExpr<N, E>, Vec<LetBinding<'a, N, E>>) {
+ fn go<'a, N, E>(
+ e: &'a SubExpr<N, E>,
+ vec: &mut Vec<LetBinding<'a, N, E>>,
+ ) -> &'a SubExpr<N, E> {
+ match e.as_ref() {
+ ExprF::Let(l, t, v, e) => {
+ vec.push((l, t, v));
+ go(e, vec)
+ }
+ _ => e,
+ }
+ }
+ let mut vec = vec![];
+ let e = go(e, &mut vec);
+ (e, vec)
+}
diff --git a/dhall/src/phase/normalize.rs b/dhall/src/phase/normalize.rs
index 35d32cb..395cf28 100644
--- a/dhall/src/phase/normalize.rs
+++ b/dhall/src/phase/normalize.rs
@@ -47,6 +47,16 @@ pub fn apply_builtin(b: Builtin, args: Vec<Thunk>) -> Value {
)),
_ => Err(()),
},
+ (NaturalSubtract, [a, b, r..]) => {
+ match (&*a.as_value(), &*b.as_value()) {
+ (NaturalLit(a), NaturalLit(b)) => {
+ Ok((r, NaturalLit(if b > a { b - a } else { 0 })))
+ }
+ (NaturalLit(0), b) => Ok((r, b.clone())),
+ (_, NaturalLit(0)) => Ok((r, NaturalLit(0))),
+ _ => Err(()),
+ }
+ }
(IntegerShow, [n, r..]) => match &*n.as_value() {
IntegerLit(n) => {
let s = if *n < 0 {
@@ -72,6 +82,17 @@ pub fn apply_builtin(b: Builtin, args: Vec<Thunk>) -> Value {
(TextShow, [v, r..]) => match &*v.as_value() {
TextLit(elts) => {
match elts.as_slice() {
+ // Empty string literal.
+ [] => {
+ // Printing InterpolatedText takes care of all the escaping
+ let txt: InterpolatedText<X> =
+ std::iter::empty().collect();
+ let s = txt.to_string();
+ Ok((
+ r,
+ TextLit(vec![InterpolatedTextContents::Text(s)]),
+ ))
+ }
// If there are no interpolations (invariants ensure that when there are no
// interpolations, there is a single Text item) in the literal.
[InterpolatedTextContents::Text(s)] => {
@@ -611,7 +632,7 @@ fn apply_binop<'a>(o: BinOp, x: &'a Thunk, y: &'a Thunk) -> Option<Ret<'a>> {
pub fn normalize_one_layer(expr: ExprF<Thunk, X>) -> Value {
use Value::{
- BoolLit, DoubleLit, EmptyListLit, EmptyOptionalLit, IntegerLit, Lam,
+ AppliedBuiltin, BoolLit, DoubleLit, EmptyListLit, IntegerLit, Lam,
NEListLit, NEOptionalLit, NaturalLit, Pi, RecordLit, RecordType,
TextLit, UnionConstructor, UnionLit, UnionType,
};
@@ -639,13 +660,21 @@ pub fn normalize_one_layer(expr: ExprF<Thunk, X>) -> Value {
ExprF::NaturalLit(n) => Ret::Value(NaturalLit(n)),
ExprF::IntegerLit(n) => Ret::Value(IntegerLit(n)),
ExprF::DoubleLit(n) => Ret::Value(DoubleLit(n)),
- ExprF::OldOptionalLit(None, t) => {
- Ret::Value(EmptyOptionalLit(TypeThunk::from_thunk(t)))
- }
- ExprF::OldOptionalLit(Some(e), _) => Ret::Value(NEOptionalLit(e)),
ExprF::SomeLit(e) => Ret::Value(NEOptionalLit(e)),
- ExprF::EmptyListLit(t) => {
- Ret::Value(EmptyListLit(TypeThunk::from_thunk(t)))
+ ExprF::EmptyListLit(ref t) => {
+ // Check if the type is of the form `List x`
+ let t_borrow = t.as_value();
+ match &*t_borrow {
+ AppliedBuiltin(Builtin::List, args) if args.len() == 1 => {
+ Ret::Value(EmptyListLit(TypeThunk::from_thunk(
+ args[0].clone(),
+ )))
+ }
+ _ => {
+ drop(t_borrow);
+ Ret::Expr(expr)
+ }
+ }
}
ExprF::NEListLit(elts) => {
Ret::Value(NEListLit(elts.into_iter().collect()))
@@ -658,13 +687,6 @@ pub fn normalize_one_layer(expr: ExprF<Thunk, X>) -> Value {
.map(|(k, t)| (k, TypeThunk::from_thunk(t)))
.collect(),
)),
- ExprF::UnionLit(l, x, kts) => Ret::Value(UnionLit(
- l,
- x,
- kts.into_iter()
- .map(|(k, t)| (k, t.map(|t| TypeThunk::from_thunk(t))))
- .collect(),
- )),
ExprF::UnionType(kts) => Ret::Value(UnionType(
kts.into_iter()
.map(|(k, t)| (k, t.map(|t| TypeThunk::from_thunk(t))))
diff --git a/dhall/src/phase/resolve.rs b/dhall/src/phase/resolve.rs
index c4d7e5f..abcee7e 100644
--- a/dhall/src/phase/resolve.rs
+++ b/dhall/src/phase/resolve.rs
@@ -86,7 +86,7 @@ fn do_resolve_expr(
}
}
};
- let expr = expr.traverse_embed(resolve)?;
+ let expr = expr.traverse_resolve(resolve)?;
Ok(Resolved(expr))
}
@@ -100,7 +100,7 @@ pub fn skip_resolve_expr(
let resolve = |import: &Import| -> Result<Normalized, ImportError> {
Err(ImportError::UnexpectedImport(import.clone()))
};
- let expr = expr.traverse_embed(resolve)?;
+ let expr = expr.traverse_resolve(resolve)?;
Ok(Resolved(expr))
}
@@ -110,24 +110,35 @@ mod spec_tests {
macro_rules! import_success {
($name:ident, $path:expr) => {
- make_spec_test!(Import, Success, $name, &("success/".to_owned() + $path));
+ make_spec_test!(Import, Success, $name, &("../dhall-lang/tests/import/success/".to_owned() + $path));
};
}
// macro_rules! import_failure {
// ($name:ident, $path:expr) => {
- // make_spec_test!(Import, Failure, $name, &("failure/".to_owned() + $path));
+ // make_spec_test!(Import, Failure, $name, &("../dhall-lang/tests/import/failure/".to_owned() + $path));
// };
// }
// import_success!(success_alternativeEnvNatural, "alternativeEnvNatural");
// import_success!(success_alternativeEnvSimple, "alternativeEnvSimple");
+ // import_success!(success_alternativeHashMismatch, "alternativeHashMismatch");
// import_success!(success_alternativeNatural, "alternativeNatural");
+ // import_success!(success_alternativeParseError, "alternativeParseError");
+ // import_success!(success_alternativeTypeError, "alternativeTypeError");
+ // import_success!(success_asLocation, "asLocation");
// import_success!(success_asText, "asText");
+ // import_success!(success_customHeaders, "customHeaders");
import_success!(success_fieldOrder, "fieldOrder");
+ // note: this one needs special setup with env variables
+ // import_success!(success_hashFromCache, "hashFromCache");
+ // import_success!(success_headerForwarding, "headerForwarding");
+ // import_success!(success_nestedHash, "nestedHash");
+ // import_success!(success_noHeaderForwarding, "noHeaderForwarding");
// import_failure!(failure_alternativeEnv, "alternativeEnv");
// import_failure!(failure_alternativeEnvMissing, "alternativeEnvMissing");
// import_failure!(failure_cycle, "cycle");
+ // import_failure!(failure_hashMismatch, "hashMismatch");
// import_failure!(failure_missing, "missing");
// import_failure!(failure_referentiallyInsane, "referentiallyInsane");
}
diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs
index a3f676c..2e4642c 100644
--- a/dhall/src/phase/typecheck.rs
+++ b/dhall/src/phase/typecheck.rs
@@ -164,37 +164,6 @@ fn tck_union_type(
))
}
-fn tck_list_type(ctx: &TypecheckContext, t: Type) -> Result<Typed, TypeError> {
- use crate::error::TypeMessage::*;
- ensure_simple_type!(
- t,
- TypeError::new(ctx, InvalidListType(t.to_normalized())),
- );
- Ok(Typed::from_thunk_and_type(
- Value::from_builtin(Builtin::List)
- .app(t.to_value())
- .into_thunk(),
- Type::from_const(Const::Type),
- ))
-}
-
-fn tck_optional_type(
- ctx: &TypecheckContext,
- t: Type,
-) -> Result<Typed, TypeError> {
- use crate::error::TypeMessage::*;
- ensure_simple_type!(
- t,
- TypeError::new(ctx, InvalidOptionalType(t.to_normalized())),
- );
- Ok(Typed::from_thunk_and_type(
- Value::from_builtin(Builtin::Optional)
- .app(t.to_value())
- .into_thunk(),
- Type::from_const(Const::Type),
- ))
-}
-
fn function_check(a: Const, b: Const) -> Result<Const, ()> {
use dhall_syntax::Const::*;
match (a, b) {
@@ -243,6 +212,7 @@ fn type_of_builtin(b: Builtin) -> Expr<X, X> {
),
NaturalToInteger => dhall::expr!(Natural -> Integer),
NaturalShow => dhall::expr!(Natural -> Text),
+ NaturalSubtract => dhall::expr!(Natural -> Natural -> Natural),
IntegerToDouble => dhall::expr!(Integer -> Double),
IntegerShow => dhall::expr!(Integer -> Text),
@@ -329,9 +299,7 @@ fn type_with(
ctx: &TypecheckContext,
e: SubExpr<Span, Normalized>,
) -> Result<Typed, TypeError> {
- use dhall_syntax::ExprF::{
- Annot, App, Embed, Lam, Let, OldOptionalLit, Pi, SomeLit, Var,
- };
+ use dhall_syntax::ExprF::{Annot, Embed, Lam, Let, Pi, Var};
use Ret::*;
Ok(match e.as_ref() {
@@ -364,18 +332,6 @@ fn type_with(
let v = type_with(ctx, v)?;
return type_with(&ctx.insert_value(x, v.clone())?, e.clone());
}
- OldOptionalLit(None, t) => {
- let none = SubExpr::from_builtin(Builtin::OptionalNone);
- let e = e.rewrap(App(none, t.clone()));
- return type_with(ctx, e);
- }
- OldOptionalLit(Some(x), t) => {
- let optional = SubExpr::from_builtin(Builtin::Optional);
- let x = x.rewrap(SomeLit(x.clone()));
- let t = t.rewrap(App(optional, t.clone()));
- let e = e.rewrap(Annot(x, t));
- return type_with(ctx, e);
- }
Embed(p) => p.clone().into_typed(),
Var(var) => match ctx.lookup(&var) {
Some(typed) => typed,
@@ -423,12 +379,9 @@ fn type_last_layer(
let mkerr = |msg: TypeMessage| TypeError::new(ctx, msg);
match e {
- Lam(_, _, _)
- | Pi(_, _, _)
- | Let(_, _, _, _)
- | OldOptionalLit(_, _)
- | Embed(_)
- | Var(_) => unreachable!(),
+ Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
+ unreachable!()
+ }
App(f, a) => {
let tf = f.get_type()?;
let (x, tx, tb) = match &tf.to_value() {
@@ -477,7 +430,17 @@ fn type_last_layer(
}
EmptyListLit(t) => {
let t = t.to_type();
- Ok(RetTypeOnly(tck_list_type(ctx, t)?.to_type()))
+ match &t.to_value() {
+ Value::AppliedBuiltin(dhall_syntax::Builtin::List, args)
+ if args.len() == 1 => {}
+ _ => {
+ return Err(TypeError::new(
+ ctx,
+ InvalidListType(t.to_normalized()),
+ ))
+ }
+ }
+ Ok(RetTypeOnly(t))
}
NEListLit(xs) => {
let mut iter = xs.iter().enumerate();
@@ -493,12 +456,38 @@ fn type_last_layer(
))
);
}
- let t = x.get_type()?.into_owned();
- Ok(RetTypeOnly(tck_list_type(ctx, t)?.to_type()))
+ let t = x.get_type()?;
+ ensure_simple_type!(
+ t,
+ TypeError::new(ctx, InvalidListType(t.to_normalized())),
+ );
+
+ Ok(RetTypeOnly(
+ Typed::from_thunk_and_type(
+ Value::from_builtin(dhall_syntax::Builtin::List)
+ .app(t.to_value())
+ .into_thunk(),
+ Type::from_const(dhall_syntax::Const::Type),
+ )
+ .to_type(),
+ ))
}
SomeLit(x) => {
let t = x.get_type()?.into_owned();
- Ok(RetTypeOnly(tck_optional_type(ctx, t)?.to_type()))
+ ensure_simple_type!(
+ t,
+ TypeError::new(ctx, InvalidOptionalType(t.to_normalized())),
+ );
+
+ Ok(RetTypeOnly(
+ Typed::from_thunk_and_type(
+ Value::from_builtin(dhall_syntax::Builtin::Optional)
+ .app(t.to_value())
+ .into_thunk(),
+ Type::from_const(dhall_syntax::Const::Type),
+ )
+ .to_type(),
+ ))
}
RecordType(kts) => Ok(RetWhole(tck_record_type(
ctx,
@@ -517,15 +506,6 @@ fn type_last_layer(
)?
.into_type(),
)),
- UnionLit(x, v, kvs) => {
- use std::iter::once;
- let kts = kvs
- .iter()
- .map(|(x, v)| Ok((x.clone(), v.as_ref().map(|v| v.to_type()))));
- let t = v.get_type()?.into_owned();
- let kts = kts.chain(once(Ok((x.clone(), Some(t)))));
- Ok(RetTypeOnly(tck_union_type(ctx, kts)?.to_type()))
- }
Field(r, x) => {
match &r.get_type()?.to_value() {
Value::RecordType(kts) => match kts.get(&x) {
@@ -840,7 +820,7 @@ fn type_last_layer(
RightBiasedRecordMerge => unreachable!(),
RecursiveRecordMerge => unreachable!(),
RecursiveRecordTypeMerge => unreachable!(),
- _ => return Err(mkerr(Unimplemented)),
+ ImportAlt => unreachable!("There should remain no import alternatives in a resolved expression"),
})?;
ensure_equal!(
@@ -985,394 +965,3 @@ pub fn typecheck_with(e: Resolved, ty: &Type) -> Result<Typed, TypeError> {
pub fn skip_typecheck(e: Resolved) -> Typed {
Typed::from_thunk_untyped(Thunk::new(NormalizationContext::new(), e.0))
}
-
-#[cfg(test)]
-mod spec_tests {
- #![rustfmt::skip]
-
- macro_rules! tc_success {
- ($name:ident, $path:expr) => {
- make_spec_test!(Typecheck, Success, $name, &("success/".to_owned() + $path));
- };
- }
- macro_rules! tc_failure {
- ($name:ident, $path:expr) => {
- make_spec_test!(Typecheck, Failure, $name, &("failure/".to_owned() + $path));
- };
- }
-
- macro_rules! ti_success {
- ($name:ident, $path:expr) => {
- make_spec_test!(TypeInference, Success, $name, &("success/".to_owned() + $path));
- };
- }
- // macro_rules! ti_failure {
- // ($name:ident, $path:expr) => {
- // make_spec_test!(TypeInference, Failure, $name, &("failure/".to_owned() + $path));
- // };
- // }
-
- // tc_success!(tc_success_accessEncodedType, "accessEncodedType");
- // tc_success!(tc_success_accessType, "accessType");
- tc_success!(tc_success_prelude_Bool_and_0, "prelude/Bool/and/0");
- tc_success!(tc_success_prelude_Bool_and_1, "prelude/Bool/and/1");
- tc_success!(tc_success_prelude_Bool_build_0, "prelude/Bool/build/0");
- tc_success!(tc_success_prelude_Bool_build_1, "prelude/Bool/build/1");
- tc_success!(tc_success_prelude_Bool_even_0, "prelude/Bool/even/0");
- tc_success!(tc_success_prelude_Bool_even_1, "prelude/Bool/even/1");
- tc_success!(tc_success_prelude_Bool_even_2, "prelude/Bool/even/2");
- tc_success!(tc_success_prelude_Bool_even_3, "prelude/Bool/even/3");
- tc_success!(tc_success_prelude_Bool_fold_0, "prelude/Bool/fold/0");
- tc_success!(tc_success_prelude_Bool_fold_1, "prelude/Bool/fold/1");
- tc_success!(tc_success_prelude_Bool_not_0, "prelude/Bool/not/0");
- tc_success!(tc_success_prelude_Bool_not_1, "prelude/Bool/not/1");
- tc_success!(tc_success_prelude_Bool_odd_0, "prelude/Bool/odd/0");
- tc_success!(tc_success_prelude_Bool_odd_1, "prelude/Bool/odd/1");
- tc_success!(tc_success_prelude_Bool_odd_2, "prelude/Bool/odd/2");
- tc_success!(tc_success_prelude_Bool_odd_3, "prelude/Bool/odd/3");
- tc_success!(tc_success_prelude_Bool_or_0, "prelude/Bool/or/0");
- tc_success!(tc_success_prelude_Bool_or_1, "prelude/Bool/or/1");
- tc_success!(tc_success_prelude_Bool_show_0, "prelude/Bool/show/0");
- tc_success!(tc_success_prelude_Bool_show_1, "prelude/Bool/show/1");
- tc_success!(tc_success_prelude_Double_show_0, "prelude/Double/show/0");
- tc_success!(tc_success_prelude_Double_show_1, "prelude/Double/show/1");
- tc_success!(tc_success_prelude_Integer_show_0, "prelude/Integer/show/0");
- tc_success!(tc_success_prelude_Integer_show_1, "prelude/Integer/show/1");
- tc_success!(tc_success_prelude_Integer_toDouble_0, "prelude/Integer/toDouble/0");
- tc_success!(tc_success_prelude_Integer_toDouble_1, "prelude/Integer/toDouble/1");
- tc_success!(tc_success_prelude_List_all_0, "prelude/List/all/0");
- tc_success!(tc_success_prelude_List_all_1, "prelude/List/all/1");
- tc_success!(tc_success_prelude_List_any_0, "prelude/List/any/0");
- tc_success!(tc_success_prelude_List_any_1, "prelude/List/any/1");
- tc_success!(tc_success_prelude_List_build_0, "prelude/List/build/0");
- tc_success!(tc_success_prelude_List_build_1, "prelude/List/build/1");
- tc_success!(tc_success_prelude_List_concat_0, "prelude/List/concat/0");
- tc_success!(tc_success_prelude_List_concat_1, "prelude/List/concat/1");
- tc_success!(tc_success_prelude_List_concatMap_0, "prelude/List/concatMap/0");
- tc_success!(tc_success_prelude_List_concatMap_1, "prelude/List/concatMap/1");
- tc_success!(tc_success_prelude_List_filter_0, "prelude/List/filter/0");
- tc_success!(tc_success_prelude_List_filter_1, "prelude/List/filter/1");
- tc_success!(tc_success_prelude_List_fold_0, "prelude/List/fold/0");
- tc_success!(tc_success_prelude_List_fold_1, "prelude/List/fold/1");
- tc_success!(tc_success_prelude_List_fold_2, "prelude/List/fold/2");
- tc_success!(tc_success_prelude_List_generate_0, "prelude/List/generate/0");
- tc_success!(tc_success_prelude_List_generate_1, "prelude/List/generate/1");
- tc_success!(tc_success_prelude_List_head_0, "prelude/List/head/0");
- tc_success!(tc_success_prelude_List_head_1, "prelude/List/head/1");
- tc_success!(tc_success_prelude_List_indexed_0, "prelude/List/indexed/0");
- tc_success!(tc_success_prelude_List_indexed_1, "prelude/List/indexed/1");
- tc_success!(tc_success_prelude_List_iterate_0, "prelude/List/iterate/0");
- tc_success!(tc_success_prelude_List_iterate_1, "prelude/List/iterate/1");
- tc_success!(tc_success_prelude_List_last_0, "prelude/List/last/0");
- tc_success!(tc_success_prelude_List_last_1, "prelude/List/last/1");
- tc_success!(tc_success_prelude_List_length_0, "prelude/List/length/0");
- tc_success!(tc_success_prelude_List_length_1, "prelude/List/length/1");
- tc_success!(tc_success_prelude_List_map_0, "prelude/List/map/0");
- tc_success!(tc_success_prelude_List_map_1, "prelude/List/map/1");
- tc_success!(tc_success_prelude_List_null_0, "prelude/List/null/0");
- tc_success!(tc_success_prelude_List_null_1, "prelude/List/null/1");
- tc_success!(tc_success_prelude_List_replicate_0, "prelude/List/replicate/0");
- tc_success!(tc_success_prelude_List_replicate_1, "prelude/List/replicate/1");
- tc_success!(tc_success_prelude_List_reverse_0, "prelude/List/reverse/0");
- tc_success!(tc_success_prelude_List_reverse_1, "prelude/List/reverse/1");
- tc_success!(tc_success_prelude_List_shifted_0, "prelude/List/shifted/0");
- tc_success!(tc_success_prelude_List_shifted_1, "prelude/List/shifted/1");
- tc_success!(tc_success_prelude_List_unzip_0, "prelude/List/unzip/0");
- tc_success!(tc_success_prelude_List_unzip_1, "prelude/List/unzip/1");
- tc_success!(tc_success_prelude_Monoid_00, "prelude/Monoid/00");
- tc_success!(tc_success_prelude_Monoid_01, "prelude/Monoid/01");
- tc_success!(tc_success_prelude_Monoid_02, "prelude/Monoid/02");
- tc_success!(tc_success_prelude_Monoid_03, "prelude/Monoid/03");
- tc_success!(tc_success_prelude_Monoid_04, "prelude/Monoid/04");
- tc_success!(tc_success_prelude_Monoid_05, "prelude/Monoid/05");
- tc_success!(tc_success_prelude_Monoid_06, "prelude/Monoid/06");
- tc_success!(tc_success_prelude_Monoid_07, "prelude/Monoid/07");
- tc_success!(tc_success_prelude_Monoid_08, "prelude/Monoid/08");
- tc_success!(tc_success_prelude_Monoid_09, "prelude/Monoid/09");
- tc_success!(tc_success_prelude_Monoid_10, "prelude/Monoid/10");
- tc_success!(tc_success_prelude_Natural_build_0, "prelude/Natural/build/0");
- tc_success!(tc_success_prelude_Natural_build_1, "prelude/Natural/build/1");
- tc_success!(tc_success_prelude_Natural_enumerate_0, "prelude/Natural/enumerate/0");
- tc_success!(tc_success_prelude_Natural_enumerate_1, "prelude/Natural/enumerate/1");
- tc_success!(tc_success_prelude_Natural_even_0, "prelude/Natural/even/0");
- tc_success!(tc_success_prelude_Natural_even_1, "prelude/Natural/even/1");
- tc_success!(tc_success_prelude_Natural_fold_0, "prelude/Natural/fold/0");
- tc_success!(tc_success_prelude_Natural_fold_1, "prelude/Natural/fold/1");
- tc_success!(tc_success_prelude_Natural_fold_2, "prelude/Natural/fold/2");
- tc_success!(tc_success_prelude_Natural_isZero_0, "prelude/Natural/isZero/0");
- tc_success!(tc_success_prelude_Natural_isZero_1, "prelude/Natural/isZero/1");
- tc_success!(tc_success_prelude_Natural_odd_0, "prelude/Natural/odd/0");
- tc_success!(tc_success_prelude_Natural_odd_1, "prelude/Natural/odd/1");
- tc_success!(tc_success_prelude_Natural_product_0, "prelude/Natural/product/0");
- tc_success!(tc_success_prelude_Natural_product_1, "prelude/Natural/product/1");
- tc_success!(tc_success_prelude_Natural_show_0, "prelude/Natural/show/0");
- tc_success!(tc_success_prelude_Natural_show_1, "prelude/Natural/show/1");
- tc_success!(tc_success_prelude_Natural_sum_0, "prelude/Natural/sum/0");
- tc_success!(tc_success_prelude_Natural_sum_1, "prelude/Natural/sum/1");
- tc_success!(tc_success_prelude_Natural_toDouble_0, "prelude/Natural/toDouble/0");
- tc_success!(tc_success_prelude_Natural_toDouble_1, "prelude/Natural/toDouble/1");
- tc_success!(tc_success_prelude_Natural_toInteger_0, "prelude/Natural/toInteger/0");
- tc_success!(tc_success_prelude_Natural_toInteger_1, "prelude/Natural/toInteger/1");
- tc_success!(tc_success_prelude_Optional_all_0, "prelude/Optional/all/0");
- tc_success!(tc_success_prelude_Optional_all_1, "prelude/Optional/all/1");
- tc_success!(tc_success_prelude_Optional_any_0, "prelude/Optional/any/0");
- tc_success!(tc_success_prelude_Optional_any_1, "prelude/Optional/any/1");
- tc_success!(tc_success_prelude_Optional_build_0, "prelude/Optional/build/0");
- tc_success!(tc_success_prelude_Optional_build_1, "prelude/Optional/build/1");
- tc_success!(tc_success_prelude_Optional_concat_0, "prelude/Optional/concat/0");
- tc_success!(tc_success_prelude_Optional_concat_1, "prelude/Optional/concat/1");
- tc_success!(tc_success_prelude_Optional_concat_2, "prelude/Optional/concat/2");
- tc_success!(tc_success_prelude_Optional_filter_0, "prelude/Optional/filter/0");
- tc_success!(tc_success_prelude_Optional_filter_1, "prelude/Optional/filter/1");
- tc_success!(tc_success_prelude_Optional_fold_0, "prelude/Optional/fold/0");
- tc_success!(tc_success_prelude_Optional_fold_1, "prelude/Optional/fold/1");
- tc_success!(tc_success_prelude_Optional_head_0, "prelude/Optional/head/0");
- tc_success!(tc_success_prelude_Optional_head_1, "prelude/Optional/head/1");
- tc_success!(tc_success_prelude_Optional_head_2, "prelude/Optional/head/2");
- tc_success!(tc_success_prelude_Optional_last_0, "prelude/Optional/last/0");
- tc_success!(tc_success_prelude_Optional_last_1, "prelude/Optional/last/1");
- tc_success!(tc_success_prelude_Optional_last_2, "prelude/Optional/last/2");
- tc_success!(tc_success_prelude_Optional_length_0, "prelude/Optional/length/0");
- tc_success!(tc_success_prelude_Optional_length_1, "prelude/Optional/length/1");
- tc_success!(tc_success_prelude_Optional_map_0, "prelude/Optional/map/0");
- tc_success!(tc_success_prelude_Optional_map_1, "prelude/Optional/map/1");
- tc_success!(tc_success_prelude_Optional_null_0, "prelude/Optional/null/0");
- tc_success!(tc_success_prelude_Optional_null_1, "prelude/Optional/null/1");
- tc_success!(tc_success_prelude_Optional_toList_0, "prelude/Optional/toList/0");
- tc_success!(tc_success_prelude_Optional_toList_1, "prelude/Optional/toList/1");
- tc_success!(tc_success_prelude_Optional_unzip_0, "prelude/Optional/unzip/0");
- tc_success!(tc_success_prelude_Optional_unzip_1, "prelude/Optional/unzip/1");
- tc_success!(tc_success_prelude_Text_concat_0, "prelude/Text/concat/0");
- tc_success!(tc_success_prelude_Text_concat_1, "prelude/Text/concat/1");
- tc_success!(tc_success_prelude_Text_concatMap_0, "prelude/Text/concatMap/0");
- tc_success!(tc_success_prelude_Text_concatMap_1, "prelude/Text/concatMap/1");
- // tc_success!(tc_success_prelude_Text_concatMapSep_0, "prelude/Text/concatMapSep/0");
- // tc_success!(tc_success_prelude_Text_concatMapSep_1, "prelude/Text/concatMapSep/1");
- // tc_success!(tc_success_prelude_Text_concatSep_0, "prelude/Text/concatSep/0");
- // tc_success!(tc_success_prelude_Text_concatSep_1, "prelude/Text/concatSep/1");
- tc_success!(tc_success_recordOfRecordOfTypes, "recordOfRecordOfTypes");
- tc_success!(tc_success_recordOfTypes, "recordOfTypes");
- // tc_success!(tc_success_simple_access_0, "simple/access/0");
- // tc_success!(tc_success_simple_access_1, "simple/access/1");
- // tc_success!(tc_success_simple_anonymousFunctionsInTypes, "simple/anonymousFunctionsInTypes");
- // tc_success!(tc_success_simple_fieldsAreTypes, "simple/fieldsAreTypes");
- // tc_success!(tc_success_simple_kindParameter, "simple/kindParameter");
- tc_success!(tc_success_simple_mergeEquivalence, "simple/mergeEquivalence");
- // tc_success!(tc_success_simple_mixedFieldAccess, "simple/mixedFieldAccess");
- tc_success!(tc_success_simple_unionsOfTypes, "simple/unionsOfTypes");
-
- tc_failure!(tc_failure_combineMixedRecords, "combineMixedRecords");
- tc_failure!(tc_failure_duplicateFields, "duplicateFields");
- tc_failure!(tc_failure_hurkensParadox, "hurkensParadox");
- // tc_failure!(tc_failure_importBoundary, "importBoundary");
- tc_failure!(tc_failure_mixedUnions, "mixedUnions");
- tc_failure!(tc_failure_preferMixedRecords, "preferMixedRecords");
- tc_failure!(tc_failure_unit_FunctionApplicationArgumentNotMatch, "unit/FunctionApplicationArgumentNotMatch");
- tc_failure!(tc_failure_unit_FunctionApplicationIsNotFunction, "unit/FunctionApplicationIsNotFunction");
- tc_failure!(tc_failure_unit_FunctionArgumentTypeNotAType, "unit/FunctionArgumentTypeNotAType");
- tc_failure!(tc_failure_unit_FunctionDependentType, "unit/FunctionDependentType");
- tc_failure!(tc_failure_unit_FunctionDependentType2, "unit/FunctionDependentType2");
- tc_failure!(tc_failure_unit_FunctionTypeArgumentTypeNotAType, "unit/FunctionTypeArgumentTypeNotAType");
- tc_failure!(tc_failure_unit_FunctionTypeKindSort, "unit/FunctionTypeKindSort");
- tc_failure!(tc_failure_unit_FunctionTypeTypeKind, "unit/FunctionTypeTypeKind");
- tc_failure!(tc_failure_unit_FunctionTypeTypeSort, "unit/FunctionTypeTypeSort");
- tc_failure!(tc_failure_unit_IfBranchesNotMatch, "unit/IfBranchesNotMatch");
- tc_failure!(tc_failure_unit_IfBranchesNotType, "unit/IfBranchesNotType");
- tc_failure!(tc_failure_unit_IfNotBool, "unit/IfNotBool");
- tc_failure!(tc_failure_unit_LetWithWrongAnnotation, "unit/LetWithWrongAnnotation");
- tc_failure!(tc_failure_unit_ListLiteralEmptyNotType, "unit/ListLiteralEmptyNotType");
- tc_failure!(tc_failure_unit_ListLiteralNotType, "unit/ListLiteralNotType");
- tc_failure!(tc_failure_unit_ListLiteralTypesNotMatch, "unit/ListLiteralTypesNotMatch");
- tc_failure!(tc_failure_unit_MergeAlternativeHasNoHandler, "unit/MergeAlternativeHasNoHandler");
- tc_failure!(tc_failure_unit_MergeAnnotationNotType, "unit/MergeAnnotationNotType");
- tc_failure!(tc_failure_unit_MergeEmptyWithoutAnnotation, "unit/MergeEmptyWithoutAnnotation");
- tc_failure!(tc_failure_unit_MergeHandlerNotFunction, "unit/MergeHandlerNotFunction");
- tc_failure!(tc_failure_unit_MergeHandlerNotInUnion, "unit/MergeHandlerNotInUnion");
- tc_failure!(tc_failure_unit_MergeHandlerNotMatchAlternativeType, "unit/MergeHandlerNotMatchAlternativeType");
- tc_failure!(tc_failure_unit_MergeHandlersWithDifferentType, "unit/MergeHandlersWithDifferentType");
- tc_failure!(tc_failure_unit_MergeLhsNotRecord, "unit/MergeLhsNotRecord");
- tc_failure!(tc_failure_unit_MergeRhsNotUnion, "unit/MergeRhsNotUnion");
- tc_failure!(tc_failure_unit_MergeWithWrongAnnotation, "unit/MergeWithWrongAnnotation");
- tc_failure!(tc_failure_unit_OperatorAndNotBool, "unit/OperatorAndNotBool");
- tc_failure!(tc_failure_unit_OperatorEqualNotBool, "unit/OperatorEqualNotBool");
- tc_failure!(tc_failure_unit_OperatorListConcatenateLhsNotList, "unit/OperatorListConcatenateLhsNotList");
- tc_failure!(tc_failure_unit_OperatorListConcatenateListsNotMatch, "unit/OperatorListConcatenateListsNotMatch");
- tc_failure!(tc_failure_unit_OperatorListConcatenateNotListsButMatch, "unit/OperatorListConcatenateNotListsButMatch");
- tc_failure!(tc_failure_unit_OperatorListConcatenateRhsNotList, "unit/OperatorListConcatenateRhsNotList");
- tc_failure!(tc_failure_unit_OperatorNotEqualNotBool, "unit/OperatorNotEqualNotBool");
- tc_failure!(tc_failure_unit_OperatorOrNotBool, "unit/OperatorOrNotBool");
- tc_failure!(tc_failure_unit_OperatorPlusNotNatural, "unit/OperatorPlusNotNatural");
- tc_failure!(tc_failure_unit_OperatorTextConcatenateLhsNotText, "unit/OperatorTextConcatenateLhsNotText");
- tc_failure!(tc_failure_unit_OperatorTextConcatenateRhsNotText, "unit/OperatorTextConcatenateRhsNotText");
- tc_failure!(tc_failure_unit_OperatorTimesNotNatural, "unit/OperatorTimesNotNatural");
- tc_failure!(tc_failure_unit_RecordMixedKinds, "unit/RecordMixedKinds");
- tc_failure!(tc_failure_unit_RecordMixedKinds2, "unit/RecordMixedKinds2");
- tc_failure!(tc_failure_unit_RecordMixedKinds3, "unit/RecordMixedKinds3");
- tc_failure!(tc_failure_unit_RecordProjectionEmpty, "unit/RecordProjectionEmpty");
- tc_failure!(tc_failure_unit_RecordProjectionNotPresent, "unit/RecordProjectionNotPresent");
- tc_failure!(tc_failure_unit_RecordProjectionNotRecord, "unit/RecordProjectionNotRecord");
- tc_failure!(tc_failure_unit_RecordSelectionEmpty, "unit/RecordSelectionEmpty");
- tc_failure!(tc_failure_unit_RecordSelectionNotPresent, "unit/RecordSelectionNotPresent");
- tc_failure!(tc_failure_unit_RecordSelectionNotRecord, "unit/RecordSelectionNotRecord");
- tc_failure!(tc_failure_unit_RecordSelectionTypeNotUnionType, "unit/RecordSelectionTypeNotUnionType");
- tc_failure!(tc_failure_unit_RecordTypeMixedKinds, "unit/RecordTypeMixedKinds");
- tc_failure!(tc_failure_unit_RecordTypeMixedKinds2, "unit/RecordTypeMixedKinds2");
- tc_failure!(tc_failure_unit_RecordTypeMixedKinds3, "unit/RecordTypeMixedKinds3");
- tc_failure!(tc_failure_unit_RecordTypeValueMember, "unit/RecordTypeValueMember");
- tc_failure!(tc_failure_unit_RecursiveRecordMergeLhsNotRecord, "unit/RecursiveRecordMergeLhsNotRecord");
- tc_failure!(tc_failure_unit_RecursiveRecordMergeMixedKinds, "unit/RecursiveRecordMergeMixedKinds");
- tc_failure!(tc_failure_unit_RecursiveRecordMergeOverlapping, "unit/RecursiveRecordMergeOverlapping");
- tc_failure!(tc_failure_unit_RecursiveRecordMergeRhsNotRecord, "unit/RecursiveRecordMergeRhsNotRecord");
- tc_failure!(tc_failure_unit_RecursiveRecordTypeMergeLhsNotRecordType, "unit/RecursiveRecordTypeMergeLhsNotRecordType");
- tc_failure!(tc_failure_unit_RecursiveRecordTypeMergeOverlapping, "unit/RecursiveRecordTypeMergeOverlapping");
- tc_failure!(tc_failure_unit_RecursiveRecordTypeMergeRhsNotRecordType, "unit/RecursiveRecordTypeMergeRhsNotRecordType");
- tc_failure!(tc_failure_unit_RightBiasedRecordMergeLhsNotRecord, "unit/RightBiasedRecordMergeLhsNotRecord");
- tc_failure!(tc_failure_unit_RightBiasedRecordMergeMixedKinds, "unit/RightBiasedRecordMergeMixedKinds");
- tc_failure!(tc_failure_unit_RightBiasedRecordMergeMixedKinds2, "unit/RightBiasedRecordMergeMixedKinds2");
- tc_failure!(tc_failure_unit_RightBiasedRecordMergeMixedKinds3, "unit/RightBiasedRecordMergeMixedKinds3");
- tc_failure!(tc_failure_unit_RightBiasedRecordMergeRhsNotRecord, "unit/RightBiasedRecordMergeRhsNotRecord");
- tc_failure!(tc_failure_unit_SomeNotType, "unit/SomeNotType");
- tc_failure!(tc_failure_unit_Sort, "unit/Sort");
- tc_failure!(tc_failure_unit_TextLiteralInterpolateNotText, "unit/TextLiteralInterpolateNotText");
- tc_failure!(tc_failure_unit_TypeAnnotationWrong, "unit/TypeAnnotationWrong");
- tc_failure!(tc_failure_unit_UnionConstructorFieldNotPresent, "unit/UnionConstructorFieldNotPresent");
- tc_failure!(tc_failure_unit_UnionTypeMixedKinds, "unit/UnionTypeMixedKinds");
- tc_failure!(tc_failure_unit_UnionTypeMixedKinds2, "unit/UnionTypeMixedKinds2");
- tc_failure!(tc_failure_unit_UnionTypeMixedKinds3, "unit/UnionTypeMixedKinds3");
- tc_failure!(tc_failure_unit_UnionTypeNotType, "unit/UnionTypeNotType");
- tc_failure!(tc_failure_unit_VariableFree, "unit/VariableFree");
-
- ti_success!(ti_success_simple_alternativesAreTypes, "simple/alternativesAreTypes");
- ti_success!(ti_success_simple_kindParameter, "simple/kindParameter");
- ti_success!(ti_success_unit_Bool, "unit/Bool");
- ti_success!(ti_success_unit_Double, "unit/Double");
- ti_success!(ti_success_unit_DoubleLiteral, "unit/DoubleLiteral");
- ti_success!(ti_success_unit_DoubleShow, "unit/DoubleShow");
- ti_success!(ti_success_unit_False, "unit/False");
- ti_success!(ti_success_unit_Function, "unit/Function");
- ti_success!(ti_success_unit_FunctionApplication, "unit/FunctionApplication");
- ti_success!(ti_success_unit_FunctionNamedArg, "unit/FunctionNamedArg");
- ti_success!(ti_success_unit_FunctionTypeKindKind, "unit/FunctionTypeKindKind");
- ti_success!(ti_success_unit_FunctionTypeKindTerm, "unit/FunctionTypeKindTerm");
- ti_success!(ti_success_unit_FunctionTypeKindType, "unit/FunctionTypeKindType");
- ti_success!(ti_success_unit_FunctionTypeTermTerm, "unit/FunctionTypeTermTerm");
- ti_success!(ti_success_unit_FunctionTypeTypeTerm, "unit/FunctionTypeTypeTerm");
- ti_success!(ti_success_unit_FunctionTypeTypeType, "unit/FunctionTypeTypeType");
- ti_success!(ti_success_unit_FunctionTypeUsingArgument, "unit/FunctionTypeUsingArgument");
- ti_success!(ti_success_unit_If, "unit/If");
- ti_success!(ti_success_unit_IfNormalizeArguments, "unit/IfNormalizeArguments");
- ti_success!(ti_success_unit_Integer, "unit/Integer");
- ti_success!(ti_success_unit_IntegerLiteral, "unit/IntegerLiteral");
- ti_success!(ti_success_unit_IntegerShow, "unit/IntegerShow");
- ti_success!(ti_success_unit_IntegerToDouble, "unit/IntegerToDouble");
- ti_success!(ti_success_unit_Kind, "unit/Kind");
- ti_success!(ti_success_unit_Let, "unit/Let");
- ti_success!(ti_success_unit_LetNestedTypeSynonym, "unit/LetNestedTypeSynonym");
- ti_success!(ti_success_unit_LetTypeSynonym, "unit/LetTypeSynonym");
- ti_success!(ti_success_unit_LetWithAnnotation, "unit/LetWithAnnotation");
- ti_success!(ti_success_unit_List, "unit/List");
- ti_success!(ti_success_unit_ListBuild, "unit/ListBuild");
- ti_success!(ti_success_unit_ListFold, "unit/ListFold");
- ti_success!(ti_success_unit_ListHead, "unit/ListHead");
- ti_success!(ti_success_unit_ListIndexed, "unit/ListIndexed");
- ti_success!(ti_success_unit_ListLast, "unit/ListLast");
- ti_success!(ti_success_unit_ListLength, "unit/ListLength");
- ti_success!(ti_success_unit_ListLiteralEmpty, "unit/ListLiteralEmpty");
- ti_success!(ti_success_unit_ListLiteralNormalizeArguments, "unit/ListLiteralNormalizeArguments");
- ti_success!(ti_success_unit_ListLiteralOne, "unit/ListLiteralOne");
- ti_success!(ti_success_unit_ListReverse, "unit/ListReverse");
- ti_success!(ti_success_unit_MergeEmptyUnion, "unit/MergeEmptyUnion");
- ti_success!(ti_success_unit_MergeOne, "unit/MergeOne");
- ti_success!(ti_success_unit_MergeOneEmpty, "unit/MergeOneEmpty");
- ti_success!(ti_success_unit_MergeOneWithAnnotation, "unit/MergeOneWithAnnotation");
- ti_success!(ti_success_unit_Natural, "unit/Natural");
- ti_success!(ti_success_unit_NaturalBuild, "unit/NaturalBuild");
- ti_success!(ti_success_unit_NaturalEven, "unit/NaturalEven");
- ti_success!(ti_success_unit_NaturalFold, "unit/NaturalFold");
- ti_success!(ti_success_unit_NaturalIsZero, "unit/NaturalIsZero");
- ti_success!(ti_success_unit_NaturalLiteral, "unit/NaturalLiteral");
- ti_success!(ti_success_unit_NaturalOdd, "unit/NaturalOdd");
- ti_success!(ti_success_unit_NaturalShow, "unit/NaturalShow");
- ti_success!(ti_success_unit_NaturalToInteger, "unit/NaturalToInteger");
- ti_success!(ti_success_unit_None, "unit/None");
- ti_success!(ti_success_unit_OldOptionalNone, "unit/OldOptionalNone");
- ti_success!(ti_success_unit_OldOptionalTrue, "unit/OldOptionalTrue");
- ti_success!(ti_success_unit_OperatorAnd, "unit/OperatorAnd");
- ti_success!(ti_success_unit_OperatorAndNormalizeArguments, "unit/OperatorAndNormalizeArguments");
- ti_success!(ti_success_unit_OperatorEqual, "unit/OperatorEqual");
- ti_success!(ti_success_unit_OperatorEqualNormalizeArguments, "unit/OperatorEqualNormalizeArguments");
- ti_success!(ti_success_unit_OperatorListConcatenate, "unit/OperatorListConcatenate");
- ti_success!(ti_success_unit_OperatorListConcatenateNormalizeArguments, "unit/OperatorListConcatenateNormalizeArguments");
- ti_success!(ti_success_unit_OperatorNotEqual, "unit/OperatorNotEqual");
- ti_success!(ti_success_unit_OperatorNotEqualNormalizeArguments, "unit/OperatorNotEqualNormalizeArguments");
- ti_success!(ti_success_unit_OperatorOr, "unit/OperatorOr");
- ti_success!(ti_success_unit_OperatorOrNormalizeArguments, "unit/OperatorOrNormalizeArguments");
- ti_success!(ti_success_unit_OperatorPlus, "unit/OperatorPlus");
- ti_success!(ti_success_unit_OperatorPlusNormalizeArguments, "unit/OperatorPlusNormalizeArguments");
- ti_success!(ti_success_unit_OperatorTextConcatenate, "unit/OperatorTextConcatenate");
- ti_success!(ti_success_unit_OperatorTextConcatenateNormalizeArguments, "unit/OperatorTextConcatenateNormalizeArguments");
- ti_success!(ti_success_unit_OperatorTimes, "unit/OperatorTimes");
- ti_success!(ti_success_unit_OperatorTimesNormalizeArguments, "unit/OperatorTimesNormalizeArguments");
- ti_success!(ti_success_unit_Optional, "unit/Optional");
- ti_success!(ti_success_unit_OptionalBuild, "unit/OptionalBuild");
- ti_success!(ti_success_unit_OptionalFold, "unit/OptionalFold");
- ti_success!(ti_success_unit_RecordEmpty, "unit/RecordEmpty");
- ti_success!(ti_success_unit_RecordNestedKind, "unit/RecordNestedKind");
- ti_success!(ti_success_unit_RecordNestedKindLike, "unit/RecordNestedKindLike");
- ti_success!(ti_success_unit_RecordNestedType, "unit/RecordNestedType");
- ti_success!(ti_success_unit_RecordNestedTypeLike, "unit/RecordNestedTypeLike");
- ti_success!(ti_success_unit_RecordOneKind, "unit/RecordOneKind");
- ti_success!(ti_success_unit_RecordOneType, "unit/RecordOneType");
- ti_success!(ti_success_unit_RecordOneValue, "unit/RecordOneValue");
- ti_success!(ti_success_unit_RecordProjectionEmpty, "unit/RecordProjectionEmpty");
- ti_success!(ti_success_unit_RecordProjectionKind, "unit/RecordProjectionKind");
- ti_success!(ti_success_unit_RecordProjectionType, "unit/RecordProjectionType");
- ti_success!(ti_success_unit_RecordProjectionValue, "unit/RecordProjectionValue");
- ti_success!(ti_success_unit_RecordSelectionKind, "unit/RecordSelectionKind");
- ti_success!(ti_success_unit_RecordSelectionType, "unit/RecordSelectionType");
- ti_success!(ti_success_unit_RecordSelectionValue, "unit/RecordSelectionValue");
- ti_success!(ti_success_unit_RecordType, "unit/RecordType");
- ti_success!(ti_success_unit_RecordTypeEmpty, "unit/RecordTypeEmpty");
- ti_success!(ti_success_unit_RecordTypeKind, "unit/RecordTypeKind");
- ti_success!(ti_success_unit_RecordTypeKindLike, "unit/RecordTypeKindLike");
- ti_success!(ti_success_unit_RecordTypeNestedKind, "unit/RecordTypeNestedKind");
- ti_success!(ti_success_unit_RecordTypeNestedKindLike, "unit/RecordTypeNestedKindLike");
- ti_success!(ti_success_unit_RecordTypeType, "unit/RecordTypeType");
- ti_success!(ti_success_unit_RecursiveRecordMergeLhsEmpty, "unit/RecursiveRecordMergeLhsEmpty");
- ti_success!(ti_success_unit_RecursiveRecordMergeRecursively, "unit/RecursiveRecordMergeRecursively");
- ti_success!(ti_success_unit_RecursiveRecordMergeRecursivelyKinds, "unit/RecursiveRecordMergeRecursivelyKinds");
- ti_success!(ti_success_unit_RecursiveRecordMergeRecursivelyTypes, "unit/RecursiveRecordMergeRecursivelyTypes");
- ti_success!(ti_success_unit_RecursiveRecordMergeRhsEmpty, "unit/RecursiveRecordMergeRhsEmpty");
- ti_success!(ti_success_unit_RecursiveRecordMergeTwo, "unit/RecursiveRecordMergeTwo");
- ti_success!(ti_success_unit_RecursiveRecordMergeTwoKinds, "unit/RecursiveRecordMergeTwoKinds");
- ti_success!(ti_success_unit_RecursiveRecordMergeTwoTypes, "unit/RecursiveRecordMergeTwoTypes");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursively, "unit/RecursiveRecordTypeMergeRecursively");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursivelyKinds, "unit/RecursiveRecordTypeMergeRecursivelyKinds");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursivelyTypes, "unit/RecursiveRecordTypeMergeRecursivelyTypes");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeRhsEmpty, "unit/RecursiveRecordTypeMergeRhsEmpty");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeTwo, "unit/RecursiveRecordTypeMergeTwo");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeTwoKinds, "unit/RecursiveRecordTypeMergeTwoKinds");
- ti_success!(ti_success_unit_RecursiveRecordTypeMergeTwoTypes, "unit/RecursiveRecordTypeMergeTwoTypes");
- ti_success!(ti_success_unit_RightBiasedRecordMergeRhsEmpty, "unit/RightBiasedRecordMergeRhsEmpty");
- ti_success!(ti_success_unit_RightBiasedRecordMergeTwo, "unit/RightBiasedRecordMergeTwo");
- ti_success!(ti_success_unit_RightBiasedRecordMergeTwoDifferent, "unit/RightBiasedRecordMergeTwoDifferent");
- ti_success!(ti_success_unit_RightBiasedRecordMergeTwoKinds, "unit/RightBiasedRecordMergeTwoKinds");
- ti_success!(ti_success_unit_RightBiasedRecordMergeTwoTypes, "unit/RightBiasedRecordMergeTwoTypes");
- ti_success!(ti_success_unit_SomeTrue, "unit/SomeTrue");
- ti_success!(ti_success_unit_Text, "unit/Text");
- ti_success!(ti_success_unit_TextLiteral, "unit/TextLiteral");
- ti_success!(ti_success_unit_TextLiteralNormalizeArguments, "unit/TextLiteralNormalizeArguments");
- ti_success!(ti_success_unit_TextLiteralWithInterpolation, "unit/TextLiteralWithInterpolation");
- ti_success!(ti_success_unit_TextShow, "unit/TextShow");
- ti_success!(ti_success_unit_True, "unit/True");
- ti_success!(ti_success_unit_Type, "unit/Type");
- ti_success!(ti_success_unit_TypeAnnotation, "unit/TypeAnnotation");
- ti_success!(ti_success_unit_TypeAnnotationSort, "unit/TypeAnnotationSort");
- ti_success!(ti_success_unit_UnionConstructorEmptyField, "unit/UnionConstructorEmptyField");
- ti_success!(ti_success_unit_UnionConstructorField, "unit/UnionConstructorField");
- ti_success!(ti_success_unit_UnionLiteralOne, "unit/UnionLiteralOne");
- ti_success!(ti_success_unit_UnionTypeEmpty, "unit/UnionTypeEmpty");
- ti_success!(ti_success_unit_UnionTypeKind, "unit/UnionTypeKind");
- ti_success!(ti_success_unit_UnionTypeOne, "unit/UnionTypeOne");
- ti_success!(ti_success_unit_UnionTypeType, "unit/UnionTypeType");
-}
diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs
index 2f68dac..9784eec 100644
--- a/dhall/src/tests.rs
+++ b/dhall/src/tests.rs
@@ -45,6 +45,7 @@ pub enum Feature {
Parser,
Printer,
BinaryEncoding,
+ BinaryDecoding,
Import,
Normalization,
AlphaNormalization,
@@ -80,20 +81,27 @@ pub fn run_test(
) -> Result<()> {
use self::Feature::*;
use self::Status::*;
- let feature_prefix = match feature {
- Parser => "parser/",
- Printer => "parser/",
- BinaryEncoding => "parser/",
- Import => "import/",
- Normalization => "normalization/",
- AlphaNormalization => "alpha-normalization/",
- Typecheck => "typecheck/",
- TypeInference => "type-inference/",
- };
- let base_path =
- "../dhall-lang/tests/".to_owned() + feature_prefix + base_path;
+ let base_path = base_path.to_owned();
match status {
Success => {
+ match feature {
+ BinaryDecoding => {
+ let expr_file_path = base_path.clone() + "A.dhallb";
+ let expr_file_path = PathBuf::from(&expr_file_path);
+ let mut expr_data = Vec::new();
+ {
+ File::open(&expr_file_path)?
+ .read_to_end(&mut expr_data)?;
+ }
+ let expr = Parsed::parse_binary(&expr_data)?;
+ let expected_file_path = base_path + "B.dhall";
+ let expected = parse_file_str(&expected_file_path)?;
+ assert_eq_pretty!(expr, expected);
+
+ return Ok(());
+ }
+ _ => {}
+ }
let expr_file_path = base_path.clone() + "A.dhall";
let expr = parse_file_str(&expr_file_path)?;
@@ -164,7 +172,9 @@ pub fn run_test(
.normalize();
match feature {
- Parser | Printer | BinaryEncoding => unreachable!(),
+ Parser | Printer | BinaryEncoding | BinaryDecoding => {
+ unreachable!()
+ }
Import => {
let expr = expr.skip_typecheck().normalize();
assert_eq_display!(expr, expected);
@@ -195,10 +205,21 @@ pub fn run_test(
let err = parse_file_str(&file_path).unwrap_err();
match err {
Error::Parse(_) => {}
+ Error::IO(e)
+ if e.kind() == std::io::ErrorKind::InvalidData => {}
e => panic!("Expected parse error, got: {:?}", e),
}
}
Printer | BinaryEncoding => unreachable!(),
+ BinaryDecoding => {
+ let expr_file_path = file_path + "b";
+ let mut expr_data = Vec::new();
+ {
+ File::open(&PathBuf::from(&expr_file_path))?
+ .read_to_end(&mut expr_data)?;
+ }
+ Parsed::parse_binary(&expr_data).unwrap_err();
+ }
Import => {
parse_file_str(&file_path)?.resolve().unwrap_err();
}
diff --git a/dhall_generated_parser/build.rs b/dhall_generated_parser/build.rs
index eab48bf..74210bf 100644
--- a/dhall_generated_parser/build.rs
+++ b/dhall_generated_parser/build.rs
@@ -26,8 +26,11 @@ fn main() -> std::io::Result<()> {
rules.get_mut(&line[2..]).map(|x| x.silent = true);
}
}
+ rules.remove("http");
+ rules.remove("url_path");
rules.remove("simple_label");
rules.remove("nonreserved_label");
+ rules.remove("expression");
let mut file = File::create(pest_path)?;
writeln!(&mut file, "// AUTO-GENERATED FILE. See build.rs.")?;
@@ -41,6 +44,40 @@ fn main() -> std::io::Result<()> {
| !keyword ~ simple_label_first_char ~ simple_label_next_char*
}}"
)?;
+ // TODO: this is a cheat; actually implement inline headers instead
+ writeln!(
+ &mut file,
+ "http = {{
+ http_raw
+ ~ (whsp
+ ~ using
+ ~ whsp1
+ ~ (import_hashed | ^\"(\" ~ whsp ~ import_hashed ~ whsp ~ ^\")\"))?
+ }}"
+ )?;
+ // TODO: hack; we'll need to upstream a change to the grammar
+ writeln!(
+ &mut file,
+ r#"expression = {{
+ lambda ~ whsp ~ ^"(" ~ whsp ~ nonreserved_label ~ whsp ~ ^":" ~ whsp1 ~ expression ~ whsp ~ ^")" ~ whsp ~ arrow ~ whsp ~ expression
+ | if_ ~ whsp1 ~ expression ~ whsp ~ then ~ whsp1 ~ expression ~ whsp ~ else_ ~ whsp1 ~ expression
+ | let_binding+ ~ in_ ~ whsp1 ~ expression
+ | forall ~ whsp ~ ^"(" ~ whsp ~ nonreserved_label ~ whsp ~ ^":" ~ whsp1 ~ expression ~ whsp ~ ^")" ~ whsp ~ arrow ~ whsp ~ expression
+ | operator_expression ~ whsp ~ arrow ~ whsp ~ expression
+ | merge ~ whsp1 ~ import_expression ~ whsp1 ~ import_expression ~ whsp ~ ^":" ~ whsp1 ~ application_expression
+ | empty_list_literal
+ | toMap ~ whsp1 ~ import_expression ~ whsp ~ ^":" ~ whsp1 ~ application_expression
+ | annotated_expression
+ }}"#
+ )?;
+ writeln!(
+ &mut file,
+ r#"empty_list_literal = {{
+ ^"[" ~ whsp ~ ^"]" ~ whsp ~ ^":" ~ whsp1 ~ application_expression
+ }}"#
+ )?;
+ // TODO: this is a cheat; properly support RFC3986 URLs instead
+ writeln!(&mut file, "url_path = _{{ path }}")?;
writeln!(
&mut file,
"nonreserved_label = _{{
diff --git a/dhall_generated_parser/src/dhall.pest.visibility b/dhall_generated_parser/src/dhall.pest.visibility
index 60de54d..de6dc8d 100644
--- a/dhall_generated_parser/src/dhall.pest.visibility
+++ b/dhall_generated_parser/src/dhall.pest.visibility
@@ -1,4 +1,5 @@
# end_of_line
+# valid_non_ascii
# tab
# block_comment
# block_comment_char
@@ -10,6 +11,7 @@
# whsp1
# ALPHA
# DIGIT
+# ALPHANUM
# HEXDIG
# simple_label_first_char
# simple_label_next_char
@@ -21,6 +23,7 @@ label
# any_label
double_quote_chunk
double_quote_escaped
+# unicode_escape
double_quote_char
double_quote_literal
single_quote_continue
@@ -42,11 +45,13 @@ missing
# Infinity
NaN
Some_
+toMap
# keyword
builtin
Optional
Text
List
+Location
# Bool
# True
# False
@@ -66,6 +71,7 @@ List
# Natural_show
# Integer_toDouble
# Integer_show
+# Natural_subtract
# Double_show
# List_build
# List_fold
@@ -116,7 +122,8 @@ authority
# ls32
# IPv4address
# dec_octet
-# reg_name
+# domain
+# domainlabel
# pchar
query
# pct_encoded
@@ -134,8 +141,6 @@ import
expression
annotated_expression
let_binding
-empty_collection
-non_empty_optional
# operator_expression
import_alt_expression
or_expression
@@ -165,11 +170,9 @@ non_empty_record_type
record_type_entry
non_empty_record_literal
record_literal_entry
-union_type_or_literal
+union_type
empty_union_type
-non_empty_union_type_or_literal
-union_literal_variant_value
+# non_empty_union_type
union_type_entry
-union_type_or_literal_variant_type
non_empty_list_literal
# complete_expression
diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs
index da9465d..b293357 100644
--- a/dhall_syntax/src/core/expr.rs
+++ b/dhall_syntax/src/core/expr.rs
@@ -1,6 +1,6 @@
use std::rc::Rc;
-use crate::map::DupTreeMap;
+use crate::map::{DupTreeMap, DupTreeSet};
use crate::visitor;
use crate::*;
@@ -119,6 +119,7 @@ pub enum Builtin {
NaturalOdd,
NaturalToInteger,
NaturalShow,
+ NaturalSubtract,
IntegerToDouble,
IntegerShow,
DoubleShow,
@@ -190,14 +191,10 @@ pub enum ExprF<SubExpr, Embed> {
DoubleLit(Double),
/// `"Some ${interpolated} text"`
TextLit(InterpolatedText<SubExpr>),
- /// `[] : List t`
+ /// `[] : t`
EmptyListLit(SubExpr),
/// `[x, y, z]`
NEListLit(Vec<SubExpr>),
- /// Deprecated Optional literal form
- /// `[] : Optional a`
- /// `[x] : Optional a`
- OldOptionalLit(Option<SubExpr>, SubExpr),
/// `Some e`
SomeLit(SubExpr),
/// `{ k1 : t1, k2 : t1 }`
@@ -206,14 +203,12 @@ pub enum ExprF<SubExpr, Embed> {
RecordLit(DupTreeMap<Label, SubExpr>),
/// `< k1 : t1, k2 >`
UnionType(DupTreeMap<Label, Option<SubExpr>>),
- /// `< k1 = t1, k2 : t2, k3 >`
- UnionLit(Label, SubExpr, DupTreeMap<Label, Option<SubExpr>>),
/// `merge x y : t`
Merge(SubExpr, SubExpr, Option<SubExpr>),
/// `e.x`
Field(SubExpr, Label),
/// `e.{ x, y, z }`
- Projection(SubExpr, Vec<Label>),
+ Projection(SubExpr, DupTreeSet<Label>),
/// Embeds an import or the result of resolving the import
Embed(Embed),
}
@@ -311,6 +306,35 @@ impl<N, E> Expr<N, E> {
{
trivial_result(self.traverse_embed(|x| Ok(map_embed(x))))
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor(
+ visit_embed,
+ ))
+ }
+
+ pub(crate) fn traverse_resolve_with_visitor<E2, Err, F1>(
+ &self,
+ visitor: &mut visitor::ResolveVisitor<F1>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ F1: FnMut(&E) -> Result<E2, Err>,
+ {
+ match self {
+ ExprF::BinOp(BinOp::ImportAlt, l, r) => l
+ .as_ref()
+ .traverse_resolve_with_visitor(visitor)
+ .or(r.as_ref().traverse_resolve_with_visitor(visitor)),
+ _ => self.visit(visitor),
+ }
+ }
}
impl Expr<X, X> {
@@ -387,6 +411,16 @@ impl<N, E> SubExpr<N, E> {
)),
}
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<SubExpr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ Ok(self.rewrap(self.as_ref().traverse_resolve(visit_embed)?))
+ }
}
impl SubExpr<X, X> {
diff --git a/dhall_syntax/src/core/import.rs b/dhall_syntax/src/core/import.rs
index c328e34..d41eae2 100644
--- a/dhall_syntax/src/core/import.rs
+++ b/dhall_syntax/src/core/import.rs
@@ -26,6 +26,7 @@ pub struct URL {
pub authority: String,
pub path: Vec<String>,
pub query: Option<String>,
+ // TODO: implement inline headers
pub headers: Option<Box<ImportHashed>>,
}
@@ -40,6 +41,7 @@ pub enum Scheme {
pub enum ImportMode {
Code,
RawText,
+ Location,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/dhall_syntax/src/core/map.rs b/dhall_syntax/src/core/map.rs
index 63f19cd..6a0ebda 100644
--- a/dhall_syntax/src/core/map.rs
+++ b/dhall_syntax/src/core/map.rs
@@ -1,5 +1,6 @@
/// A sorted map that allows multiple values for each key.
pub use dup_tree_map::DupTreeMap;
+pub use dup_tree_set::DupTreeSet;
mod one_or_more {
use either::Either;
@@ -232,3 +233,97 @@ mod dup_tree_map {
// unsafe impl<K, V> iter::TrustedLen for IntoIter<K, V> {}
}
+
+mod dup_tree_set {
+ use super::DupTreeMap;
+ use std::iter;
+
+ #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+ pub struct DupTreeSet<K> {
+ map: DupTreeMap<K, ()>,
+ }
+
+ pub type Iter<'a, K> = iter::Map<
+ super::dup_tree_map::Iter<'a, K, ()>,
+ for<'b> fn((&'b K, &'b ())) -> &'b K,
+ >;
+ pub type IntoIter<K> =
+ iter::Map<super::dup_tree_map::IntoIter<K, ()>, fn((K, ())) -> K>;
+
+ impl<K> DupTreeSet<K> {
+ pub fn new() -> Self
+ where
+ K: Ord,
+ {
+ DupTreeSet {
+ map: DupTreeMap::new(),
+ }
+ }
+
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+ pub fn is_empty(&self) -> bool {
+ self.map.is_empty()
+ }
+
+ pub fn iter(&self) -> Iter<'_, K>
+ where
+ K: Ord,
+ {
+ fn foo<'a, K>((k, ()): (&'a K, &'a ())) -> &'a K {
+ k
+ }
+ self.map.iter().map(foo)
+ }
+ }
+
+ impl<K> Default for DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ fn default() -> Self {
+ Self::new()
+ }
+ }
+
+ impl<K> IntoIterator for DupTreeSet<K>
+ where
+ K: Ord + Clone,
+ {
+ type Item = K;
+ type IntoIter = IntoIter<K>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ fn foo<K>((k, ()): (K, ())) -> K {
+ k
+ }
+ self.map.into_iter().map(foo)
+ }
+ }
+
+ impl<'a, K> IntoIterator for &'a DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ type Item = &'a K;
+ type IntoIter = Iter<'a, K>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+ }
+
+ impl<K> iter::FromIterator<K> for DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ fn from_iter<T>(iter: T) -> Self
+ where
+ T: IntoIterator<Item = K>,
+ {
+ let map = iter.into_iter().map(|k| (k, ())).collect();
+ DupTreeSet { map }
+ }
+ }
+}
diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs
index 99a9c11..68ad956 100644
--- a/dhall_syntax/src/core/visitor.rs
+++ b/dhall_syntax/src/core/visitor.rs
@@ -137,17 +137,10 @@ where
),
EmptyListLit(t) => EmptyListLit(v.visit_subexpr(t)?),
NEListLit(es) => NEListLit(vec(es, |e| v.visit_subexpr(e))?),
- OldOptionalLit(x, t) => OldOptionalLit(
- opt(x, |e| v.visit_subexpr(e))?,
- v.visit_subexpr(t)?,
- ),
SomeLit(e) => SomeLit(v.visit_subexpr(e)?),
RecordType(kts) => RecordType(dupmap(kts, v)?),
RecordLit(kvs) => RecordLit(dupmap(kvs, v)?),
UnionType(kts) => UnionType(optdupmap(kts, v)?),
- UnionLit(k, x, kts) => {
- UnionLit(k.clone(), v.visit_subexpr(x)?, optdupmap(kts, v)?)
- }
Merge(x, y, t) => Merge(
v.visit_subexpr(x)?,
v.visit_subexpr(y)?,
@@ -362,6 +355,31 @@ where
}
}
+pub struct ResolveVisitor<F1>(pub F1);
+
+impl<'a, 'b, N, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, E, E2>
+ for &'b mut ResolveVisitor<F1>
+where
+ N: Clone + 'a,
+ F1: FnMut(&E) -> Result<E2, Err>,
+{
+ type Error = Err;
+
+ fn visit_subexpr(
+ &mut self,
+ subexpr: &'a SubExpr<N, E>,
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
+ Ok(subexpr.rewrap(
+ subexpr
+ .as_ref()
+ .traverse_resolve_with_visitor(&mut **self)?,
+ ))
+ }
+ fn visit_embed(self, embed: &'a E) -> Result<E2, Self::Error> {
+ (self.0)(embed)
+ }
+}
pub struct NoteAbsurdVisitor;
impl<'a, 'b, N, E>
diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs
index 9d9a374..72dfcdd 100644
--- a/dhall_syntax/src/parser.rs
+++ b/dhall_syntax/src/parser.rs
@@ -6,7 +6,7 @@ use std::rc::Rc;
use dhall_generated_parser::{DhallParser, Rule};
-use crate::map::DupTreeMap;
+use crate::map::{DupTreeMap, DupTreeSet};
use crate::ExprF::*;
use crate::*;
@@ -80,6 +80,7 @@ impl crate::Builtin {
"Natural/odd" => Some(NaturalOdd),
"Natural/toInteger" => Some(NaturalToInteger),
"Natural/show" => Some(NaturalShow),
+ "Natural/subtract" => Some(NaturalSubtract),
"Integer/toDouble" => Some(IntegerToDouble),
"Integer/show" => Some(IntegerShow),
"Double/show" => Some(DoubleShow),
@@ -402,11 +403,50 @@ make_parser! {
"n" => "\n".to_owned(),
"r" => "\r".to_owned(),
"t" => "\t".to_owned(),
+ // "uXXXX" or "u{XXXXX}"
_ => {
- // "uXXXX"
- use std::convert::TryFrom;
- let c = u16::from_str_radix(&s[1..5], 16).unwrap();
- let c = char::try_from(u32::from(c)).unwrap();
+ use std::convert::{TryFrom, TryInto};
+
+ let s = &s[1..];
+ let s = if &s[0..1] == "{" {
+ &s[1..s.len()-1]
+ } else {
+ &s[0..s.len()]
+ };
+
+ if s.len() > 8 {
+ Err(format!("Escape sequences can't have more than 8 chars: \"{}\"", s))?
+ }
+
+ // pad with zeroes
+ let s: String = std::iter::repeat('0')
+ .take(8 - s.len())
+ .chain(s.chars())
+ .collect();
+
+ // `s` has length 8, so `bytes` has length 4
+ let bytes: &[u8] = &hex::decode(s).unwrap();
+ let i = u32::from_be_bytes(bytes.try_into().unwrap());
+ let c = char::try_from(i).unwrap();
+ match i {
+ 0xD800..=0xDFFF => {
+ let c_ecapsed = c.escape_unicode();
+ Err(format!("Escape sequences can't contain surrogate pairs: \"{}\"", c_ecapsed))?
+ },
+ 0x0FFFE..=0x0FFFF | 0x1FFFE..=0x1FFFF |
+ 0x2FFFE..=0x2FFFF | 0x3FFFE..=0x3FFFF |
+ 0x4FFFE..=0x4FFFF | 0x5FFFE..=0x5FFFF |
+ 0x6FFFE..=0x6FFFF | 0x7FFFE..=0x7FFFF |
+ 0x8FFFE..=0x8FFFF | 0x9FFFE..=0x9FFFF |
+ 0xAFFFE..=0xAFFFF | 0xBFFFE..=0xBFFFF |
+ 0xCFFFE..=0xCFFFF | 0xDFFFE..=0xDFFFF |
+ 0xEFFFE..=0xEFFFF | 0xFFFFE..=0xFFFFF |
+ 0x10FFFE..=0x10FFFF => {
+ let c_ecapsed = c.escape_unicode();
+ Err(format!("Escape sequences can't contain non-characters: \"{}\"", c_ecapsed))?
+ },
+ _ => {}
+ }
std::iter::once(c).collect()
}
}
@@ -677,6 +717,7 @@ make_parser! {
));
token_rule!(Text<()>);
+ token_rule!(Location<()>);
rule!(import<ParsedSubExpr> as expression; span; children!(
[import_hashed(location_hashed)] => {
@@ -691,6 +732,12 @@ make_parser! {
location_hashed
}))
},
+ [import_hashed(location_hashed), Location(_)] => {
+ spanned(span, Embed(Import {
+ mode: ImportMode::Location,
+ location_hashed
+ }))
+ },
));
token_rule!(lambda<()>);
@@ -700,6 +747,12 @@ make_parser! {
token_rule!(if_<()>);
token_rule!(in_<()>);
+ rule!(empty_list_literal<ParsedSubExpr> as expression; span; children!(
+ [expression(e)] => {
+ spanned(span, EmptyListLit(e))
+ },
+ ));
+
rule!(expression<ParsedSubExpr> as expression; span; children!(
[lambda(()), label(l), expression(typ),
arrow(()), expression(body)] => {
@@ -738,21 +791,6 @@ make_parser! {
token_rule!(List<()>);
token_rule!(Optional<()>);
- rule!(empty_collection<ParsedSubExpr> as expression; span; children!(
- [List(_), expression(t)] => {
- spanned(span, EmptyListLit(t))
- },
- [Optional(_), expression(t)] => {
- spanned(span, OldOptionalLit(None, t))
- },
- ));
-
- rule!(non_empty_optional<ParsedSubExpr> as expression; span; children!(
- [expression(x), Optional(_), expression(t)] => {
- spanned(span, OldOptionalLit(Some(x), t))
- }
- ));
-
rule!(import_alt_expression<ParsedSubExpr> as expression; children!(
[expression(e)] => e,
[expression(first), expression(rest)..] => {
@@ -846,6 +884,7 @@ make_parser! {
));
token_rule!(Some_<()>);
+ token_rule!(toMap<()>);
rule!(application_expression<ParsedSubExpr> as expression; children!(
[expression(e)] => e,
@@ -875,13 +914,13 @@ make_parser! {
}
));
- rule!(selector<Either<Label, Vec<Label>>>; children!(
+ rule!(selector<Either<Label, DupTreeSet<Label>>>; children!(
[label(l)] => Either::Left(l),
[labels(ls)] => Either::Right(ls),
[expression(e)] => unimplemented!("selection by expression"), // TODO
));
- rule!(labels<Vec<Label>>; children!(
+ rule!(labels<DupTreeSet<Label>>; children!(
[label(ls)..] => ls.collect(),
));
@@ -938,67 +977,22 @@ make_parser! {
[label(name), expression(expr)] => (name, expr)
));
- rule!(union_type_or_literal<ParsedSubExpr> as expression; span; children!(
+ rule!(union_type<ParsedSubExpr> as expression; span; children!(
[empty_union_type(_)] => {
spanned(span, UnionType(Default::default()))
},
- [non_empty_union_type_or_literal((Some((l, e)), entries))] => {
- spanned(span, UnionLit(l, e, entries))
- },
- [non_empty_union_type_or_literal((None, entries))] => {
- spanned(span, UnionType(entries))
+ [union_type_entry(entries)..] => {
+ spanned(span, UnionType(entries.collect()))
},
));
token_rule!(empty_union_type<()>);
- rule!(non_empty_union_type_or_literal
- <(Option<(Label, ParsedSubExpr)>,
- DupTreeMap<Label, Option<ParsedSubExpr>>)>;
- children!(
- [label(l), union_literal_variant_value((e, entries))] => {
- (Some((l, e)), entries)
- },
- [label(l), union_type_or_literal_variant_type((e, rest))] => {
- let (x, mut entries) = rest;
- entries.insert(l, e);
- (x, entries)
- },
- ));
-
- rule!(union_literal_variant_value
- <(ParsedSubExpr, DupTreeMap<Label, Option<ParsedSubExpr>>)>;
- children!(
- [expression(e), union_type_entry(entries)..] => {
- (e, entries.collect())
- },
- ));
-
rule!(union_type_entry<(Label, Option<ParsedSubExpr>)>; children!(
[label(name), expression(expr)] => (name, Some(expr)),
[label(name)] => (name, None),
));
- // TODO: unary union variants
- rule!(union_type_or_literal_variant_type
- <(Option<ParsedSubExpr>,
- (Option<(Label, ParsedSubExpr)>,
- DupTreeMap<Label, Option<ParsedSubExpr>>))>;
- children!(
- [expression(e), non_empty_union_type_or_literal(rest)] => {
- (Some(e), rest)
- },
- [expression(e)] => {
- (Some(e), (None, Default::default()))
- },
- [non_empty_union_type_or_literal(rest)] => {
- (None, rest)
- },
- [] => {
- (None, (None, Default::default()))
- },
- ));
-
rule!(non_empty_list_literal<ParsedSubExpr> as expression; span;
children!(
[expression(items)..] => spanned(
diff --git a/dhall_syntax/src/printer.rs b/dhall_syntax/src/printer.rs
index dbed55d..1d6c113 100644
--- a/dhall_syntax/src/printer.rs
+++ b/dhall_syntax/src/printer.rs
@@ -27,17 +27,11 @@ impl<SE: Display + Clone, E: Display> Display for ExprF<SE, E> {
write!(f, " = {} in {}", c, d)?;
}
EmptyListLit(t) => {
- write!(f, "[] : List {}", t)?;
+ write!(f, "[] : {}", t)?;
}
NEListLit(es) => {
fmt_list("[", ", ", "]", es, f, Display::fmt)?;
}
- OldOptionalLit(None, t) => {
- write!(f, "[] : Optional {}", t)?;
- }
- OldOptionalLit(Some(x), t) => {
- write!(f, "[{}] : Optional {}", x, t)?;
- }
SomeLit(e) => {
write!(f, "Some {}", e)?;
}
@@ -91,16 +85,6 @@ impl<SE: Display + Clone, E: Display> Display for ExprF<SE, E> {
}
Ok(())
})?,
- UnionLit(a, b, c) => {
- write!(f, "< {} = {}", a, b)?;
- for (k, v) in c {
- write!(f, " | {}", k)?;
- if let Some(v) = v {
- write!(f, ": {}", v)?;
- }
- }
- f.write_str(" >")?
- }
Embed(a) => a.fmt(f)?,
}
Ok(())
@@ -154,7 +138,6 @@ impl<S: Clone, A: Display + Clone> Expr<S, A> {
| Let(_, _, _, _)
| EmptyListLit(_)
| NEListLit(_)
- | OldOptionalLit(_, _)
| SomeLit(_)
| Merge(_, _, _)
| Annot(_, _)
@@ -189,8 +172,6 @@ impl<S: Clone, A: Display + Clone> Expr<S, A> {
a.phase(PrintPhase::BinOp(op)),
b.phase(PrintPhase::BinOp(op)),
),
- EmptyListLit(t) => EmptyListLit(t.phase(Import)),
- OldOptionalLit(x, t) => OldOptionalLit(x, t.phase(Import)),
SomeLit(e) => SomeLit(e.phase(Import)),
ExprF::App(f, a) => ExprF::App(f.phase(Import), a.phase(Import)),
Field(a, b) => Field(a.phase(Primitive), b),
@@ -443,6 +424,7 @@ impl Display for Import {
match self.mode {
Code => {}
RawText => write!(f, " as Text")?,
+ Location => write!(f, " as Location")?,
}
Ok(())
}
@@ -467,6 +449,7 @@ impl Display for Builtin {
NaturalOdd => "Natural/odd",
NaturalToInteger => "Natural/toInteger",
NaturalShow => "Natural/show",
+ NaturalSubtract => "Natural/subtract",
IntegerToDouble => "Integer/toDouble",
IntegerShow => "Integer/show",
DoubleShow => "Double/show",
diff --git a/tests_buffer b/tests_buffer
index 1ea9a1c..ca578e4 100644
--- a/tests_buffer
+++ b/tests_buffer
@@ -6,6 +6,7 @@ remove `double`
remove imports/parenthesizeUsing
remove multilet
selection by expression unit tests
+split aslocation test into actual unit tests
success/
imports/
Missing missing
@@ -86,6 +87,8 @@ success/
failure/
ProjectionByExpressionNeedsParens r.{ x: T }
+binary decoding:
+decode old-style optional literals ?
import:
success/
@@ -96,6 +99,8 @@ failure/
normalization:
variables across import boundaries
+Text/show ""
+Double/show -1.5e-10
TextLitNested1 "${""}${x}"
TextLitNested2 "${"${x}"}"
TextLitNested3 "${"${""}"}${x}"
@@ -104,6 +109,8 @@ variables across import boundaries
typecheck:
something that involves destructuring a recordtype after merge
+add some of the more complicated Prelude tests back, like List/enumerate
+failure on old-style optional literal
success/
MergeEmptyAlternative merge { x = 1 } < x >.x
MergeTrickyShadowing let _ = Bool in merge {_ = \(x: _) -> x} (<_: Bool>._ True)