├── .cargo └── config.toml ├── .envrc ├── .github ├── dependabot.yml ├── settings.yml └── workflows │ ├── benchmark-master.yaml │ ├── benchmark-pr.yaml │ ├── continuous-integration.yml │ ├── release-artifacts.yaml │ ├── release-python.yml │ ├── update-flake-lock.yml │ └── upload-pr-benchmarks.yaml ├── .gitignore ├── .markdownlint.json ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── HACKING.md ├── LICENSE ├── RATIONALE.md ├── README.md ├── RELEASES.md ├── RELEASING.md ├── cli ├── Cargo.toml ├── src │ ├── cli.rs │ ├── completions.rs │ ├── customize │ │ ├── interface.rs │ │ └── mod.rs │ ├── doc.rs │ ├── doctest.rs │ ├── error.rs │ ├── eval.rs │ ├── export.rs │ ├── format.rs │ ├── global.rs │ ├── input.rs │ ├── main.rs │ ├── metrics.rs │ ├── package.rs │ ├── pprint_ast.rs │ ├── query.rs │ ├── repl.rs │ └── typecheck.rs └── tests │ ├── integration │ ├── inputs │ │ ├── mixed.json │ │ ├── mixed.ncl │ │ ├── mixed.toml │ │ └── mixed_contract.ncl │ └── main.rs │ └── snapshot │ ├── README.md │ ├── imports │ ├── additional_contract1.ncl │ ├── additional_contract2.ncl │ └── package.toml │ ├── inputs │ ├── customize-mode │ │ ├── assignment_syntax_error.ncl │ │ ├── field_path_syntax_error.ncl │ │ ├── help.ncl │ │ ├── list.ncl │ │ ├── not_an_input.ncl │ │ ├── show.ncl │ │ ├── sigil_env.ncl │ │ ├── sigil_missing_colon.ncl │ │ ├── simple_adder.ncl │ │ ├── unknown_field_path.ncl │ │ ├── unknown_override.ncl │ │ ├── unknown_sigil_attr.ncl │ │ └── unknown_sigil_expr.ncl │ ├── docs │ │ ├── evaluation.ncl │ │ ├── function.ncl │ │ ├── record.ncl │ │ ├── recursive.ncl │ │ ├── recursive_false_positive.ncl │ │ └── types.ncl │ ├── doctest │ │ ├── fail_expected_error.ncl │ │ ├── fail_unexpected_error.ncl │ │ ├── fail_wrong_output.ncl │ │ ├── pass.ncl │ │ └── record_regression.ncl │ ├── errors │ │ ├── annotated_record_pattern_typecheck_fail.ncl │ │ ├── array_at_empty_array.ncl │ │ ├── array_at_out_of_bound.ncl │ │ ├── array_contract_fail.ncl │ │ ├── array_merge_fail.ncl │ │ ├── array_range_reversed_indices.ncl │ │ ├── array_range_step_negative_step.ncl │ │ ├── blame_custom_message_ansi_escaping.ncl │ │ ├── caller_contract_violation.ncl │ │ ├── contract_label_propagation.ncl │ │ ├── contract_with_custom_diagnostic.ncl │ │ ├── destructuring_assign_fail.ncl │ │ ├── destructuring_closed_fail.ncl │ │ ├── destructuring_nonexistent_idents.ncl │ │ ├── destructuring_repeated_ident.ncl │ │ ├── destructuring_repeated_ident_typed.ncl │ │ ├── destructuring_rest_fail.ncl │ │ ├── destructuring_type_mismatch_fail.ncl │ │ ├── destructuring_type_mismatch_field_pattern_fail.ncl │ │ ├── destructuring_type_mismatch_nested_destructuring_fail.ncl │ │ ├── destructuring_typecontract_fail.ncl │ │ ├── dictionary_contract_fail.ncl │ │ ├── enum_forall_constraints_typecheck.ncl │ │ ├── enum_forall_parametricity_violation.ncl │ │ ├── fun_contract_range_nested.ncl │ │ ├── fun_contract_range_violation.ncl │ │ ├── function_contract_domain_violation.ncl │ │ ├── function_contract_violation.ncl │ │ ├── include_multiple_composite_path.ncl │ │ ├── include_multiple_list.ncl │ │ ├── include_multiple_other_include.ncl │ │ ├── include_multiple_with_def.ncl │ │ ├── interpolate_record_type_field.ncl │ │ ├── interpolation_non_stringable.ncl │ │ ├── invalid_contract_expression.ncl │ │ ├── invalid_record_type.ncl │ │ ├── let_block_duplicate_identifier.ncl │ │ ├── let_block_not_rec.ncl │ │ ├── mismatched_row_record_pattern_fail.ncl │ │ ├── nested_annotated_record_pattern_typecheck_fail.ncl │ │ ├── no_internals_when_currying.ncl │ │ ├── non_exhaustive_match.ncl │ │ ├── non_serializable_print_path.ncl │ │ ├── query_non_record.ncl │ │ ├── record_access.ncl │ │ ├── record_access_suggestion.ncl │ │ ├── record_destructuring_duplicate_ident.ncl │ │ ├── record_forall_constraints_contract.ncl │ │ ├── record_forall_constraints_typecheck.ncl │ │ ├── record_forall_parametricity_violation.ncl │ │ ├── record_type_repeated_field.ncl │ │ ├── serialization_number_out_of_range.ncl │ │ ├── simple_contract_fail.ncl │ │ ├── spanned_toml.ncl │ │ ├── string_delimiter_mismatch.ncl │ │ ├── subcontract_nested_custom_diagnostics.ncl │ │ ├── subcontract_type_path_underline.ncl │ │ ├── trace_not_saturated.ncl │ │ ├── typecheck_strict_mode.ncl │ │ ├── typed_field_without_annotation.ncl │ │ ├── typedcheck_strict_mode_is_strict.ncl │ │ ├── unification_variable_aliasing.ncl │ │ ├── validator_custom_error.ncl │ │ └── value_contract_violation.ncl │ ├── eval │ │ ├── escaping.ncl │ │ ├── fail_additional_contract.ncl │ │ ├── fail_additional_two_contracts1.ncl │ │ ├── fail_additional_two_contracts2.ncl │ │ ├── fieldarg_with_contracts.ncl │ │ └── records.ncl │ ├── export │ │ ├── nested_record.ncl │ │ ├── not_exported_undefined.ncl │ │ └── trace.ncl │ ├── package │ │ ├── invalid-git-dep.ncl │ │ ├── invalid-git-url.ncl │ │ ├── invalid-version.ncl │ │ └── missing-field.ncl │ ├── pretty │ │ ├── field_escaping.ncl │ │ ├── id_quoting.ncl │ │ ├── let_annotations.ncl │ │ ├── let_block.ncl │ │ ├── let_block_with_pat.ncl │ │ ├── let_rec.ncl │ │ ├── multiline_doc.ncl │ │ └── simple_record.ncl │ ├── query │ │ └── query_included_field.ncl │ └── warnings │ │ ├── naked_contract.ncl │ │ ├── naked_contract_parametrized.ncl │ │ └── supressed.ncl │ ├── main.rs │ └── snapshots │ ├── snapshot__doc_stderr_function.ncl.snap │ ├── snapshot__doc_stdout_evaluation.ncl.snap │ ├── snapshot__doc_stdout_record.ncl.snap │ ├── snapshot__doc_stdout_recursive.ncl.snap │ ├── snapshot__doc_stdout_recursive_false_positive.ncl.snap │ ├── snapshot__doc_stdout_types.ncl.snap │ ├── snapshot__eval_stderr_annotated_record_pattern_typecheck_fail.ncl.snap │ ├── snapshot__eval_stderr_array_at_empty_array.ncl.snap │ ├── snapshot__eval_stderr_array_at_out_of_bound.ncl.snap │ ├── snapshot__eval_stderr_array_contract_fail.ncl.snap │ ├── snapshot__eval_stderr_array_merge_fail.ncl.snap │ ├── snapshot__eval_stderr_array_range_reversed_indices.ncl.snap │ ├── snapshot__eval_stderr_array_range_step_negative_step.ncl.snap │ ├── snapshot__eval_stderr_blame_custom_message_ansi_escaping.ncl.snap │ ├── snapshot__eval_stderr_caller_contract_violation.ncl.snap │ ├── snapshot__eval_stderr_contract_label_propagation.ncl.snap │ ├── snapshot__eval_stderr_contract_with_custom_diagnostic.ncl.snap │ ├── snapshot__eval_stderr_destructuring_assign_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_closed_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_nonexistent_idents.ncl.snap │ ├── snapshot__eval_stderr_destructuring_repeated_ident.ncl.snap │ ├── snapshot__eval_stderr_destructuring_repeated_ident_typed.ncl.snap │ ├── snapshot__eval_stderr_destructuring_rest_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_type_mismatch_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_type_mismatch_field_pattern_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_type_mismatch_nested_destructuring_fail.ncl.snap │ ├── snapshot__eval_stderr_destructuring_typecontract_fail.ncl.snap │ ├── snapshot__eval_stderr_dictionary_contract_fail.ncl.snap │ ├── snapshot__eval_stderr_enum_forall_constraints_typecheck.ncl.snap │ ├── snapshot__eval_stderr_enum_forall_parametricity_violation.ncl.snap │ ├── snapshot__eval_stderr_fail_additional_contract.ncl.snap │ ├── snapshot__eval_stderr_fail_additional_two_contracts1.ncl.snap │ ├── snapshot__eval_stderr_fail_additional_two_contracts2.ncl.snap │ ├── snapshot__eval_stderr_fieldarg_with_contracts.ncl.snap │ ├── snapshot__eval_stderr_fun_contract_range_nested.ncl.snap │ ├── snapshot__eval_stderr_fun_contract_range_violation.ncl.snap │ ├── snapshot__eval_stderr_function_contract_domain_violation.ncl.snap │ ├── snapshot__eval_stderr_function_contract_violation.ncl.snap │ ├── snapshot__eval_stderr_include_multiple_composite_path.ncl.snap │ ├── snapshot__eval_stderr_include_multiple_list.ncl.snap │ ├── snapshot__eval_stderr_include_multiple_other_include.ncl.snap │ ├── snapshot__eval_stderr_include_multiple_with_def.ncl.snap │ ├── snapshot__eval_stderr_interpolate_record_type_field.ncl.snap │ ├── snapshot__eval_stderr_interpolation_non_stringable.ncl.snap │ ├── snapshot__eval_stderr_invalid_contract_expression.ncl.snap │ ├── snapshot__eval_stderr_invalid_record_type.ncl.snap │ ├── snapshot__eval_stderr_let_block_duplicate_identifier.ncl.snap │ ├── snapshot__eval_stderr_let_block_not_rec.ncl.snap │ ├── snapshot__eval_stderr_mismatched_row_record_pattern_fail.ncl.snap │ ├── snapshot__eval_stderr_naked_contract.ncl.snap │ ├── snapshot__eval_stderr_naked_contract_parametrized.ncl.snap │ ├── snapshot__eval_stderr_nested_annotated_record_pattern_typecheck_fail.ncl.snap │ ├── snapshot__eval_stderr_no_internals_when_currying.ncl.snap │ ├── snapshot__eval_stderr_non_exhaustive_match.ncl.snap │ ├── snapshot__eval_stderr_record_access.ncl.snap │ ├── snapshot__eval_stderr_record_access_suggestion.ncl.snap │ ├── snapshot__eval_stderr_record_destructuring_duplicate_ident.ncl.snap │ ├── snapshot__eval_stderr_record_forall_constraints_contract.ncl.snap │ ├── snapshot__eval_stderr_record_forall_constraints_typecheck.ncl.snap │ ├── snapshot__eval_stderr_record_forall_parametricity_violation.ncl.snap │ ├── snapshot__eval_stderr_record_type_repeated_field.ncl.snap │ ├── snapshot__eval_stderr_simple_contract_fail.ncl.snap │ ├── snapshot__eval_stderr_spanned_toml.ncl.snap │ ├── snapshot__eval_stderr_string_delimiter_mismatch.ncl.snap │ ├── snapshot__eval_stderr_subcontract_nested_custom_diagnostics.ncl.snap │ ├── snapshot__eval_stderr_subcontract_type_path_underline.ncl.snap │ ├── snapshot__eval_stderr_supressed.ncl.snap │ ├── snapshot__eval_stderr_trace_not_saturated.ncl.snap │ ├── snapshot__eval_stderr_typed_field_without_annotation.ncl.snap │ ├── snapshot__eval_stderr_unification_variable_aliasing.ncl.snap │ ├── snapshot__eval_stderr_validator_custom_error.ncl.snap │ ├── snapshot__eval_stderr_value_contract_violation.ncl.snap │ ├── snapshot__eval_stdout_escaping.ncl.snap │ ├── snapshot__eval_stdout_let_block_rec.ncl.snap │ ├── snapshot__eval_stdout_records.ncl.snap │ ├── snapshot__export_stderr_assignment_syntax_error.ncl.snap │ ├── snapshot__export_stderr_field_path_syntax_error.ncl.snap │ ├── snapshot__export_stderr_non_serializable_print_path.ncl.snap │ ├── snapshot__export_stderr_not_an_input.ncl.snap │ ├── snapshot__export_stderr_serialization_number_out_of_range.ncl.snap │ ├── snapshot__export_stderr_sigil_missing_colon.ncl.snap │ ├── snapshot__export_stderr_trace.ncl.snap │ ├── snapshot__export_stderr_unknown_field_path.ncl.snap │ ├── snapshot__export_stderr_unknown_override.ncl.snap │ ├── snapshot__export_stderr_unknown_sigil_attr.ncl.snap │ ├── snapshot__export_stderr_unknown_sigil_expr.ncl.snap │ ├── snapshot__export_stderr_unkonwn_field_path.ncl.snap │ ├── snapshot__export_stdout_help.ncl.snap │ ├── snapshot__export_stdout_list.ncl.snap │ ├── snapshot__export_stdout_nested_record.ncl.snap │ ├── snapshot__export_stdout_not_exported_undefined.ncl.snap │ ├── snapshot__export_stdout_show.ncl.snap │ ├── snapshot__export_stdout_sigil_env.ncl.snap │ ├── snapshot__export_stdout_simple_adder.ncl.snap │ ├── snapshot__export_stdout_trace.ncl.snap │ ├── snapshot__package_stderr_invalid-git-dep.ncl.snap │ ├── snapshot__package_stderr_invalid-git-url.ncl.snap │ ├── snapshot__package_stderr_invalid-index-id.ncl.snap │ ├── snapshot__package_stderr_invalid-version.ncl.snap │ ├── snapshot__package_stderr_missing-field.ncl.snap │ ├── snapshot__pprint-ast_stdout_field_escaping.ncl.snap │ ├── snapshot__pprint-ast_stdout_id_quoting.ncl.snap │ ├── snapshot__pprint-ast_stdout_let_annotations.ncl.snap │ ├── snapshot__pprint-ast_stdout_let_block.ncl.snap │ ├── snapshot__pprint-ast_stdout_let_block_with_pat.ncl.snap │ ├── snapshot__pprint-ast_stdout_let_rec.ncl.snap │ ├── snapshot__pprint-ast_stdout_multiline_doc.ncl.snap │ ├── snapshot__pprint-ast_stdout_simple_record.ncl.snap │ ├── snapshot__query_stderr_field_path_syntax_error.ncl.snap │ ├── snapshot__query_stderr_query_non_record.ncl.snap │ ├── snapshot__query_stderr_unknown_field_path.ncl.snap │ ├── snapshot__query_stdout_query_included_field.ncl.snap │ ├── snapshot__query_stdout_show.ncl.snap │ ├── snapshot__test_stderr_fail_expected_error.ncl.snap │ ├── snapshot__test_stderr_fail_unexpected_error.ncl.snap │ ├── snapshot__test_stderr_fail_wrong_output.ncl.snap │ ├── snapshot__test_stderr_pass.ncl.snap │ ├── snapshot__test_stderr_record_regression.ncl.snap │ ├── snapshot__test_stdout_fail_expected_error.ncl.snap │ ├── snapshot__test_stdout_fail_unexpected_error.ncl.snap │ ├── snapshot__test_stdout_fail_wrong_output.ncl.snap │ ├── snapshot__test_stdout_pass.ncl.snap │ ├── snapshot__test_stdout_record_regression.ncl.snap │ ├── snapshot__typecheck_stderr_typecheck_strict_mode.ncl.snap │ └── snapshot__typecheck_stderr_typedcheck_strict_mode_is_strict.ncl.snap ├── core ├── Cargo.toml ├── benches │ ├── arrays.rs │ ├── arrays │ │ ├── fold.ncl │ │ ├── generate.ncl │ │ ├── map.ncl │ │ ├── pipe.ncl │ │ ├── primes.ncl │ │ ├── random.ncl │ │ ├── sort.ncl │ │ └── sum.ncl │ ├── functions.rs │ ├── functions │ │ └── church.ncl │ ├── lorem.txt │ ├── mantis.rs │ ├── mantis │ │ ├── README.md │ │ ├── deploy-example.ncl │ │ ├── deploy.ncl │ │ ├── jobs │ │ │ └── mantis.ncl │ │ ├── lib.ncl │ │ ├── run.ncl │ │ ├── schemas │ │ │ └── nomad │ │ │ │ └── types.ncl │ │ └── tasks │ │ │ ├── promtail.ncl │ │ │ └── telegraf.ncl │ ├── nixpkgs │ │ └── lists.ncl │ ├── numeric.rs │ ├── numeric │ │ ├── fibonacci.ncl │ │ ├── pidigits.ncl │ │ ├── reduce.ncl │ │ └── scalar.ncl │ ├── records.rs │ ├── records │ │ ├── countLetters.ncl │ │ └── merge.ncl │ ├── serialization.rs │ ├── serialization │ │ ├── input.json │ │ └── main.ncl │ ├── stdlib.rs │ ├── strings │ │ └── interpolation.ncl │ └── typecheck-nixpkgs-lib.rs ├── build.rs ├── src │ ├── bytecode │ │ ├── ast │ │ │ ├── alloc.rs │ │ │ ├── builder.rs │ │ │ ├── combine.rs │ │ │ ├── compat.rs │ │ │ ├── mod.rs │ │ │ ├── pattern │ │ │ │ ├── bindings.rs │ │ │ │ └── mod.rs │ │ │ ├── primop.rs │ │ │ ├── record.rs │ │ │ └── typ.rs │ │ ├── mod.rs │ │ └── pretty.rs │ ├── cache.rs │ ├── closurize.rs │ ├── combine.rs │ ├── deserialize.rs │ ├── environment.rs │ ├── error │ │ ├── mod.rs │ │ ├── report.rs │ │ ├── suggest.rs │ │ └── warning.rs │ ├── eval │ │ ├── cache │ │ │ ├── incremental.rs │ │ │ ├── lazy.rs │ │ │ └── mod.rs │ │ ├── callstack.rs │ │ ├── contract_eq.rs │ │ ├── fixpoint.rs │ │ ├── merge.rs │ │ ├── mod.rs │ │ ├── operation.rs │ │ ├── stack.rs │ │ └── tests.rs │ ├── files.rs │ ├── format.rs │ ├── identifier.rs │ ├── label.rs │ ├── lib.rs │ ├── metrics.rs │ ├── nix_ffi │ │ ├── cpp │ │ │ ├── nix.cc │ │ │ └── nix.hh │ │ └── mod.rs │ ├── package.rs │ ├── parser │ │ ├── error.rs │ │ ├── grammar.lalrpop │ │ ├── lexer.rs │ │ ├── mod.rs │ │ ├── tests.rs │ │ ├── uniterm.rs │ │ └── utils.rs │ ├── position.rs │ ├── pretty.rs │ ├── program.rs │ ├── repl │ │ ├── command.rs │ │ ├── mod.rs │ │ ├── query_print.rs │ │ ├── rustyline_frontend.rs │ │ ├── simple_frontend.rs │ │ └── wasm_frontend.rs │ ├── serialize.rs │ ├── stdlib.rs │ ├── term │ │ ├── array.rs │ │ ├── make │ │ │ └── builder.rs │ │ ├── mod.rs │ │ ├── pattern │ │ │ ├── bindings.rs │ │ │ ├── compile.rs │ │ │ └── mod.rs │ │ ├── record.rs │ │ └── string.rs │ ├── transform │ │ ├── desugar_destructuring.rs │ │ ├── free_vars.rs │ │ ├── gen_pending_contracts.rs │ │ ├── import_resolution.rs │ │ ├── mod.rs │ │ └── substitute_wildcards.rs │ ├── traverse.rs │ ├── typ.rs │ └── typecheck │ │ ├── eq.rs │ │ ├── error.rs │ │ ├── mk_uniftype.rs │ │ ├── mod.rs │ │ ├── operation.rs │ │ ├── pattern.rs │ │ ├── record.rs │ │ ├── reporting.rs │ │ ├── subtyping.rs │ │ └── unif.rs ├── stdlib │ ├── internals.ncl │ └── std.ncl └── tests │ ├── README.md │ ├── examples │ └── main.rs │ ├── integration │ ├── contract_label_path.rs │ ├── contracts_fail.rs │ ├── free_vars.rs │ ├── infinite_rec.rs │ ├── inputs │ │ ├── adts │ │ │ ├── deep_seq_enum.ncl │ │ │ ├── deep_seq_enum2.ncl │ │ │ ├── enum_contract_propagation.ncl │ │ │ ├── enum_primops.ncl │ │ │ ├── enum_wildcard_substitution.ncl │ │ │ ├── force_enum.ncl │ │ │ └── force_enum2.ncl │ │ ├── arrays │ │ │ ├── elem_at_empty_array.ncl │ │ │ ├── elem_at_index_out_of_bounds.ncl │ │ │ ├── elem_at_negative_index.ncl │ │ │ ├── elem_at_non_array_arg.ncl │ │ │ ├── elem_at_non_int_index.ncl │ │ │ ├── slice_empty_array.ncl │ │ │ ├── slice_non_array.ncl │ │ │ ├── stdlib_at_non_array_arg_raises_blame.ncl │ │ │ ├── stdlib_at_non_number_arg_raises_blame.ncl │ │ │ ├── stdlib_drop_first_non_array_arg.ncl │ │ │ └── stdlib_first_non_array_arg.ncl │ │ ├── contracts │ │ │ ├── and_bool_contract_fail.ncl │ │ │ ├── and_number_bool.ncl │ │ │ ├── any_of_basic_fail.ncl │ │ │ ├── any_of_empty.ncl │ │ │ ├── any_of_record_delayed_fail.ncl │ │ │ ├── any_of_record_immediate_fail.ncl │ │ │ ├── array_contract_bad_element.ncl │ │ │ ├── array_contract_fn_is_not_an_array.ncl │ │ │ ├── array_contract_num_is_not_an_array.ncl │ │ │ ├── basic_custom_contract.ncl │ │ │ ├── boolean_combinators.ncl │ │ │ ├── contract_applies_to_default_value.ncl │ │ │ ├── contracts.ncl │ │ │ ├── contracts_dont_capture_type_vars.ncl │ │ │ ├── custom_generic_fail.ncl │ │ │ ├── custom_generic_immediate_fail.ncl │ │ │ ├── custom_generic_succeed.ncl │ │ │ ├── custom_predicate_fail.ncl │ │ │ ├── custom_predicate_succeed.ncl │ │ │ ├── custom_validator_fail.ncl │ │ │ ├── custom_validator_succeed.ncl │ │ │ ├── dedup_multiple.ncl │ │ │ ├── dictionary_contract_propagates_through_merge.ncl │ │ │ ├── div_by_zero.ncl │ │ │ ├── enum_contract_empty_enum.ncl │ │ │ ├── enum_contract_missing_variant.ncl │ │ │ ├── enum_contract_non_enum_value.ncl │ │ │ ├── enum_variant_fail.ncl │ │ │ ├── equating_fn_match.ncl │ │ │ ├── equating_functions.ncl │ │ │ ├── include_recursive_contract.ncl │ │ │ ├── let_order.ncl │ │ │ ├── not_any_of_fail.ncl │ │ │ ├── not_basic_fail.ncl │ │ │ ├── not_record_fail.ncl │ │ │ ├── poly_record_contract_bad_field.ncl │ │ │ ├── poly_record_contract_empty_record.ncl │ │ │ ├── poly_record_contract_higher_order_fn.ncl │ │ │ ├── poly_record_contract_map_sealed_tail.ncl │ │ │ ├── poly_record_contract_merge_sealed_tail_lhs.ncl │ │ │ ├── poly_record_contract_merge_sealed_tail_rhs.ncl │ │ │ ├── poly_record_contract_missing_field.ncl │ │ │ ├── poly_record_contract_return_val_without_tail.ncl │ │ │ ├── poly_record_contract_return_val_wrong_tail.ncl │ │ │ ├── poly_record_contract_sealed_tail_dynamic_access.ncl │ │ │ ├── poly_record_contract_sealed_tail_remove_field.ncl │ │ │ ├── poly_record_contract_sealed_tail_static_access.ncl │ │ │ ├── polymorphic_function_contract.ncl │ │ │ ├── record_contract_bad_field.ncl │ │ │ ├── record_contract_constraint.ncl │ │ │ ├── record_contract_empty_record.ncl │ │ │ ├── record_contract_extra_field.ncl │ │ │ ├── record_contract_missing_field.ncl │ │ │ ├── record_contract_nested_extra_field.ncl │ │ │ ├── record_contract_nested_failure.ncl │ │ │ ├── record_contract_nested_missing_field.ncl │ │ │ ├── regression_panic_function_contract_fail.ncl │ │ │ ├── sequence.ncl │ │ │ ├── simplify_doesnt_remove_fields.ncl │ │ │ ├── type_annot_inline.ncl │ │ │ ├── type_annot_let.ncl │ │ │ ├── types_dont_propagate.ncl │ │ │ ├── unsound_dedup_dict_contract.ncl │ │ │ └── unsound_dedup_record_contract.ncl │ │ ├── core │ │ │ ├── arrays.ncl │ │ │ ├── basics.ncl │ │ │ ├── builtins.ncl │ │ │ ├── comparison_ge_string_string.ncl │ │ │ ├── comparison_geq_string_string.ncl │ │ │ ├── comparison_le_number_bool.ncl │ │ │ ├── comparison_le_string_number.ncl │ │ │ ├── comparison_leq_bool_array.ncl │ │ │ ├── curried_dot.ncl │ │ │ ├── eq.ncl │ │ │ ├── fibo.ncl │ │ │ ├── functions.ncl │ │ │ ├── import.ncl │ │ │ ├── let_block_rec.ncl │ │ │ ├── let_rec_block_with_pat.ncl │ │ │ ├── numbers.ncl │ │ │ ├── or_string_bool.ncl │ │ │ ├── records.ncl │ │ │ └── recursive_let.ncl │ │ ├── destructuring │ │ │ ├── adt_enum_tag.ncl │ │ │ ├── adt_enum_tag_tag_mismatch.ncl │ │ │ ├── adt_extra_arg.ncl │ │ │ ├── adt_missing_arg.ncl │ │ │ ├── adt_type_matches.ncl │ │ │ ├── adt_type_mismatch_extra_row.ncl │ │ │ ├── adt_type_mismatch_tag.ncl │ │ │ ├── adt_wrong_tag.ncl │ │ │ ├── adt_wrong_type.ncl │ │ │ ├── assign.ncl │ │ │ ├── assign_fail.ncl │ │ │ ├── atbind.ncl │ │ │ ├── closed_fail.ncl │ │ │ ├── constant_bool_fail.ncl │ │ │ ├── constant_null_fail.ncl │ │ │ ├── constant_number_fail.ncl │ │ │ ├── constant_string_fail.ncl │ │ │ ├── constants.ncl │ │ │ ├── default.ncl │ │ │ ├── fun.ncl │ │ │ ├── mixed.ncl │ │ │ ├── nested.ncl │ │ │ ├── nonexistent_idents.ncl │ │ │ ├── open.ncl │ │ │ ├── preserves_types.ncl │ │ │ ├── repeated_ident.ncl │ │ │ ├── repeated_ident_typed.ncl │ │ │ ├── rest.ncl │ │ │ ├── rest_fail.ncl │ │ │ ├── simple.ncl │ │ │ ├── type_annotations.ncl │ │ │ ├── type_mismatch_fail.ncl │ │ │ ├── type_mismatch_field_pattern_fail.ncl │ │ │ ├── type_mismatch_nested_destructuring_fail.ncl │ │ │ ├── typecontract.ncl │ │ │ └── typecontract_fail.ncl │ │ ├── imports │ │ │ ├── circular_imports.ncl │ │ │ ├── contract_fail.ncl │ │ │ ├── direct_import_loop.ncl │ │ │ ├── explicit.ncl │ │ │ ├── explicit_unknowntag.ncl │ │ │ ├── fallback.ncl │ │ │ ├── imported │ │ │ │ ├── circular_imports.ncl │ │ │ │ ├── circular_imports1.ncl │ │ │ │ ├── circular_imports2.ncl │ │ │ │ ├── contract_fail.ncl │ │ │ │ ├── direct_import_loop.ncl │ │ │ │ ├── empty.yaml │ │ │ │ ├── file_with_unknown_extension.tst │ │ │ │ ├── file_without_extension │ │ │ │ ├── import_parent.ncl │ │ │ │ ├── multi_imports.ncl │ │ │ │ ├── multiple.yaml │ │ │ │ ├── nested.ncl │ │ │ │ ├── nested_syntax_error.ncl │ │ │ │ ├── nested_syntax_error1.ncl │ │ │ │ ├── nested_syntax_error2.ncl │ │ │ │ ├── nested_table.toml │ │ │ │ ├── pkg1 │ │ │ │ │ └── main.ncl │ │ │ │ ├── pkg2 │ │ │ │ │ └── main.ncl │ │ │ │ ├── root_path.ncl │ │ │ │ ├── root_path │ │ │ │ │ ├── fourtytwo.ncl │ │ │ │ │ └── import.ncl │ │ │ │ ├── serialize.ncl │ │ │ │ ├── two.ncl │ │ │ │ ├── typecheck_fail.ncl │ │ │ │ ├── unexpected_token.ncl │ │ │ │ ├── unexpected_token_buried.ncl │ │ │ │ └── unexpected_token_in_record.ncl │ │ │ ├── missing-nickel-path.ncl │ │ │ ├── multi_imports.ncl │ │ │ ├── needs-nickel-path.ncl │ │ │ ├── nested.ncl │ │ │ ├── nested_syntax_error.ncl │ │ │ ├── nested_toml_table.ncl │ │ │ ├── recursive.ncl │ │ │ ├── root_path.ncl │ │ │ ├── serialize.ncl │ │ │ ├── static_typing_fail.ncl │ │ │ ├── typecheck_fail.ncl │ │ │ ├── unexpected_token_buried.ncl │ │ │ ├── unexpected_token_fail.ncl │ │ │ ├── unexpected_token_in_record_fail.ncl │ │ │ └── yaml_import.ncl │ │ ├── infinite_loops │ │ │ ├── mutually_recursive_functions.ncl │ │ │ ├── x_eq_expr_involving_x.ncl │ │ │ ├── x_eq_x.ncl │ │ │ └── x_eq_y_eq_z_eq_x.ncl │ │ ├── lib │ │ │ ├── import_typecheck_strict.ncl │ │ │ ├── imported.ncl │ │ │ └── typed-import.ncl │ │ ├── merging │ │ │ ├── adts.ncl │ │ │ ├── adts_different_tags.ncl │ │ │ ├── array-merge.ncl │ │ │ ├── lazy-propagation.ncl │ │ │ ├── merge_compose_contract.ncl │ │ │ ├── merge_conflict_inside_metavalue.ncl │ │ │ ├── merge_contract.ncl │ │ │ ├── merge_default_contract.ncl │ │ │ ├── metavalues.ncl │ │ │ ├── multiple_overrides.ncl │ │ │ ├── overriding.ncl │ │ │ └── priorities.ncl │ │ ├── parsing │ │ │ ├── annotations.ncl │ │ │ ├── identifiers.ncl │ │ │ ├── type_var_outside_forall.ncl │ │ │ ├── unbound_record_tail_var.ncl │ │ │ ├── unbound_type_variable.ncl │ │ │ ├── unbound_var_in_contract.ncl │ │ │ └── unexpected_token │ │ │ │ ├── buried.ncl │ │ │ │ ├── dollar.ncl │ │ │ │ └── in_record.ncl │ │ ├── pattern-matching │ │ │ ├── arrays.ncl │ │ │ ├── basics.ncl │ │ │ ├── contract_blame.ncl │ │ │ ├── contract_default_value_blame.ncl │ │ │ ├── contracts.ncl │ │ │ ├── default_fail_previous_contract.ncl │ │ │ ├── default_value.ncl │ │ │ ├── enum_after_wildcard.ncl │ │ │ ├── guards.ncl │ │ │ ├── non_bool_guard.ncl │ │ │ ├── non_exhaustive_enum_pattern.ncl │ │ │ ├── non_exhaustive_record_pattern.ncl │ │ │ ├── or_pattern_vars_mismatch.ncl │ │ │ ├── or_patterns.ncl │ │ │ └── wildcards.ncl │ │ ├── records │ │ │ ├── cannot_use_dynamic_fields_recursively.ncl │ │ │ ├── dynamic_field_missing.ncl │ │ │ ├── freeze_insert_fails_on_missing.ncl │ │ │ ├── freezing.ncl │ │ │ ├── freezing_ops.ncl │ │ │ ├── merge_different_vals_both_force.ncl │ │ │ ├── merge_different_vals_default_prio.ncl │ │ │ ├── merge_different_vals_no_priority.ncl │ │ │ ├── merge_nested_different_vals_default_prio.ncl │ │ │ ├── merge_nested_different_vals_no_prio.ncl │ │ │ ├── merge_nested_different_vals_prio_0.ncl │ │ │ ├── merge_nested_different_vals_same_priority.ncl │ │ │ ├── merge_nested_incompatible_types.ncl │ │ │ ├── merge_unfreezes.ncl │ │ │ ├── missing_field.ncl │ │ │ ├── missing_field_not_exported.ncl │ │ │ ├── missing_field_with_contract.ncl │ │ │ ├── record_defs.ncl │ │ │ ├── record_includes.ncl │ │ │ ├── record_insert.ncl │ │ │ └── static_access_missing_field.ncl │ │ ├── serialization │ │ │ ├── number_out_of_range.ncl │ │ │ ├── serialize.ncl │ │ │ └── serialize_package.ncl │ │ ├── stdlib │ │ │ ├── enum.ncl │ │ │ ├── maths.ncl │ │ │ ├── record_empty_optional_ops.ncl │ │ │ ├── record_get_missing_field.ncl │ │ │ ├── record_insert_with_opts_existing_field.ncl │ │ │ ├── record_remove_empty_opt_field.ncl │ │ │ ├── string_contains_find_replace.ncl │ │ │ ├── string_contracts.ncl │ │ │ ├── string_conversions.ncl │ │ │ ├── string_find.ncl │ │ │ ├── string_find_all.ncl │ │ │ ├── string_primitives.ncl │ │ │ ├── string_split_join.ncl │ │ │ ├── string_trim.ncl │ │ │ └── string_uppercase_lowercase.ncl │ │ ├── strings │ │ │ ├── string_interpolation.ncl │ │ │ ├── string_interpolation_record.ncl │ │ │ └── symbolic_strings.ncl │ │ └── typecheck │ │ │ ├── algebraic_data_types.ncl │ │ │ ├── array_subtyping.ncl │ │ │ ├── basic_algebraic_data_type_mismatch.ncl │ │ │ ├── basic_algebraic_data_type_row_mismatch.ncl │ │ │ ├── basic_typechecking.ncl │ │ │ ├── chaining_dictionary_function_record_dictionary_subtyping.ncl │ │ │ ├── contracts_dont_unify.ncl │ │ │ ├── dictionary_subtyping.ncl │ │ │ ├── dyn_tail_contract_in_typechecking_mode.ncl │ │ │ ├── dynamic_record_field.ncl │ │ │ ├── dynamic_type_error_with_wildcard_annotation.ncl │ │ │ ├── dynamic_type_error_without_wildcard.ncl │ │ │ ├── enum_match_mismatched_branch_types.ncl │ │ │ ├── enum_match_variant_not_covered.ncl │ │ │ ├── enum_row_conflict_extend.ncl │ │ │ ├── enum_row_conflict_poly.ncl │ │ │ ├── enum_row_conflict_remove.ncl │ │ │ ├── enum_row_tags_dont_conflict.ncl │ │ │ ├── enum_variant_not_in_type.ncl │ │ │ ├── field_polymorphic_annot.ncl │ │ │ ├── forall_inside_row_type.ncl │ │ │ ├── higher_rank_coeval.ncl │ │ │ ├── higher_rank_eval.ncl │ │ │ ├── include_annot_mismatch.ncl │ │ │ ├── include_contract_annot.ncl │ │ │ ├── include_instantiated_dep.ncl │ │ │ ├── include_nonrec_occurrence.ncl │ │ │ ├── include_polymorphic_var.ncl │ │ │ ├── include_record_type_mismatch.ncl │ │ │ ├── let_block_not_rec.ncl │ │ │ ├── let_blocks.ncl │ │ │ ├── let_rec_outer_scope.ncl │ │ │ ├── locally_different_flat_types.ncl │ │ │ ├── mismatch_array_elem_at.ncl │ │ │ ├── mismatch_array_entry.ncl │ │ │ ├── mismatch_array_map.ncl │ │ │ ├── mismatch_array_multiple_entries.ncl │ │ │ ├── mismatch_array_typed_entry.ncl │ │ │ ├── mismatch_contract_type.ncl │ │ │ ├── mismatch_convert_empty_record_to_dynamic_tail.ncl │ │ │ ├── mismatch_convert_static_record_type_to_dynamic_tail.ncl │ │ │ ├── mismatch_dict_dynamic_field.ncl │ │ │ ├── mismatch_enum_case_in_multiple_types.ncl │ │ │ ├── mismatch_enum_match_fun_type.ncl │ │ │ ├── mismatch_enum_poly_nested.ncl │ │ │ ├── mismatch_enum_poly_row_var.ncl │ │ │ ├── mismatch_forall_var_concrete_type.ncl │ │ │ ├── mismatch_forall_variable.ncl │ │ │ ├── mismatch_in_fun_body.ncl │ │ │ ├── mismatch_let_inference.ncl │ │ │ ├── mismatch_rec_record_field.ncl │ │ │ ├── mismatch_rec_record_inference.ncl │ │ │ ├── mismatch_rec_record_rec_field.ncl │ │ │ ├── mismatch_record_dictionary_subtyping.ncl │ │ │ ├── mismatch_record_dyn_field.ncl │ │ │ ├── mismatch_record_field_access.ncl │ │ │ ├── mismatch_record_field_name.ncl │ │ │ ├── mismatch_record_field_type.ncl │ │ │ ├── mismatch_record_poly_field_misused.ncl │ │ │ ├── mismatch_record_poly_fields.ncl │ │ │ ├── mismatch_record_poly_row_var.ncl │ │ │ ├── no_implicit_polymorphism.ncl │ │ │ ├── or_patterns.ncl │ │ │ ├── pattern_array_elem_mismatch.ncl │ │ │ ├── pattern_array_rest_mismatch.ncl │ │ │ ├── pattern_extend_closed.ncl │ │ │ ├── pattern_generalize_closed.ncl │ │ │ ├── pattern_generalize_enum.ncl │ │ │ ├── pattern_matching.ncl │ │ │ ├── pattern_non_bool_guard.ncl │ │ │ ├── pattern_not_an_array.ncl │ │ │ ├── pattern_or_closed_enum.ncl │ │ │ ├── pattern_or_type_mismatch.ncl │ │ │ ├── pattern_rest_mismatch.ncl │ │ │ ├── pattern_unbound_identifier_guard.ncl │ │ │ ├── pattern_variant_arg_mismatch.ncl │ │ │ ├── pattern_variant_arg_mismatch_wildcard.ncl │ │ │ ├── piecewise_signature.ncl │ │ │ ├── primitive_mismatch_bool_number.ncl │ │ │ ├── primitive_mismatch_number_bool.ncl │ │ │ ├── primitive_mismatch_string_number.ncl │ │ │ ├── record-typed-field-path.ncl │ │ │ ├── record_dictionary_subtyping.ncl │ │ │ ├── record_row_conflict_extend.ncl │ │ │ ├── record_row_conflict_poly_shuffled1.ncl │ │ │ ├── record_row_conflict_poly_shuffled2.ncl │ │ │ ├── record_row_conflict_poly_shuffled3.ncl │ │ │ ├── record_row_conflict_remove.ncl │ │ │ ├── record_subtyping.ncl │ │ │ ├── record_subtyping_multiple_components.ncl │ │ │ ├── record_subtyping_with_tail.ncl │ │ │ ├── recursive_let.ncl │ │ │ ├── regression-rrows-unification-loops.ncl │ │ │ ├── row_type_unification_variable_mismatch.ncl │ │ │ ├── shallow_type_inference.ncl │ │ │ ├── shallow_type_inference_strict_mode.ncl │ │ │ ├── strict_mode.ncl │ │ │ ├── strict_mode_import.ncl │ │ │ ├── type_in_term_position.ncl │ │ │ ├── typechecking.ncl │ │ │ ├── unannotated_bindings_type_as_dyn.ncl │ │ │ ├── unbound_variable.ncl │ │ │ ├── unsound_generalization_enum_rows.ncl │ │ │ ├── unsound_generalization_fun.ncl │ │ │ ├── unsound_generalization_monomorphic_id.ncl │ │ │ ├── unsound_generalization_record_rows.ncl │ │ │ ├── unsound_generalization_simple.ncl │ │ │ └── wildcard_apparent_ty_is_dyn.ncl │ ├── main.rs │ ├── pretty.rs │ ├── query.rs │ ├── stdlib_typecheck.rs │ └── typecheck_fail.rs │ └── manual │ └── main.rs ├── default.nix ├── doc └── manual │ ├── cli.md │ ├── contracts.md │ ├── cookbook.md │ ├── correctness.md │ ├── introduction.md │ ├── merging.md │ ├── modular-configurations.md │ ├── package-management.md │ ├── syntax.md │ ├── tutorial.md │ ├── types-vs-contracts.md │ └── typing.md ├── examples ├── README.md ├── arrays │ ├── README.md │ └── arrays.ncl ├── config-gcc │ ├── README.md │ └── config-gcc.ncl ├── fibonacci │ ├── README.md │ └── fibonacci.ncl ├── foreach-pattern │ ├── README.md │ ├── data_users.yml │ ├── foreach-pattern-on-import.ncl │ └── foreach-pattern.ncl ├── imports │ ├── README.md │ ├── data_groups.json │ ├── data_machines.toml │ ├── data_nickel_properties.ncl │ ├── data_users.yml │ └── imports.ncl ├── merge-priorities │ ├── README.md │ ├── main.ncl │ ├── security.ncl │ └── server.ncl ├── merge │ ├── README.md │ ├── main.ncl │ ├── security.ncl │ └── server.ncl ├── polymorphism │ ├── README.md │ └── polymorphism.ncl ├── record-contract │ ├── README.md │ └── record-contract.ncl └── simple-contracts │ ├── README.md │ ├── simple-contract-bool.ncl │ └── simple-contract-div.ncl ├── flake.lock ├── flake.nix ├── flock ├── Cargo.toml └── src │ └── lib.rs ├── git ├── Cargo.toml ├── examples │ └── fetch.rs ├── src │ └── lib.rs └── tests │ └── main.rs ├── lsp ├── README.md ├── lsp-harness │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── jsonrpc.rs │ │ ├── lib.rs │ │ └── output.rs ├── nls │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── benches │ │ └── main.rs │ ├── foo-bar-lsp-log.log │ ├── src │ │ ├── actions.rs │ │ ├── analysis.rs │ │ ├── background.rs │ │ ├── codespan_lsp.rs │ │ ├── command.rs │ │ ├── config.rs │ │ ├── diagnostic.rs │ │ ├── error.rs │ │ ├── field_walker.rs │ │ ├── files.rs │ │ ├── identifier.rs │ │ ├── incomplete.rs │ │ ├── main.rs │ │ ├── position.rs │ │ ├── requests │ │ │ ├── completion.rs │ │ │ ├── formatting.rs │ │ │ ├── goto.rs │ │ │ ├── hover.rs │ │ │ ├── mod.rs │ │ │ ├── rename.rs │ │ │ └── symbols.rs │ │ ├── server.rs │ │ ├── term.rs │ │ ├── trace.rs │ │ ├── usage.rs │ │ └── world.rs │ └── tests │ │ ├── inputs │ │ ├── completion-array.ncl │ │ ├── completion-basic.ncl │ │ ├── completion-dict.ncl │ │ ├── completion-field-disambiguation.ncl │ │ ├── completion-fun-parameter-contract.ncl │ │ ├── completion-incomplete-record-field-nested.ncl │ │ ├── completion-incomplete-record-field.ncl │ │ ├── completion-incomplete-record-value.ncl │ │ ├── completion-incomplete.ncl │ │ ├── completion-inside-enum.ncl │ │ ├── completion-match-typed.ncl │ │ ├── completion-match.ncl │ │ ├── completion-nested.ncl │ │ ├── completion-patterns-rec.ncl │ │ ├── completion-patterns.ncl │ │ ├── diagnostics-array.ncl │ │ ├── diagnostics-basic.ncl │ │ ├── diagnostics-recursion.ncl │ │ ├── diagnostics-typecheck.ncl │ │ ├── diagnostics-undefined-fields.ncl │ │ ├── external_import.json │ │ ├── external_import.yaml │ │ ├── formatting.ncl │ │ ├── goto-basic.ncl │ │ ├── goto-cross-file.ncl │ │ ├── goto-let-block.ncl │ │ ├── goto-let-rec.ncl │ │ ├── goto-multiple.ncl │ │ ├── goto-pattern.ncl │ │ ├── goto-perf.ncl │ │ ├── goto-record.ncl │ │ ├── goto-recursive.ncl │ │ ├── goto-scoping.ncl │ │ ├── hover-basic.ncl │ │ ├── hover-cousin.ncl │ │ ├── hover-double-def.ncl │ │ ├── hover-pattern-typed.ncl │ │ ├── hover-pattern.ncl │ │ ├── hover-stdlib-type.ncl │ │ ├── hover_field_typed_block_regression_1574.ncl │ │ ├── import_external_format.ncl │ │ ├── import_invalidation.ncl │ │ ├── no-crash-on-pretty-print.ncl │ │ ├── offsets.ncl │ │ ├── package-manifest.ncl │ │ ├── rename.ncl │ │ ├── symbols-basic.ncl │ │ └── symbols-recursion.ncl │ │ ├── main.rs │ │ └── snapshots │ │ ├── main__lsp__nls__tests__inputs__completion-array.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-basic.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-dict.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-field-disambiguation.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-fun-parameter-contract.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-incomplete-record-field-nested.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-incomplete-record-field.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-incomplete-record-value.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-incomplete.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-inside-enum.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-match-typed.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-match.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-nested.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-patterns-rec.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__completion-patterns.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__diagnostics-array.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__diagnostics-basic.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__diagnostics-recursion.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__diagnostics-typecheck.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__diagnostics-undefined-fields.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__formatting.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-basic.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-cross-file.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-let-block.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-let-rec.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-multiple.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-pattern.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-perf.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-record.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-recursive.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__goto-scoping.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-basic.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-cousin.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-double-def.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-pattern-typed.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-pattern.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover-stdlib-type.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__hover_field_typed_block_regression_1574.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__import_external_format.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__import_invalidation.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__no-crash-on-pretty-print.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__offsets.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__package-manifest.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__rename.ncl.snap │ │ ├── main__lsp__nls__tests__inputs__symbols-basic.ncl.snap │ │ └── main__lsp__nls__tests__inputs__symbols-recursion.ncl.snap └── vscode-extension │ ├── .vscodeignore │ ├── LICENSE │ ├── README.md │ ├── images │ └── nickel-logo-256.png │ ├── language-configuration.json │ ├── package.json │ ├── src │ ├── extension.ts │ └── toolchain.ts │ ├── syntaxes │ └── nickel.tmLanguage.json │ ├── tsconfig.json │ └── yarn.lock ├── notes ├── error-reporting-lib-choice.md ├── fixing-sealing-and-recursive-records.md ├── intersection-and-union-types.md ├── lossless-ast-parsing.md ├── lsp-semantics.md ├── partial-parsing.md ├── standardization-meeting-07.12.21.md ├── sum-as-dependent-records.md ├── trees-that-grow-proc-macro.md └── typechecking.md ├── package ├── Cargo.toml ├── src │ ├── config.rs │ ├── error.rs │ ├── index │ │ ├── lock.rs │ │ ├── mod.rs │ │ ├── scrape.rs │ │ └── serialize.rs │ ├── lib.rs │ ├── lock.rs │ ├── manifest.rs │ ├── resolve.rs │ ├── snapshot.rs │ └── version.rs └── tests │ ├── git_update.rs │ ├── index.rs │ ├── integration.rs │ ├── integration │ └── inputs │ │ ├── git │ │ ├── branch-leaf │ │ │ ├── Nickel-pkg.ncl │ │ │ └── branch.txt │ │ ├── leaf │ │ │ └── Nickel-pkg.ncl │ │ ├── tag-leaf │ │ │ ├── Nickel-pkg.ncl │ │ │ └── tag.txt │ │ └── with-subdirs │ │ │ ├── Nickel-pkg.ncl │ │ │ ├── leaf-subdir │ │ │ └── Nickel-pkg.ncl │ │ │ └── subdir-with-path-dep │ │ │ └── Nickel-pkg.ncl │ │ ├── index │ │ └── github │ │ │ └── example │ │ │ └── leaf │ │ │ ├── 0.1.0 │ │ │ └── Nickel-pkg.ncl │ │ │ ├── 0.1.1 │ │ │ └── Nickel-pkg.ncl │ │ │ └── 0.2.0 │ │ │ └── Nickel-pkg.ncl │ │ └── path │ │ ├── conflicting-index-deps │ │ └── Nickel-pkg.ncl │ │ ├── different-versions-index-dep │ │ └── Nickel-pkg.ncl │ │ ├── double-path-dep │ │ └── Nickel-pkg.ncl │ │ ├── duplicate-index-path-with-exact │ │ └── Nickel-pkg.ncl │ │ ├── duplicate-index-path │ │ └── Nickel-pkg.ncl │ │ ├── duplicate-lock-name │ │ └── Nickel-pkg.ncl │ │ ├── duplicate-path │ │ └── Nickel-pkg.ncl │ │ ├── git-branch-and-tag-dep │ │ └── Nickel-pkg.ncl │ │ ├── git-path-dep │ │ └── Nickel-pkg.ncl │ │ ├── leaf │ │ └── Nickel-pkg.ncl │ │ ├── path-to-index-dep │ │ └── Nickel-pkg.ncl │ │ ├── single-git-dep │ │ └── Nickel-pkg.ncl │ │ ├── single-index-compat-dep │ │ └── Nickel-pkg.ncl │ │ ├── single-index-dep │ │ └── Nickel-pkg.ncl │ │ └── single-path-dep │ │ └── Nickel-pkg.ncl │ ├── lock_preference.rs │ ├── snapshots │ ├── git_update__no_fetch_if_exact_match.snap │ ├── integration__package__tests__integration__inputs__path__conflicting-index-deps__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__different-versions-index-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__double-path-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__duplicate-index-path-with-exact__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__duplicate-index-path__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__duplicate-lock-name__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__duplicate-path__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__git-branch-and-tag-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__git-path-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__leaf__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__path-to-index-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__single-git-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__single-index-compat-dep__Nickel-pkg.ncl.snap │ ├── integration__package__tests__integration__inputs__path__single-index-dep__Nickel-pkg.ncl.snap │ └── integration__package__tests__integration__inputs__path__single-path-dep__Nickel-pkg.ncl.snap │ ├── up_to_date.rs │ └── util.rs ├── py-nickel ├── Cargo.toml ├── README.md ├── build.rs ├── pyproject.toml └── src │ └── lib.rs ├── rfcs ├── 001-overriding.md ├── 002-merge-types-terms-syntax.md ├── 004-typechecking.md ├── 005-metadata-rework.md ├── 006-package-management.md └── 007-bytecode-interpreter.md ├── scripts └── release.sh ├── shell.nix ├── spec ├── README.md └── type-system │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── flake.lock │ ├── flake.nix │ ├── grammar.ott │ ├── notes │ └── examples.md │ └── rules.ott ├── utils ├── Cargo.toml └── src │ ├── annotated_test.rs │ ├── bench.rs │ ├── lib.rs │ ├── project_root.rs │ └── test_program.rs ├── vector ├── Cargo.toml ├── benches │ ├── array.rs │ ├── rpds_comparison.rs │ └── slice.rs ├── src │ ├── lib.rs │ ├── slice.rs │ └── vector.rs └── tests │ └── arbtest.rs └── wasm-repl ├── Cargo.toml └── src └── lib.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Set the windows stack size to 8MB, because the traversal functions are recursive 2 | # and can use up a substantial amount of stack. 3 | # https://github.com/tweag/nickel/issues/2237 4 | 5 | [target.x86_64-pc-windows-msvc] 6 | rustflags = [ 7 | "-C", "link-arg=/STACK:8000000" 8 | ] 9 | 10 | [target.x86_64-pc-windows-gnu] 11 | rustflags = [ 12 | "-C", "link-arg=-Wl,--stack,8000000" 13 | ] 14 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: github-actions 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | time: '00:00' 9 | timezone: UTC 10 | open-pull-requests-limit: 10 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD013": { 4 | "code_blocks": false, 5 | "tables": false 6 | }, 7 | "MD024": { 8 | "siblings_only": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.watcherExclude": { 3 | "**/target": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /cli/tests/integration/inputs/mixed.json: -------------------------------------------------------------------------------- 1 | { 2 | "extra": { 3 | "subfield": "here", 4 | "json": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/integration/inputs/mixed.ncl: -------------------------------------------------------------------------------- 1 | { 2 | extra.nickel = true, 3 | } 4 | -------------------------------------------------------------------------------- /cli/tests/integration/inputs/mixed.toml: -------------------------------------------------------------------------------- 1 | foo = "hello" 2 | bar = 123 3 | 4 | [extra] 5 | toml = true 6 | -------------------------------------------------------------------------------- /cli/tests/integration/inputs/mixed_contract.ncl: -------------------------------------------------------------------------------- 1 | { 2 | bar | Number, 3 | extra | { 4 | nickel | Bool, 5 | subfield | String, 6 | toml | Bool, 7 | json | Bool, 8 | }, 9 | foo | String, 10 | } 11 | -------------------------------------------------------------------------------- /cli/tests/snapshot/imports/additional_contract1.ncl: -------------------------------------------------------------------------------- 1 | { 2 | foo | Number, 3 | baz | Bool, 4 | .. 5 | } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/imports/additional_contract2.ncl: -------------------------------------------------------------------------------- 1 | { 2 | foo | Number, 3 | bar | String, 4 | .. 5 | } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/imports/package.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = 5 3 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/help.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | # extra_args = ['--', '--help'] 4 | { 5 | input.foo.bar | String, 6 | input.foo.baz | Array Number, 7 | input.defaulted.subfield 8 | | doc "Some documentation" 9 | | default = 2, 10 | 11 | override.first = 1, 12 | override.second = { 13 | subsecond = { 14 | subsubsecond = "a", 15 | other = [], 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/list.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | # extra_args = ['--', 'list'] 4 | { 5 | input.foo.bar | String, 6 | input.foo.baz | Array Number, 7 | input.defaulted.subfield 8 | | doc "Some documentation" 9 | | default = 2, 10 | 11 | override.first = 1, 12 | override.second = { 13 | subsecond = { 14 | subsubsecond = "a", 15 | other = [], 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/sigil_env.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | # extra_args = [ 4 | # '--', 5 | # 'env.pkg=@env:CARGO_PKG_NAME', 6 | # ] 7 | 8 | # We bet that CARGO_PKG_NAME is always set in the test environment by cargo, and 9 | # that it's unlikely to change often, which should fit the bill for this 10 | # snapshot test. 11 | { 12 | env.pkg | String, 13 | } 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/sigil_missing_colon.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['export'] 3 | # extra_args = [ 4 | # '--', 5 | # 'input=@env_missing_value', 6 | # ] 7 | { 8 | input 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/simple_adder.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | # extra_args = ['--', 'input=5'] 4 | { 5 | input | Number, 6 | output = input + 1, 7 | } 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/unknown_sigil_attr.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['export'] 3 | # extra_args = [ 4 | # '--', 5 | # 'input."foo bar".baz=@env/attr:PATH', 6 | # ] 7 | { 8 | input."foo bar".baz, 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/customize-mode/unknown_sigil_expr.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['export'] 3 | # extra_args = [ 4 | # '--', 5 | # 'input."foo bar".baz=@what/attr:value', 6 | # ] 7 | { 8 | input."foo bar".baz, 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/evaluation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['doc', '--stdout', '--format=json'] 3 | { 4 | foo | { x | Dyn, y } 5 | } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/function.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['doc', '--stdout'] 3 | fun x => x 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/record.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['doc', '--stdout'] 3 | { 4 | Hello 5 | | doc "World!" 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/recursive.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['doc', '--stdout'] 3 | 4 | # Regression test for https://github.com/tweag/nickel/issues/1967 (`nickel doc` 5 | # shouldn't overflow the stack on recursive data) 6 | { 7 | Recursive = { 8 | foo | Number, 9 | bar | Recursive | optional 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/recursive_false_positive.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['doc', '--stdout'] 3 | 4 | # Companion test for the `recursive` regression test 5 | # Check that the infinite recursion detection of `nickel doc` doesn't have 6 | # obvious false positive 7 | { 8 | outer = { 9 | mid = { inner | doc "this is inner" }, 10 | z | doc "this is z" = outer.mid, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/docs/types.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['doc', '--stdout'] 3 | { 4 | Hello 5 | : Number 6 | | std.string.Stringable 7 | | doc "World!" 8 | = 5, 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/doctest/fail_unexpected_error.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'all' 2 | # command = ['test'] 3 | { 4 | foo 5 | | doc m%" 6 | ```nickel 7 | foo + "1" 8 | ``` 9 | 10 | ```nickel 11 | foo + "1" 12 | # => 2 13 | ``` 14 | "% 15 | = 1, 16 | 17 | bar 18 | | doc m%" 19 | ```nickel 20 | { foo = 1 } 21 | # => { foo = 2 } 22 | ``` 23 | "% 24 | } 25 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/doctest/record_regression.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'all' 2 | # command = ['test'] 3 | 4 | # Regression test for #2248 5 | let types = { 6 | ServiceKind = [| 'Dns |], 7 | mk_Server | ServiceKind -> { kind } 8 | = fun kind_ => { kind = kind_ }, 9 | } 10 | in 11 | { 12 | MyDnsServer = types.mk_Server 'Dns 13 | } 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/annotated_record_pattern_typecheck_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ( 4 | let { x : Bool } = { x = 5 } in 5 | x 6 | ) : _ 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_at_empty_array.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | std.array.at 0 [] 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_at_out_of_bound.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | std.array.at 2 [1] 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Regression test for https://github.com/tweag/nickel/issues/1021 5 | let Foo = Array Number in %force% (["a"] | Foo) 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_merge_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let foo = [1,2,3] in 4 | foo & [1,2,4] 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_range_reversed_indices.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | std.array.range 1 0 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/array_range_step_negative_step.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | std.array.range_step 0 10 (-1) 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/blame_custom_message_ansi_escaping.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | null | std.FailWith "\x1B[9;33;47mstrike through with background \"and\" \"quotes\"" 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/caller_contract_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | std.array.map std.function.id 'not-an-array 4 | 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/contract_label_propagation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let Contract = 4 | std.contract.custom (fun lbl value => 5 | value 6 | |> std.array.fold_left 7 | (fun acc x => std.contract.check Number lbl x |> match { 'Ok _v => acc, 'Error e => 'Error e }) 8 | 'Ok 9 | ) 10 | in 11 | 12 | [1, 2, "hi"] | Contract 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/contract_with_custom_diagnostic.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let Contract = fun label _value => 4 | label 5 | |> std.contract.label.with_message "main error message" 6 | |> std.contract.label.with_notes [ 7 | "This is the first note", 8 | "This is the second note" 9 | ] 10 | |> std.contract.blame 11 | in 12 | 13 | null | Contract 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_assign_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let {a=x} = {a=1} 4 | in a == 1 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_closed_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let {a} = {a=1, b=2} 4 | in a == 1 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_nonexistent_idents.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ( 4 | let { a, b } = { a = 1, c = 2 } in 5 | a: Number 6 | ): _ 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_repeated_ident.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f = fun { duped, duped, .. } => duped 4 | in f { duped = 1, other = "x" } 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_repeated_ident_typed.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ( 4 | let { a, a, .. } = { a = 1, b = 2 } in 5 | a : Number 6 | ): _ 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_rest_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let {a, ..y} = {a=1, b=2} in 4 | y.a 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_type_mismatch_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | (let { a : Number } = { a = "hi" } in 4 | a) : _ 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_type_mismatch_field_pattern_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | (let { a : Number = b } = { a = "x" } in b) : _ 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_type_mismatch_nested_destructuring_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | (let { a : { b : Number } = { b }} = { a = { b = "no" }} in 4 | b) : _ 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/destructuring_typecontract_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let {a | String} = {a=1} in 4 | a 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/dictionary_contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | { foo = 1, bar = "bar" } | {_: String} 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/enum_forall_constraints_typecheck.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f | forall r. [| ; r |] -> [| 'Foo Number; r |] = fun tag => 4 | if true then 5 | tag 6 | else 7 | 'Foo 1 8 | in 9 | (f ('Foo "hello") : _) 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/enum_forall_parametricity_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f : forall r. [| 'x; r |] -> [| 'y ; r |] = 4 | match { 'x => 'y, _ => 'z } 5 | in f 'x 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/fun_contract_range_nested.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Regression test for https://github.com/tweag/nickel/issues/1021 5 | let Foo = { foo : Number } in %force% (((fun x => { foo = "a" }) | Dyn -> Foo) null) 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/fun_contract_range_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Regression test for https://github.com/tweag/nickel/issues/1021 5 | let Foo = Number -> Number in ((fun x => "a") | Foo) 0 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/function_contract_domain_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Regression test for https://github.com/tweag/nickel/issues/1021 5 | let Foo = Number -> Number in ((fun x => x) | Foo) "a" 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/function_contract_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let r = { f | Number -> Number = fun x => 'not-a-number } in r.f 7 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/include_multiple_composite_path.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let foo = {bar.baz = 1} in 5 | {include foo, foo.qux = 2} 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/include_multiple_list.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let foo = {} in 5 | let bar = {} in 6 | {include [foo, bar, foo]} 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/include_multiple_other_include.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let foo = {} in 5 | {include foo, include foo} 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/include_multiple_with_def.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let foo = {} in 5 | {include foo, foo = {}} 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/interpolate_record_type_field.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let a = "foo" in { "%{a}" : Number } 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/interpolation_non_stringable.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | let data = {foo = 1, bar = "string"} in 5 | "hello, I am %{data}" 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/invalid_contract_expression.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | { foo | Number -> [| 'Foo 5 |] = null } 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/invalid_record_type.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | {a: Number, b = 1; r} 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/let_block_duplicate_identifier.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let 4 | { x, y } = { x = 1, y = 2 }, 5 | x = 3 6 | in 7 | x 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/let_block_not_rec.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let 4 | a = 2, 5 | b = a 6 | in 7 | b 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/mismatched_row_record_pattern_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ( 4 | let { x : { a : Number } = { a : String } } = { x = { a = true } } 5 | in a 6 | ) : _ 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/nested_annotated_record_pattern_typecheck_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ( 4 | let { x = { a : Number }} = { x = { a = "" }} in 5 | x 6 | ) : _ 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/no_internals_when_currying.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let add : Number -> Number -> Number = fun x y => x + y in 4 | add 1 - 1 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/non_exhaustive_match.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Ensure that a non-exhaustive pattern matching applied to a non-matching 5 | # argument produces a proper error message. 6 | let x = if true then 'a else 'b in 7 | let f = match { 8 | 'c => "hello", 9 | 'd => "adios", 10 | } 11 | in 12 | 13 | f x 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/query_non_record.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = [ 'query', '--field', 'value' ] 3 | 1 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_access.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ({ "%{(if false then "foo" else "bar")}" = false, bar = true }).foo 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_access_suggestion.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ({ 4 | some_field_name = "some value", 5 | another_field_name = "another value", 6 | }).some_fild_nam 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_destructuring_duplicate_ident.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f = fun { one, two, one } => { one, two } 4 | in f { one = 1, two = "2" } 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_forall_constraints_contract.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f | forall r. { ; r } -> { x: Number; r } = fun r => %record/insert% "x" r 1 in f { x = 0 } 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_forall_constraints_typecheck.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f | forall r. { ; r } -> { x: Number; r } = fun r => %record/insert% "x" r 1 in (f { x = 0 } : _) 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_forall_parametricity_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let f : forall r. { x : String } -> { x : String; r } = 4 | fun x => x 5 | in f { x = 1 } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/record_type_repeated_field.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | ({foo.bar.baz = "a"} : {foo : String, foo : Number}) 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/serialization_number_out_of_range.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['export'] 3 | 4 | 1e400 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/simple_contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 1 | String 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/spanned_toml.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let test = import "../../imports/package.toml" in 4 | test | { 5 | package.name | String, 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/string_delimiter_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | m%"Hello"%% 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/subcontract_type_path_underline.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let val | Array (Array {foo: Dyn -> Number }) = [ 4 | [], 5 | [{ foo = fun x => "string" }] 6 | ] in 7 | std.array.at 1 val 8 | |> std.array.at 0 9 | |> (fun r => r.foo null) 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/trace_not_saturated.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | %trace% "too few arguments" 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/typecheck_strict_mode.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['typecheck', '--strict-typechecking'] 3 | 1 + "foo" 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/typed_field_without_annotation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | { 4 | foo : Number 5 | | doc "foo", 6 | bar : String, 7 | } 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/typedcheck_strict_mode_is_strict.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['typecheck', '--strict-typechecking'] 3 | let x = (1 + 1) in (x + 1 : Number) 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/unification_variable_aliasing.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | 4 | # Regression test for #1312 5 | let f : forall a. (forall r. { bla : Bool, blo : a, ble : a; r } -> a) = fun r => if r.bla then (r.blo + 1) else r.ble 6 | in (f { bla = true, blo = 1, ble = 2, blip = 'blip } : Number) 7 | 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/validator_custom_error.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let Is42 = std.contract.from_validator (fun value => 4 | if value == 42 then 5 | 'Ok 6 | else 7 | 'Error { 8 | message = "Value must be 42", 9 | notes = ["This is a first custom note", "This is a second custom note"] 10 | } 11 | ) in 12 | 43 | Is42 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/errors/value_contract_violation.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | { foo | std.FailWith "no reason" = 1 }.foo 4 | 5 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/eval/escaping.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['eval'] 3 | "a\"bcd\"" 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/eval/fail_additional_contract.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval', '--apply-contract', 'imports/additional_contract1.ncl'] 3 | { 4 | foo = 1, 5 | bar = "hello, world!", 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/eval/fail_additional_two_contracts1.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval', '--apply-contract', 'imports/additional_contract1.ncl', '--apply-contract', 'imports/additional_contract2.ncl'] 3 | { 4 | foo = 1, 5 | bar = "hello, world!", 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/eval/fail_additional_two_contracts2.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval', '--apply-contract', 'imports/additional_contract1.ncl', '--apply-contract', 'imports/additional_contract2.ncl'] 3 | { 4 | foo = 1, 5 | baz = false, 6 | } 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/eval/records.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['eval'] 3 | { a = true, b | Number = 6 * 7 } 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/export/nested_record.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | { 4 | a_num = 1, 5 | some_str = "this is a string", 6 | booooool = false, 7 | an_array = [ 2, "other string", true, ["nested", "array"], { nested = "record" }], 8 | a_record = { 9 | even = { 10 | more = { 11 | nested = "record" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/export/not_exported_undefined.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['export'] 3 | { 4 | foo | not_exported, 5 | bar = 42, 6 | } -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/export/trace.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'all' 2 | # command = ['export'] 3 | std.trace "Hello, world!" true 4 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/package/invalid-git-dep.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['package', 'lock'] 3 | # is_package_manifest = true 4 | { 5 | name = "package", 6 | version = "0.1.0", 7 | minimal_nickel_version = "1.10.0", 8 | authors = [], 9 | dependencies = { 10 | git = 'Git { url = "http://example.com", ref = 'Commit "invalid hex string" } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/package/invalid-git-url.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['package', 'lock'] 3 | # is_package_manifest = true 4 | { 5 | name = "package", 6 | version = "0.1.0", 7 | minimal_nickel_version = "1.10.0", 8 | authors = [], 9 | dependencies = { 10 | git = 'Git { url = "https://does not parse" } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/package/invalid-version.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['package', 'lock'] 3 | # is_package_manifest = true 4 | { 5 | name = "package", 6 | version = "0.1", 7 | minimal_nickel_version = "1.10.0", 8 | authors = [], 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/package/missing-field.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['package', 'lock'] 3 | # is_package_manifest = true 4 | { 5 | name = "package", 6 | version = "0.1.0", 7 | minimal_nickel_version = "1.10.0", 8 | } 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/field_escaping.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | { 4 | "this needs \\\"escaping\"\nvery much" = true 5 | } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/id_quoting.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | { 4 | "a field" = 1, 5 | "Number" = 1, 6 | bar = 'if, 7 | foo = bar |> match { 'if => 1, '"has space" => 0 }, 8 | has_space = '"hi there", 9 | annotated | [| 'if, 'then, '"has space" |], 10 | }."a field" 11 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/let_annotations.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | let foo : String | String | std.string.NonEmpty = "some very long string to blow past the 80 character line length limit" in foo -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/let_block.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | let rec 4 | fib = fun n => 5 | if n == 0 || n == 1 then 6 | 1 7 | else 8 | fib (n - 1) + fib (n - 2), 9 | fib2 = fun n => fib (fib n) 10 | in fib2 3 11 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/let_block_with_pat.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | let 4 | a = 1, 5 | d@{ b, c } = { b = "b", c = 2 }, 6 | in a + d.c 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/let_rec.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | let rec fib = fun n => 4 | if n == 0 || n == 1 then 5 | 1 6 | else 7 | fib (n - 1) + fib (n - 2) 8 | in fib 5 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/pretty/simple_record.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = ['pprint-ast'] 3 | { 4 | aaaaa | Number | default = 1, 5 | bbbbb : String | force = "some long string that goes past the 80 character line limit for pretty printing", 6 | ccccc : { x : Number, y: Number } = { x = 999.8979, y = 500 }, 7 | ddddd | Array std.string.NonEmpty = ["a", "list", "of", "non", "empty", "strings"], 8 | } 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/query/query_included_field.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stdout' 2 | # command = [ 'query', '--field', 'x.y', '--format', 'json' ] 3 | let y = 1 in 4 | let x = { include y | doc "Doc of y" | default } in 5 | { include x } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/warnings/naked_contract.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let C = fun label value => value in 4 | [ 5 | 1 | C, 6 | [1, 2] | Array C 7 | ] 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/warnings/naked_contract_parametrized.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let C = fun arg label value => value in 4 | [ 5 | 1 | C "hi", 6 | [1, 2] | Array (C "hi") 7 | ] 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/inputs/warnings/supressed.ncl: -------------------------------------------------------------------------------- 1 | # capture = 'stderr' 2 | # command = ['eval'] 3 | let C = fun label value => value in 4 | [ 5 | 1 | C, 6 | 2 | C, 7 | 3 | C, 8 | 4 | C, 9 | 5 | C, 10 | 6 | C, 11 | 7 | C, 12 | 8 | C, 13 | 9 | C, 14 | 10 | C, 15 | 11 | C, 16 | ] 17 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stderr_function.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: no documentation found 6 | ┌─ [INPUTS_PATH]/docs/function.ncl:3:1 7 | │ 8 | 3 │ fun x => x 9 | │ ^^^^^^^^^^ 10 | │ 11 | = documentation can only be collected from a record. 12 | 13 | 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stdout_evaluation.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | {"foo":{"fields":null,"type":null,"contracts":["{ x | Dyn, y, }"],"documentation":null}} 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stdout_record.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | # `Hello` 6 | 7 | World\! 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stdout_recursive.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | # `Recursive` 6 | 7 | ## `bar` 8 | 9 | - `bar | Recursive` 10 | 11 | ## `foo` 12 | 13 | - `foo | Number` 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stdout_recursive_false_positive.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | # `outer` 6 | 7 | ## `mid` 8 | 9 | ### `inner` 10 | 11 | this is inner 12 | 13 | ## `z` 14 | 15 | this is z 16 | 17 | ### `inner` 18 | 19 | this is inner 20 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__doc_stdout_types.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | # `Hello` 6 | 7 | - `Hello : Number` 8 | - `Hello | std.string.Stringable` 9 | 10 | World\! 11 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_destructuring_assign_fail.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: unbound identifier `a` 6 | ┌─ [INPUTS_PATH]/errors/destructuring_assign_fail.ncl:4:4 7 | │ 8 | 4 │ in a == 1 9 | │ ^ this identifier is unbound 10 | 11 | 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_destructuring_closed_fail.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: destructuring failed 6 | ┌─ [INPUTS_PATH]/errors/destructuring_closed_fail.ncl:3:5 7 | │ 8 | 3 │ let {a} = {a=1, b=2} 9 | │ ^^^ ---------- this value failed to match 10 | │ │ 11 | │ this pattern 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_destructuring_rest_fail.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: missing field `a` 6 | ┌─ [INPUTS_PATH]/errors/destructuring_rest_fail.ncl:4:1 7 | │ 8 | 4 │ y.a 9 | │ ^^^ this requires the field `a` to exist 10 | 11 | 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_destructuring_typecontract_fail.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: contract broken by a value 6 | ┌─ [INPUTS_PATH]/errors/destructuring_typecontract_fail.ncl:3:23 7 | │ 8 | 3 │ let {a | String} = {a=1} in 9 | │ ------ ^ applied to this expression 10 | │ │ 11 | │ expected type 12 | 13 | 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_let_block_duplicate_identifier.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: duplicated binding `x` in let block 6 | ┌─ [INPUTS_PATH]/errors/let_block_duplicate_identifier.ncl:5:3 7 | │ 8 | 4 │ { x, y } = { x = 1, y = 2 }, 9 | │ - previous binding here 10 | 5 │ x = 3 11 | │ ^ duplicated binding here 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_let_block_not_rec.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: unbound identifier `a` 6 | ┌─ [INPUTS_PATH]/errors/let_block_not_rec.ncl:5:7 7 | │ 8 | 5 │ b = a 9 | │ ^ this identifier is unbound 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_record_access.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: record/insert: tried to extend a record with the field bar, but it already exists 6 | 7 | 8 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_simple_contract_fail.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: contract broken by a value 6 | ┌─ [INPUTS_PATH]/errors/simple_contract_fail.ncl:3:1 7 | │ 8 | 3 │ 1 | String 9 | │ ^ ------ expected type 10 | │ │ 11 | │ applied to this expression 12 | 13 | 14 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_spanned_toml.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: contract broken by the value of `name` 6 | ┌─ [INPUTS_PATH]/errors/spanned_toml.ncl:5:18 7 | │ 8 | 5 │ package.name | String, 9 | │ ------ expected type 10 | │ 11 | ┌─ [IMPORTS_PATH]/package.toml:2:8 12 | │ 13 | 2 │ name = 5 14 | │ ^ applied to this expression 15 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stderr_trace_not_saturated.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | std.trace: too few arguments 6 | error: not enough arguments 7 | ┌─ [INPUTS_PATH]/errors/trace_not_saturated.ncl:3:1 8 | │ 9 | 3 │ %trace% "too few arguments" 10 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace expects 2 arguments, but not enough were provided 11 | 12 | 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stdout_escaping.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | "a\"bcd\"" 6 | 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stdout_let_block_rec.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | 4 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__eval_stdout_records.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { a = true, b | Number = 42, } 6 | 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_not_an_input.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: invalid assignment: `override.first` isn't an input 6 | = `override.first` already has a value and thus can't be assigned without `--override`. 7 | = If you really want to override this field, please use `--override 'override.first="test"'` instead. 8 | 9 | 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_trace.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | std.trace: Hello, world! 6 | 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_unknown_field_path.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: invalid query: unknown field `unknown.field.path` 6 | = `unknown.field.path` doesn't refer to a record field accessible from the root of the configuration. 7 | = Use `nickel [OPTIONS] -- list` to show a list of available fields. 8 | 9 | 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_unknown_override.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: invalid override: unknown field `unknown.field.path` 6 | = `unknown.field.path` doesn't refer to a record field accessible from the root of the configuration. 7 | = Use `nickel [OPTIONS] -- list` to show a list of available fields. 8 | 9 | 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_unknown_sigil_attr.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: unknown sigil attribute `attr` 6 | ┌─ :1:6 7 | │ 8 | 1 │ @env/attr:PATH 9 | │ ^^^^ unknown attribute for sigil selector `env` 10 | │ 11 | = No attributes are available for sigil selector `env`. Use the selector directly as in `@env:` 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_unknown_sigil_expr.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: unknown sigil selector `what` 6 | ┌─ :1:2 7 | │ 8 | 1 │ @what/attr:value 9 | │ ^^^^ 10 | │ 11 | = Available selectors are currently: `env` 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stderr_unkonwn_field_path.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: invalid query: unknown field `unkonwn.field.path` 6 | = `unkonwn.field.path` doesn't refer to record field accessible from the root of the configuration. 7 | 8 | 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stdout_not_exported_undefined.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { 6 | "bar": 42 7 | } 8 | 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stdout_show.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stdout_sigil_env.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { 6 | "env": { 7 | "pkg": "nickel-lang-cli" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stdout_simple_adder.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { 6 | "input": 5, 7 | "output": 6 8 | } 9 | 10 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__export_stdout_trace.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | true 6 | 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__package_stderr_invalid-git-url.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: packaging error 6 | = URL "https://does not parse" can not be parsed as valid URL 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_field_escaping.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { "this needs \\\"escaping\"\nvery much" = true, } 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_id_quoting.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { 6 | "Number" = 1, 7 | "a field" = 1, 8 | annotated | [| 'if, 'then, '"has space" |], 9 | bar = 'if, 10 | foo = (match { 'if => 1, '"has space" => 0, }) bar, 11 | has_space = '"hi there", 12 | }."a field" 13 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_let_annotations.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | let foo 6 | : String 7 | | String 8 | | std.string.NonEmpty 9 | = "some very long string to blow past the 80 character line length limit" 10 | in 11 | foo 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_let_block.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | let rec fib 6 | = fun n => if (n == 0) || (n == 1) then 1 else (fib (n - 1)) + (fib (n - 2)), 7 | fib2 8 | = fun n => fib (fib n) 9 | in 10 | fib2 3 11 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_let_block_with_pat.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | let a = 1, d @ { b, c, } = { b = "b", c = 2, } in a + d.c 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__pprint-ast_stdout_let_rec.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | let rec fib 6 | = fun n => if (n == 0) || (n == 1) then 1 else (fib (n - 1)) + (fib (n - 2)) 7 | in 8 | fib 5 9 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__query_stderr_query_non_record.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: tried to query field of a non-record 6 | ┌─ [INPUTS_PATH]/errors/query_non_record.ncl:3:1 7 | │ 8 | 3 │ 1 9 | │ ^ tried to query field `value`, but the expression has type Number 10 | 11 | 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__query_stdout_query_included_field.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | { 6 | "doc": "Doc of y", 7 | "optional": false, 8 | "not_exported": false, 9 | "priority": "default", 10 | "value": "1" 11 | } 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__query_stdout_show.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stderr_fail_expected_error.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | 4 failures 6 | error: tests failed 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stderr_fail_unexpected_error.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | 3 failures 6 | error: tests failed 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stderr_fail_wrong_output.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | 4 failures 6 | error: tests failed 7 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stderr_pass.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stderr_record_regression.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stdout_pass.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | testing foo/0...ok 6 | testing foo/1...ok 7 | testing foo/2...ok 8 | testing foo/3...ok 9 | testing foo/4...ok 10 | testing bar/0...ok 11 | testing bar/1...ok 12 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__test_stdout_record_regression.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: out 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /cli/tests/snapshot/snapshots/snapshot__typecheck_stderr_typecheck_strict_mode.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: cli/tests/snapshot/main.rs 3 | expression: err 4 | --- 5 | error: incompatible types 6 | ┌─ [INPUTS_PATH]/errors/typecheck_strict_mode.ncl:3:5 7 | │ 8 | 3 │ 1 + "foo" 9 | │ ^^^^^ this expression 10 | │ 11 | = Expected an expression of type `Number` 12 | = Found an expression of type `String` 13 | = These types are not compatible 14 | -------------------------------------------------------------------------------- /core/benches/arrays/map.ncl: -------------------------------------------------------------------------------- 1 | let f = { f = fun x => if (x == 0) then 0 else f (x - 1) }.f in 2 | { 3 | run = fun n => 4 | std.array.map f (std.array.generate std.function.id n) 5 | } 6 | -------------------------------------------------------------------------------- /core/benches/arrays/pipe.ncl: -------------------------------------------------------------------------------- 1 | { 2 | run = fun n => 3 | std.array.generate (fun n => n * n) n 4 | |> std.array.filter (fun n => n % 2 == 0) 5 | |> std.array.map (fun n => [n, n + 1]) 6 | |> std.array.flatten 7 | |> std.array.partition (fun n => n % 2 == 0) 8 | } 9 | -------------------------------------------------------------------------------- /core/benches/arrays/sort.ncl: -------------------------------------------------------------------------------- 1 | let ascending = fun x y => 2 | if x < y then 3 | 'Lesser 4 | else if x == y then 5 | 'Equal 6 | else 7 | 'Greater 8 | in 9 | 10 | { run = std.array.sort ascending } 11 | -------------------------------------------------------------------------------- /core/benches/arrays/sum.ncl: -------------------------------------------------------------------------------- 1 | let rec sum | Array Number -> Number = match { 2 | [] => 0, 3 | [x, ..xs] => x + sum xs, 4 | } 5 | in 6 | { 7 | run = fun n => std.array.generate (fun x => x + 1) n |> sum 8 | } 9 | -------------------------------------------------------------------------------- /core/benches/functions.rs: -------------------------------------------------------------------------------- 1 | use criterion::criterion_main; 2 | use nickel_lang_utils::{bench::criterion_config, ncl_bench_group}; 3 | 4 | ncl_bench_group! { 5 | name = benches; 6 | config = criterion_config(); 7 | { 8 | name = "church 3", 9 | path = "functions/church", 10 | args = (3), 11 | } 12 | } 13 | criterion_main!(benches); 14 | -------------------------------------------------------------------------------- /core/benches/mantis/deploy-example.ncl: -------------------------------------------------------------------------------- 1 | (import "deploy.ncl") { 2 | namespace = "mantis-staging", 3 | job = "miner", 4 | role = 'miner, 5 | } 6 | -------------------------------------------------------------------------------- /core/benches/mantis/run.ncl: -------------------------------------------------------------------------------- 1 | { 2 | run = import "deploy.ncl", 3 | serialize.run = fun args => 4 | ( 5 | std.serialize 'Json (run args) 6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /core/benches/numeric/fibonacci.ncl: -------------------------------------------------------------------------------- 1 | { 2 | run = 3 | let rec f = fun n => 4 | if n == 0 || n == 1 then 5 | 1 6 | else 7 | f (n - 1) + f (n - 2) 8 | in f 9 | } 10 | -------------------------------------------------------------------------------- /core/benches/numeric/reduce.ncl: -------------------------------------------------------------------------------- 1 | { 2 | sum = { 3 | run = fun n => 4 | let numbers = std.array.generate std.function.id n in 5 | std.array.fold_left (fun acc x => acc + x) 0 numbers 6 | }, 7 | 8 | product = { 9 | run = fun n => 10 | let numbers = std.array.generate std.function.id n in 11 | std.array.fold_left (fun acc x => acc * x) 1 numbers 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /core/benches/records/countLetters.ncl: -------------------------------------------------------------------------------- 1 | { 2 | run = fun s => 3 | let update_dict = fun dict char => 4 | if std.record.has_field char dict then 5 | std.record.update char (dict."%{char}" + 1) dict 6 | else 7 | std.record.insert "%{char}" 1 dict 8 | in 9 | std.array.fold_left update_dict {} (std.string.characters s) 10 | } 11 | -------------------------------------------------------------------------------- /core/benches/serialization.rs: -------------------------------------------------------------------------------- 1 | use criterion::criterion_main; 2 | use nickel_lang_utils::{bench::criterion_config, ncl_bench_group}; 3 | 4 | ncl_bench_group! { 5 | name = benches; 6 | config = criterion_config(); 7 | { 8 | name = "round_trip", 9 | path = "serialization/main", 10 | subtest = "input", 11 | } 12 | } 13 | criterion_main!(benches); 14 | -------------------------------------------------------------------------------- /core/benches/serialization/main.ncl: -------------------------------------------------------------------------------- 1 | { 2 | input.run = ( 3 | std.serialize 'Json (import "input.json") 4 | ) 5 | } 6 | -------------------------------------------------------------------------------- /core/benches/typecheck-nixpkgs-lib.rs: -------------------------------------------------------------------------------- 1 | use criterion::criterion_main; 2 | use nickel_lang_utils::{bench::criterion_config, bench::EvalMode, ncl_bench_group}; 3 | 4 | ncl_bench_group! { 5 | name = benches; 6 | config = criterion_config(); 7 | { 8 | name = "nixpkgs lists", 9 | path = "nixpkgs/lists", 10 | eval_mode = EvalMode::TypeCheck, 11 | } 12 | } 13 | criterion_main!(benches); 14 | -------------------------------------------------------------------------------- /core/src/bytecode/mod.rs: -------------------------------------------------------------------------------- 1 | //! Experimental bytecode compiler, virtual machine, and their intermediate representations. 2 | //! 3 | //! This implementation is under construction; it's currently not usable and it's not available by 4 | //! default in mainline Nickel. 5 | 6 | pub mod ast; 7 | pub mod pretty; 8 | -------------------------------------------------------------------------------- /core/src/nix_ffi/cpp/nix.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "rust/cxx.h" 5 | 6 | #include "nickel-lang-core/src/nix_ffi/mod.rs.h" 7 | 8 | using namespace nix; 9 | 10 | rust::String eval_to_json(const rust::Str nix_code); 11 | -------------------------------------------------------------------------------- /core/src/nix_ffi/mod.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge] 2 | mod internal { 3 | unsafe extern "C++" { 4 | include!("nickel-lang-core/src/nix_ffi/cpp/nix.hh"); 5 | fn eval_to_json(nix_code: &str) -> Result; 6 | } 7 | } 8 | 9 | pub use internal::*; 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/deep_seq_enum.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 6 | # Check that deep_seq correctly evaluates the content of an enum variant 7 | %deep_seq% ('Foo 5 | [| 'Foo String |]) null 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/deep_seq_enum2.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | 6 | # Check that deep_seq correctly deeply evaluates the content of an enum variant 7 | %deep_seq% ('Foo { bar = 5 + "a" }) null 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/enum_contract_propagation.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::BlameError' 6 | 7 | # Check that contracts in enums are evaluated 8 | 'Foo { bar = "hi" } | [| 'Foo { bar | Number } |] 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/enum_primops.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | [ 5 | %enum/get_arg% ('Left (1+1)) == 2, 6 | !(%enum/is_variant% 'Right), 7 | %enum/is_variant% ('Right 1), 8 | %enum/get_tag% 'Right == 'Right, 9 | %enum/get_tag% ('Right "stuff") == 'Right, 10 | ] 11 | |> std.test.assert_all 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/enum_wildcard_substitution.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 6 | # Check that wildcards inside enum variants are substituted for their inferred type 7 | let f : [| 'Foo _ |] -> Number = match { 'Foo n => n } in f ('Foo "a") 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/force_enum.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 6 | # Check that force correctly evaluates the content of an enum variant 7 | %force% ('Foo 5 | [| 'Foo String |]) 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/adts/force_enum2.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | 6 | # Check that force correctly deeply evaluates the content of an enum variant 7 | %force% ('Foo { bar = 5 + "a" }) 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/elem_at_empty_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | %array/at% [] 0 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/elem_at_index_out_of_bounds.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | %array/at% [true, false, true] 3 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/elem_at_negative_index.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | %array/at% [1, 2, 3] (-1) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/elem_at_non_array_arg.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | %array/at% {} 0 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/elem_at_non_int_index.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | %array/at% [1, 2, 3] 0.5 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/slice_empty_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | %array/slice% 1 1 [] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/slice_non_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | %array/slice% 0 1 {} 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/stdlib_at_non_array_arg_raises_blame.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | std.array.at 0 {} -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/stdlib_at_non_number_arg_raises_blame.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | std.array.at "a" [] -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/stdlib_drop_first_non_array_arg.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | std.array.drop_first 2 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/arrays/stdlib_first_non_array_arg.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | std.array.first false 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/and_bool_contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let throw | (fun l _v => %blame% l) = null in 6 | false || true && throw 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/and_number_bool.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | 0 && true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/any_of_basic_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | true | std.contract.any_of [Number, String] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/any_of_empty.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | null | std.contract.any_of [] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/any_of_record_delayed_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::BlameError' 6 | { foo = 1, bar = 2, qux = true} | std.contract.any_of [ 7 | { foo | Number, bar | Number }, 8 | { foo | String, bar | Number, qux | Bool } 9 | ] 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/any_of_record_immediate_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | { foo = 1, bar = 2, qux } | std.contract.any_of [ 6 | { foo | Number, bar | String }, 7 | { foo | String, bar | Number, baz | Bool } 8 | ] 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/array_contract_bad_element.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | %force% ([1, "a"] | Array Number) 0 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/array_contract_fn_is_not_an_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | (fun x => x) | Array Dyn -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/array_contract_num_is_not_an_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 1 | Array Dyn -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/basic_custom_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let 6 | AlwaysTrue = fun l t => 7 | let boolT | Bool = t 8 | in if boolT then boolT else %blame% l 9 | in (false | AlwaysTrue) 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/contract_applies_to_default_value.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | { val | default | Number = true }.val 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/contracts_dont_capture_type_vars.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'a' 8 | forall a b. b -> Array b -> { _ | a } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_generic_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let AlwaysFail = std.contract.custom (fun label _ => std.contract.blame label) in 6 | 3 | AlwaysFail 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_generic_immediate_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let AlwaysFail = std.contract.custom (fun _ _ => 'Error {}) in 6 | 3 | AlwaysFail 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_generic_succeed.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let AlwaysSucceed = std.contract.custom (fun _ value => 'Ok value) in 3 | 4 | ( 5 | 3 6 | | AlwaysSucceed 7 | ) == 3 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_predicate_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let AlwaysFail = std.contract.from_predicate (fun _ => false) in 6 | 3 | AlwaysFail 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_predicate_succeed.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let AlwaysSucceed = std.contract.from_predicate (fun _ => true) in 3 | (3 | AlwaysSucceed) == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_validator_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let AlwaysFail = std.contract.from_validator (fun _ => 'Error {}) in 6 | 3 | AlwaysFail 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/custom_validator_succeed.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let AlwaysSucceed = std.contract.from_validator (fun _ => 'Ok) in 3 | (3 | AlwaysSucceed) == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/dedup_multiple.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | # Regression test for https://github.com/tweag/nickel/issues/2189 4 | let Linktype = { 5 | source, 6 | target 7 | | Dyn 8 | | { file | default = source } 9 | } 10 | in 11 | ( 12 | { 13 | source = "", 14 | target | Dyn | Dyn = {}, 15 | } | Linktype 16 | ) == { 17 | source = "", 18 | target.file = "", 19 | } 20 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/dictionary_contract_propagates_through_merge.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | %force% (({ foo } | { _ | Number }) & { foo = "string" }) true -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/div_by_zero.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | 1 + 1 / (1 - 1) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/enum_contract_empty_enum.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 'foo | [| |] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/enum_contract_missing_variant.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 'far | [|'foo, 'bar |] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/enum_contract_non_enum_value.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 123 | [| 'foo, 'bar |] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/enum_variant_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | %force% ('Foo 5 | [| 'Foo String, 'Bar Number, 'Barg |]) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/equating_fn_match.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IncomparableValues' 5 | let g = fun x => x + 1 in 6 | let h = match { 0 => 0 } in 7 | g == h 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/equating_functions.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IncomparableValues' 5 | let g = fun x => x + 1 in 6 | g == g 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/include_recursive_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x = 1 in 6 | ({ 7 | include x | Contract, 8 | Contract = Dyn, 9 | } & { 10 | Contract | force = std.FailWith "", 11 | }).x 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/let_order.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | let ConstantTrue = fun _label value => std.seq value true in 4 | [ 5 | let foo | ConstantTrue | Bool = "not a bool" in 6 | foo, 7 | 8 | { 9 | foo 10 | | ConstantTrue 11 | | Bool 12 | = "still not a bool" 13 | }.foo 14 | ] 15 | |> std.test.assert_all 16 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/not_any_of_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | "a" | std.contract.not (std.contract.any_of [Number, String]) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/not_basic_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | [] | std.contract.not (Array Number) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/not_record_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | { foo = 1, bar = 2} | std.contract.not {foo, bar} 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_bad_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | (forall r. { x : Number; r } -> { x : Number; r }) 6 | -> { x : String, y : Number } -> { x : Number, y: Number } = 7 | fun g r => g r 8 | in (f (fun r => r) { x = "", y = 1 }).x 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_empty_record.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | forall a. { foo: Number; a } -> Number = fun r => r.foo 6 | in f { } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_higher_order_fn.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | (forall r. { x : Number; r } -> { ; r }) 6 | -> { x : Number, y : Number } -> { y : Number } = 7 | fun g r => g r 8 | in f (fun r => r) { x = 1, y = 2 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_map_sealed_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let f | forall r. { a : Number; r } -> { a : String; r } = 6 | fun r => %record/map% r (fun x => %to_string% x) 7 | in f { a = 1, b = 2 } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_merge_sealed_tail_lhs.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let f | forall r. { a : Number; r } -> { a : Number; r } = 6 | fun r => r & { a | force = 0 } 7 | in f { a | default = 100, b = 1 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_merge_sealed_tail_rhs.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let f | forall r. { a : Number; r } -> { a : Number; r } = 6 | fun r => { a | force = 0 } & r 7 | in f { a | default = 100, b = 1 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | forall r. { x : Number, y : Number; r } -> { x : Number, y : Number; r} = 6 | fun r => r 7 | in f { x = 1 } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_return_val_without_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | forall r. { foo : Number; r } -> { foo : Number; r } = 6 | fun r => { foo = 1 } 7 | in f { foo = 1, other = 2 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_return_val_wrong_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | forall r r'. { a : Number; r } 6 | -> { a: Number; r' } 7 | -> { a: Number; r } = 8 | fun r r' => r' 9 | in f { a = 1, b = "yes" } { a = 1, b = "no" } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_sealed_tail_dynamic_access.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let f | forall a. { ; a } -> { ; a } = fun x => %seq% x."a" x 6 | in f { a = 1 } 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_sealed_tail_remove_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let remove_x | forall r. { ; r } -> { ; r } = fun r => %record/remove% "x" r in 6 | remove_x { x = 1 } 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/poly_record_contract_sealed_tail_static_access.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::IllegalPolymorphicTailAccess' 5 | let f | forall a. { ; a } -> { ; a } = fun x => %seq% x.a 6 | in f { a = 1 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/polymorphic_function_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let id | forall a. a -> a = fun x => false 6 | in id false && false -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_bad_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, b: String } = { a = 1, s = 2 } 6 | in %deep_seq% x x -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_constraint.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f | forall r. { ; r } -> { x : { y : Number ; r } ; r } 6 | = fun r => %record/insert% "x" r (%record/insert% "y" r 1) in 7 | f { y = 3 } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_empty_record.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | { a = 1 } | {} 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_extra_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, s : String } = { a = 1, s = "a", extra = 1 } 6 | in %deep_seq% x x 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, s: String } = { s = "yes" } 6 | in %deep_seq% x x 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_nested_extra_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, b : { foo : Bool }} = { a = 1, b = { foo = true, extra = 0 }} 6 | in %deep_seq% x x -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_nested_failure.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, b : { foo: Bool }} = { a = 1, b = { foo = 2 }} 6 | in %deep_seq% x x -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/record_contract_nested_missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let x | { a : Number, b : { foo : Bool }} = { a = 1, b = {}} 6 | in %deep_seq% x x -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/regression_panic_function_contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let foo | (Dyn -> Dyn) -> Dyn = fun x y => x y in foo null null 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/sequence.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 6 | 3 | std.contract.Sequence [ Number, std.contract.from_predicate (fun x => x < 5), std.contract.from_predicate (fun x => x > 5) ] 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/simplify_doesnt_remove_fields.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | # Regression test for issue #2014 "Record row polymorphism can be destructive" 4 | # (https://github.com/tweag/nickel/issues/2014) 5 | let f : forall tail. { a : Number; tail } -> { a : Number; tail } 6 | = fun o => o 7 | in 8 | f { a = 1, b = ".." } == { a = 1, b = ".." } 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/type_annot_inline.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | ((fun x => x) : Number -> Number) "a" 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/type_annot_let.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let f : Number -> Number = fun x => x in 6 | f "a" 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/contracts/unsound_dedup_dict_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::BlameError' 6 | 7 | # Regression test for https://github.com/tweag/nickel/issues/1700 8 | let False = std.contract.from_predicate (fun x => false) in 9 | ({ bli = {foo = 1} } 10 | | { _| {..} }) 11 | | { _| False } 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/comparison_ge_string_string.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | "a" > "b" -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/comparison_geq_string_string.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | "a" >= "b" -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/comparison_le_number_bool.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | 1 < 2 < 3 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/comparison_le_string_number.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | "a" < 2 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/comparison_leq_bool_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | true <= [] 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/curried_dot.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | let record = {foo = 1, bar = { baz = 2 }} in 5 | let field = "bar" in 6 | let part = "ba" in 7 | [ 8 | (.) record "foo" == 1, 9 | (.) record field == { baz = 2 }, 10 | let res = (.) record field == {baz = 2} in res, 11 | (.) record "%{part}r" == { baz = 2 }, 12 | ] |> std.test.assert_all 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/import.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let Assert = std.test.Assert in 3 | ((import "../lib/imported.ncl") 3 == 3 | Assert) 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/let_block_rec.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let rec 3 | b = a, 4 | a = 2, 5 | c = b 6 | in 7 | [ 8 | a == 2, 9 | b == 2, 10 | c == 2, 11 | ] 12 | |> std.test.assert_all 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/let_rec_block_with_pat.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let rec 3 | a = 2, 4 | { b } = { b = a } 5 | in 6 | b == 2 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/numbers.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | [ 5 | 5 + 5 == 10, 6 | 5 * 5 == 25, 7 | 1e6 == 1000000, 8 | 1e+3 / 2e-3 == 0.5e6, 9 | ] 10 | |> std.test.assert_all 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/or_string_bool.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NAryPrimopTypeError' 5 | "a" || false 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/core/recursive_let.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | [ 5 | let rec f = fun n => if n == 0 then n else f (n - 1) in f 10 == 0, 6 | let rec fib = fun n => if n == 0 || n == 1 then 1 else fib (n - 1) + fib (n - 2) in fib 5 == 8, 7 | ] 8 | |> std.test.assert_all 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_enum_tag.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let x = 'Foo in 3 | let 'Foo = x in 4 | true 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_enum_tag_tag_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 'Foo = 'Bar in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_extra_arg.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 'Foo = 'Foo 5 in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_missing_arg.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 'Foo x = 'Foo in 6 | x 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_type_matches.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | ( 3 | let y = 'Foo (1 + 1) in 4 | let 'Foo x = y in 5 | x + 1 == 3 6 | ) : _ 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_type_mismatch_extra_row.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::ExtraRow' 5 | # 6 | # [test.metadata.expectation] 7 | # ident = 'Bar' 8 | (let y : [| 'Foo Number, 'Bar String |] = 'Foo 5 in let 'Foo x = y in x) : _ 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_type_mismatch_tag.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::ExtraRow' 5 | # 6 | # [test.metadata.expectation] 7 | # ident = 'Bar' 8 | (let 'Foo x = 'Bar 5 in x) : _ 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_wrong_tag.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 'Foo x = 'Bar 5 in 6 | x 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/adt_wrong_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 'Foo x = {bar = 1} in 6 | x 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/assign.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a=x, b=y} = {a=1, b=2} in 3 | x + y == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/assign_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'a' 8 | let {a=x} = {a=1} 9 | in a == 1 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/atbind.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let x @ {..} = {a=1, b=2} in 3 | x.a + x.b == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/closed_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let {a} = {a=1, b=2} 6 | in a == 1 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/constant_bool_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let true = false in true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/constant_null_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let null = 0 in true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/constant_number_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let 1 = 1 + 1 in true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/constant_string_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FailedDestructuring' 5 | let "ab" = "a" ++ "b" ++ "c" in true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/constants.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let 5 = 4 + 1 in 3 | let null = null in 4 | let false = !true in 5 | let true = true in 6 | let "ab" = "a" ++ "b" in 7 | true 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/default.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a ? 1, b} = {b=2} in 3 | a + b == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/fun.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let f = fun x@{a, b} {c=d, ..} => a - x.a + b - x.b + d in 3 | f {a=1, b=2} {c=3, d=4} == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/mixed.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let baz = 10 in 3 | let x @ {foo ? 10, b = xb, d ? baz = bar, c = xc @ {ca, ..}, ..y} = {a = 2, b = 3, c = {ca = 22, cb = 0}} in 4 | y.a + x.b - xb + x.c.ca - xc.ca - ca + foo + bar == 0 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/nested.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a={b}} = {a={b=1}} in 3 | b == 1 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/nonexistent_idents.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::MissingRow' 5 | # 6 | # [test.metadata.expectation] 7 | # ident = 'b' 8 | ( 9 | let { a, b } = { a = 1, c = 2 } in 10 | a: Number 11 | ): _ 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/open.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a, ..} = {a=1, b=2} in 3 | a == 1 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/repeated_ident.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError::DuplicateIdentInRecordPattern' 5 | # 6 | # [test.metadata.expectation] 7 | # ident = 'duped' 8 | let f = fun { duped, duped, .. } => duped 9 | in f { duped = 1, other = "x" } -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/repeated_ident_typed.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError::DuplicateIdentInRecordPattern' 5 | # 6 | # [test.metadata.expectation] 7 | # ident = 'a' 8 | ( 9 | let { a, a, .. } = { a = 1, b = 2 } in 10 | a : Number 11 | ): _ 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/rest.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let x @ {..y} = {a=1, b=2} in 3 | x == y 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/rest_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FieldMissing' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'a' 8 | let {a, ..y} = {a=1, b=2} in 9 | y.a 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/simple.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a, b} = {a=1, b=2} in 3 | a + b == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/type_mismatch_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'String' 9 | (let { a : Number } = { a = "hi" } in 10 | a) : _ 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/type_mismatch_field_pattern_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'String' 9 | (let { a : Number = b } = { a = "x" } in b) : _ 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/type_mismatch_nested_destructuring_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'String' 9 | (let { a : { b : Number } = { b }} = { a = { b = "no" }} in 10 | b) : _ 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/typecontract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let {a | Number, b | Number} = {a=1, b=2} in 3 | a + b == 3 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/destructuring/typecontract_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let {a | String} = {a=1} in 6 | a 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/circular_imports.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | (import "imported/circular_imports.ncl") == { a = 1, b = 1 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | import "imported/contract_fail.ncl" -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/direct_import_loop.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | 4 | # Regression test for simple import loop making the typechecker overflow 5 | import "imported/direct_import_loop.ncl" -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/explicit_unknowntag.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError' 5 | 6 | import "imported/empty.yaml" as 'Qqq 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/fallback.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | # Testing that importing files with unknown extension interprets them as Nickel source code 4 | [ 5 | (import "imported/file_without_extension") == 1234, 6 | (import "imported/file_with_unknown_extension.tst") == 1234, 7 | ] 8 | |> std.test.assert_all 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/circular_imports.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | let x = import "circular_imports1.ncl" in {a = 1, b = x.a} 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/circular_imports1.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | let x = import "circular_imports.ncl" in 3 | let y = import "circular_imports2.ncl" in 4 | {a = x.a, b = y} 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/circular_imports2.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | let _x = import "circular_imports.ncl" in 3 | let _y = import "circular_imports1.ncl" in 4 | 0 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/contract_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 1 | String -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/direct_import_loop.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | import "direct_import_loop.ncl" 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/empty.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tweag/nickel/44bdce177e5d66a7a32345607bea6649c4f70df4/core/tests/integration/inputs/imports/imported/empty.yaml -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/file_with_unknown_extension.tst: -------------------------------------------------------------------------------- 1 | 34+1200 2 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/file_without_extension: -------------------------------------------------------------------------------- 1 | 1200+34 2 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/import_parent.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | import "../root_path.ncl" 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/multi_imports.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | let x = import "two.ncl" in 3 | let y = import "nested.ncl" in 4 | x + y 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/multiple.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | type: event 3 | id: 1 4 | --- 5 | type: event 6 | id: 2 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/nested.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | let x = import "two.ncl" in x + 1 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/nested_syntax_error.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | import "nested_syntax_error1.ncl" 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/nested_syntax_error1.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | import "nested_syntax_error2.ncl" 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/nested_syntax_error2.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 1 + 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/nested_table.toml: -------------------------------------------------------------------------------- 1 | [foo.bar] 2 | qux = 42 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/pkg1/main.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 1 + (import dep) 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/pkg2/main.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 43 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/root_path.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | import "root_path/import.ncl" 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/root_path/fourtytwo.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 21 + 21 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/root_path/import.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | (import "fourtytwo.ncl") + (import "../two.ncl") 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/serialize.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | {foo = "a" ++ "b"} 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/two.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 1 + 1 : Number 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/typecheck_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | false : Number 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/unexpected_token.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | "Nickel"$ 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/unexpected_token_buried.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | { 3 | foo = { 4 | bar = [2 @ ], 5 | }, 6 | baz = 2 7 | } -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/imported/unexpected_token_in_record.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | { 3 | name = "Nickel",, 4 | } 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/missing-nickel-path.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ImportError::IoError' 5 | 2 == (import "two.ncl") 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/multi_imports.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | (import "imported/multi_imports.ncl") == 5 -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/needs-nickel-path.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # nickel_path = ['tests/integration/inputs/imports/imported'] 3 | 2 == (import "two.ncl") 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/nested.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | (import "imported/nested.ncl") == 3 -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/nested_syntax_error.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ImportError::ParseError' 5 | 6 | # Regression test for #1090 7 | import "imported/nested_syntax_error.ncl" -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/nested_toml_table.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # 3 | # # Regression test for #2059, where importing toml would fail on nested tables 4 | (import "imported/nested_table.toml").foo.bar.qux == 42 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/recursive.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::InfiniteRecursion' 5 | let x = import "./recursive.ncl" in x 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/root_path.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | (import "imported/root_path.ncl") == 44 -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/serialize.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | (std.serialize 'Json (import "imported/serialize.ncl") == (std.serialize 'Json ({ foo = "ab" }))) -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/static_typing_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'String' 8 | # inferred = 'Number' 9 | (let x = import "imported/two.ncl" in x) : String 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/typecheck_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'Bool' 9 | import "imported/typecheck_fail.ncl" 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/unexpected_token_buried.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ImportError::ParseError' 5 | import "imported/unexpected_token_buried.ncl" -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/unexpected_token_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ImportError::ParseError' 5 | import "imported/unexpected_token.ncl" -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/unexpected_token_in_record_fail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ImportError::ParseError' 5 | let x = import "imported/unexpected_token_in_record.ncl" 6 | in "Hello, " ++ x.name -------------------------------------------------------------------------------- /core/tests/integration/inputs/imports/yaml_import.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | [ 5 | (import "imported/empty.yaml") == null, 6 | 7 | (import "imported/multiple.yaml") == [ 8 | { type = "event", id = 1 }, 9 | { type = "event", id = 2 } 10 | ], 11 | ] 12 | |> std.test.assert_all 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/infinite_loops/mutually_recursive_functions.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::InfiniteRecursion' 5 | { 6 | x = (fun a => a + y) 0, 7 | y = (fun a => a + x) 0, 8 | }.x -------------------------------------------------------------------------------- /core/tests/integration/inputs/infinite_loops/x_eq_expr_involving_x.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::InfiniteRecursion' 5 | { x = y + z, y = z + x, z = 1 }.x -------------------------------------------------------------------------------- /core/tests/integration/inputs/infinite_loops/x_eq_x.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::InfiniteRecursion' 5 | { x = x }.x -------------------------------------------------------------------------------- /core/tests/integration/inputs/infinite_loops/x_eq_y_eq_z_eq_x.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::InfiniteRecursion' 5 | { x = y, y = z, z = x }.x -------------------------------------------------------------------------------- /core/tests/integration/inputs/lib/import_typecheck_strict.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 3 | # This is an auxiliary file used by typechecking tests 4 | 1 + "foo" 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/lib/imported.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 3 | # This is an auxiliary file used by `import.ncl` 4 | fun x => x 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/lib/typed-import.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'skip' 2 | 1 + 1 : Number 3 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/merging/adts_different_tags.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::MergeIncompatibleArgs' 6 | 'Foo null & 'Bar null 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/merging/merge_compose_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let DivBy = fun n l x => if x % n == 0 then x else %blame% l in 6 | let Even = DivBy 2 in 7 | let composed = { a | Even } & { a | DivBy 3 } in 8 | ({ a = 27 } & composed).a 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/merging/merge_conflict_inside_metavalue.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::MergeIncompatibleArgs' 6 | { 7 | foo | default = (fun x => x), 8 | foo | default = (fun x => x) 1 9 | } -------------------------------------------------------------------------------- /core/tests/integration/inputs/merging/merge_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | let r = { a = 2 } & { a | Bool } in r.a 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/merging/merge_default_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | ({ a = 2 } & { b | Number } & { b | default = true }).b -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/identifiers.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | [ 5 | let this-isn't-invalid = true in this-isn't-invalid, 6 | let ___multi_underscore_start = true in ___multi_underscore_start, 7 | ] 8 | |> std.test.assert_all 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/type_var_outside_forall.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'a' 8 | let f | a -> (forall a. a -> a) = 9 | fun x => builtin.seq x null 10 | in null -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unbound_record_tail_var.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundTypeVariable' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'e' 8 | let f : forall a b c. a -> (b -> Array c) -> { foo : Array {field : a}, bar: a; e } = 9 | fun bar_ _g => { foo = [{ field = bar_ }], bar = bar_ } 10 | in null 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unbound_type_variable.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'd' 8 | let f | forall a b c. a -> (b -> Array c) -> {foo : Array {_ : d}, bar: a; Dyn} 9 | = fun bar_ _g => {foo = [{field = 1}], bar = bar_} 10 | in (f 1 (fun _x => [])).foo == [{ field = 1 }] -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unbound_var_in_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'a' 8 | 1 | a -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unexpected_token/buried.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError' 5 | { foo = { bar = [ 2 @ ],}, baz = 2 } -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unexpected_token/dollar.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError' 5 | "Nickel"$ -------------------------------------------------------------------------------- /core/tests/integration/inputs/parsing/unexpected_token/in_record.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ParseError' 5 | { name = "Nickel", , } -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/contract_blame.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | {foo.bar = 5} |> match { 6 | {foo={bar | String}} => bar, 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/contract_default_value_blame.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | {foo = {}} |> match { 6 | {foo={bar | String ? 5}} => bar, 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/contracts.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | 4 | 5 | [ 6 | {foo = {}} |> match { {foo = {bar ? 5}} => true}, 7 | {foo = {}} |> match { {foo = {bar | String }} => false, {foo} => true}, 8 | ] 9 | |> std.test.assert_all 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/default_fail_previous_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | {field | String} |> match { 6 | {field ? 1} => field, 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/non_bool_guard.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::UnaryPrimopTypeError' 5 | {foo = 'Foo 5, bar = 5} |> match { 6 | {foo = 'Foo x, bar} if x => x, 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/non_exhaustive_enum_pattern.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NonExhaustiveMatch' 5 | {foo = 'Foo 5, bar = 5} |> match { 6 | {foo = 'Bar x, bar} => x, 7 | {foo = 'Baz x, ..rest} => x, 8 | } 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/non_exhaustive_record_pattern.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::NonExhaustiveMatch' 5 | {foo.bar = 1, baz = 2} |> match { 6 | {foo = {bar, other}, ..} => null, 7 | {foo = {bar, ..}, baz, other} => null, 8 | } 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/pattern-matching/or_pattern_vars_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::OrPatternVarsMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # var = 'y' 8 | {data = 'Foo 5} |> match { 9 | {data = 'Foo x} or {field = y @ 'Bar x} => true, 10 | } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/cannot_use_dynamic_fields_recursively.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::UnboundIdentifier' 5 | # 6 | # [test.metadata.expectation] 7 | # identifier = 'foo' 8 | let x = "foo" 9 | in { "%{x}" = 1, bar = foo }.bar 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/dynamic_field_missing.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::Other' 5 | { "%{(if false then "foo" else "bar")}" = false, bar = true }.foo -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/freeze_insert_fails_on_missing.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MissingFieldDef' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'bar' 8 | ((std.record.insert "bar" 1 { foo = bar + 1, bar | optional }) & { bar | force = 2 }).foo 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_different_vals_both_force.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a | force = false } & { a | force = true }).a -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_different_vals_default_prio.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a | default = false } & { a | default = true }).a -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_different_vals_no_priority.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a = 1 } & { a = 2 }).a 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_nested_different_vals_default_prio.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | { 6 | foo.bar | default = false, 7 | foo.bar | default = true, 8 | }.foo.bar 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_nested_different_vals_no_prio.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a.b = 1, a = { b = 2 }}).a.b -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_nested_different_vals_prio_0.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a.b | priority 0 = 1, a = { b = 2 }}).a.b -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_nested_different_vals_same_priority.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ foo.bar | priority -10 = false, foo.bar | priority -10 = true }).foo.bar -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_nested_incompatible_types.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MergeIncompatibleArgs' 5 | ({ a.b = {} } & { a.b.c = [] } & { a.b.c = {}}).a.b.c -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/merge_unfreezes.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::BlameError' 5 | 6 | # Test that even if freezing makes the initial `String` contract to not 7 | # propagate, it doesn't prevent other contracts coming from unfrozen records to 8 | # propagate. 9 | %force% ((%record/freeze% { x | String = "a" }) 10 | & { x | priority 1 | Number = 2 } 11 | & { x | priority 2 = false }) 12 | 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MissingFieldDef' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'foo' 8 | { foo, bar = foo + 1 }.foo -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/missing_field_not_exported.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MissingFieldDef' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'a' 8 | { a | not_exported, b = a + 1 }.a -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/missing_field_with_contract.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::MissingFieldDef' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'something' 8 | { something | Number, other = something + 1 }.something -------------------------------------------------------------------------------- /core/tests/integration/inputs/records/static_access_missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::FieldMissing' 5 | # 6 | # [test.metadata.expectation] 7 | # field = 'bar' 8 | { foo = true }.bar -------------------------------------------------------------------------------- /core/tests/integration/inputs/serialization/number_out_of_range.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'ExportError::NumberOutOfRange' 5 | std.serialize 'Json 1e400 -------------------------------------------------------------------------------- /core/tests/integration/inputs/stdlib/record_get_missing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::BlameError' 6 | let record = { 7 | foo = 1, 8 | bar = "two", 9 | baz = false, 10 | } 11 | in 12 | 13 | record 14 | |> std.record.remove "foo" 15 | |> std.record.get "foo" 16 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/stdlib/record_insert_with_opts_existing_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::Other' 6 | let record | {foo_opt | optional, ..} = { 7 | foo = 1, 8 | bar = "two", 9 | baz = false, 10 | } 11 | in 12 | 13 | std.record.insert_with_opts "foo_opt" true record 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/stdlib/record_remove_empty_opt_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'full' 3 | # 4 | # [test.metadata] 5 | # error = 'EvalError::FieldMissing' 6 | # 7 | # [test.metadata.expectation] 8 | # field = 'foo_opt' 9 | let record | {foo_opt | optional, ..} = { 10 | foo = 1, 11 | bar = "two", 12 | baz = false, 13 | } 14 | in 15 | 16 | std.record.remove "foo_opt" record 17 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/strings/string_interpolation_record.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'EvalError::TypeError' 5 | "bad type %{{}}" 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/algebraic_data_types.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let typecheck = [ 3 | ('a |> match 4 | { 5 | 'a => 'Foo 2, 6 | 'b => 'Bar "hello", 7 | 'c => 'Baz true, 8 | } 9 | ) : [| 'Foo Number, 'Bar String, 'Baz Bool, 'OtherTail |], 10 | (fun arg => 'Foo arg) : forall a b. a -> [| 'Foo a; b |], 11 | 'Foo ('Bar 'Baz) : [| 'Foo [| 'Bar [| 'Baz |] |] |], 12 | ] in 13 | 14 | true 15 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/array_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test : Array {foo : Number} = [{foo = 5}] in 3 | let test_func : Array {_ : Number} -> Array {_ : Number} = fun a => a in 4 | let result : Array {_ : Number} = test_func test in 5 | true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/basic_algebraic_data_type_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'Bool' 9 | let force_type_equality : forall a. a -> a -> Dyn = fun _x _y => null in 10 | ( 11 | force_type_equality ('Foo 5) ('Foo true) 12 | ) : _ 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/basic_algebraic_data_type_row_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::EnumRowMismatch' 5 | ( 6 | let x : [| 'Foo Number |] = 'Foo 5 in 7 | let y : [| 'Foo Bool |] = 'Foo true in 8 | # force x and y to have the same type 9 | if true then x else y 10 | ) : _ 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/basic_typechecking.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let Assert = std.test.Assert in 3 | 4 | (let plus : Number -> Number -> Number = fun x => fun y => x + y in 5 | plus (54 : Number) (6 : Number) == 60 | Assert) 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/chaining_dictionary_function_record_dictionary_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # [test.metadata] 3 | # error = 'EvalError::BlameError' 4 | let x = {foo = 1, bar = 2} in 5 | let y = std.record.insert "baz" 5 x in 6 | let _ = std.record.get "foo" y in 7 | let z = std.record.remove "foo" y in 8 | std.record.get "foo" z 9 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/contracts_dont_unify.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'fun l t => t' 9 | # inferred = 'fun l t => t' 10 | (fun x => x) : (fun l t => t) -> (fun l t => t) 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/dictionary_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test : _ = 3 | let test_func : {_ : {_ : Number}} -> {_ : {_ : Number}} = fun a => a in 4 | test_func {a = {foo = 5}} 5 | in 6 | true 7 | 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/dyn_tail_contract_in_typechecking_mode.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ExtraDynTail' 6 | ({ a = 1 } | { a : Number ; Dyn }) : { a : Number } -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/dynamic_record_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = '{ foo : Number }' 9 | # inferred = '{ _ : _a }' 10 | let x = "foo" 11 | in { "%{x}" = 1 } : { foo : Number } 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/dynamic_type_error_with_wildcard_annotation.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Array _a' 9 | # inferred = 'Number' 10 | (let head = fun l => (%array/at% l 0) in (head 10)) : _ 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/dynamic_type_error_without_wildcard.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | let head = fun l => (%array/at% l 0) 4 | in head 10 5 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/enum_match_mismatched_branch_types.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | match { 'foo => 3, 'bar => true } 'bar : Number 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/enum_match_variant_not_covered.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ExtraRow' 6 | # 7 | # [test.metadata.expectation] 8 | # ident = 'bar' 9 | match { 'foo => 3 } 'bar : Number -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/enum_row_tags_dont_conflict.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | ( 3 | let f : forall r. [| 'Foo Number; r |] -> Bool = match { 4 | 'Foo x => false, 5 | _ => true, 6 | } in 7 | 8 | let g : forall r. [| 'Foo Number, 'Foo |] -> Bool = match { 9 | 'Foo x => false, 10 | 'Foo => true, 11 | } in 12 | 13 | f 'Foo && g 'Foo 14 | ) : Bool 15 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/enum_variant_not_in_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ExtraRow' 6 | # 7 | # [test.metadata.expectation] 8 | # ident = 'foo' 9 | 'foo : [| 'bar |] -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/field_polymorphic_annot.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | 3 | # Regression test for https://github.com/tweag/nickel/issues/1690 4 | let lib : _ = { id : forall a. a -> a = std.function.id } in 5 | lib.id true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/forall_inside_row_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | 4 | # regression test for https://github.com/tweag/nickel/issues/1027 5 | let r : { id : forall a. a -> a } = { id = fun r => r } in 6 | r.id "x" 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/higher_rank_coeval.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | let co_eval : ((forall a. a -> a) -> Number) -> Number = ( 4 | ( 5 | fun eval => 6 | let id : forall b. b -> b = fun y => y 7 | in eval id 8 | ) 9 | ) 10 | in 11 | (co_eval (fun id => id 3)) : _ 12 | 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/higher_rank_eval.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | let eval : forall a. (forall b. b -> b) -> a -> a = fun f x => f x 4 | in 5 | (eval (fun x => x)) : _ 6 | 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/include_annot_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | let x : Number = 1 in 11 | { include x : String } 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/include_contract_annot.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | let x : Number = 1 in 4 | { 5 | include x | String, 6 | y = x ++ "b", 7 | } : _ 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/include_polymorphic_var.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck' 3 | let f : forall a. a -> a = fun x => x in 4 | { 5 | include f, 6 | x = f 1, 7 | y = f "hello", 8 | z = f ((+) 1), 9 | } : _ 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/include_record_type_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::RecordRowMismatch' 6 | let x : Number = 1 in 7 | { include x } : { x : String } 8 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/let_block_not_rec.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::UnboundIdentifier' 6 | # 7 | # [test.metadata.expectation] 8 | # identifier = "x" 9 | (let 10 | x = 1, 11 | y = x, 12 | in 13 | true): _ 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/let_rec_outer_scope.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = "Number" 9 | # inferred = "String" 10 | (let x = 1 in 11 | let rec 12 | y = x, 13 | x = "1", 14 | in 15 | y + 1): _ 16 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_array_elem_at.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'b' 9 | # inferred = 'a' 10 | (fun l => %array/at% l 0) : forall a b. (Array a -> b) 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_array_entry.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | [1, 2, false] : Array Number 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_array_map.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Dyn -> _a' 9 | # inferred = 'a -> b' 10 | (fun f l => %array/map% l f) : forall a b. (a -> b) -> Array Dyn -> b 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_array_multiple_entries.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | [1, 2, "3"] : Array String 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_array_typed_entry.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | [(1 : String), true, "b"] : Array Dyn 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_contract_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | (101 | Bool) : Number 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_convert_empty_record_to_dynamic_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::MissingDynTail' 6 | {} : { ; Dyn } -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_convert_static_record_type_to_dynamic_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ExtraRow' 6 | # 7 | # [test.metadata.expectation] 8 | # ident = 'b' 9 | { a = 1, b = 2 } : { a : Number ; Dyn } -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_dict_dynamic_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Bool' 9 | # inferred = 'Number' 10 | 11 | # Regression test for https://github.com/tweag/nickel/issues/2124 12 | let x = "a" in {"%{x}" = 1, bar = false} : {_ : Bool} 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_enum_match_fun_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ExtraRow' 6 | # 7 | # [test.metadata.expectation] 8 | # ident = 'bli' 9 | (match { 10 | 'bla => 1, 11 | 'ble => 2, 12 | 'bli => 3, 13 | }) : [| 'bla, 'ble |] -> Number -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_enum_poly_row_var.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ForallParametricityViolation' 6 | # 7 | # [test.metadata.expectation] 8 | # tail = '[| ; r |]' 9 | # violating_type = "[| 'bli |]" 10 | let f : forall r. [| 'blo, 'ble; r |] -> Number = 11 | match { 'blo => 1, 'ble => 2, 'bli => 3 } 12 | in f -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_forall_var_concrete_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'a' 9 | # inferred = 'Number' 10 | let g : Number -> Number = fun x => x in 11 | let f : forall a. a -> a = fun x => g x in 12 | f 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_forall_variable.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'a' 9 | # inferred = 'b' 10 | let f : forall a. (forall b. a -> b -> a) = 11 | fun x y => y 12 | in f 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_in_fun_body.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | let f : Bool -> Number = 11 | fun x => 12 | if x then x + 1 else 34 13 | in f false 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_let_inference.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | ( 11 | let x = 1 + 2 12 | in let f = fun x => x ++ "a" 13 | in f x 14 | ) : Number 15 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_rec_record_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | { a : Number = true, b = a + 1 } : { a : Number, b : Number } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_rec_record_inference.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | { 11 | f = fun x => if x == 0 then false else 1 + (f (x + (-1))) 12 | } : { f : Number -> Number } 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_rec_record_rec_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Bool' 9 | # inferred = 'Number' 10 | { a = 1, b : Bool = a } : { a : Number, b : Bool } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_dictionary_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::InhomogeneousRecord' 6 | # [test.metadata.expectation] 7 | # row_a = 'Number' 8 | # row_b = 'String' 9 | let test : { foo : Number, bar : String } = { foo = 5, bar = "test" } in 10 | (std.record.insert "baz" 5 test) : { _ : Number } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_dyn_field.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = '{ bla : _a; _rrows_b }' 9 | # inferred = '{ _ : _c }' 10 | ({ 11 | "%{if true then "foo" else "bar"}" = 2, 12 | "foo" = true, 13 | }."bla") : Number 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_field_access.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Bool' 9 | # inferred = 'Number' 10 | { blo = 1 }.blo : Bool 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_field_name.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::MissingRow' 6 | # 7 | # [test.metadata.expectation] 8 | # ident = 'bla' 9 | { blo = 1 } : { bla : Number } -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_field_type.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | { bla = true } : { bla : Number } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_poly_fields.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | let f : forall a. { bla : Bool, blo: a, ble: a } -> a = 11 | fun r => if r.bla then r.blo else r.ble 12 | in (f { bla = true, blo = 1, ble = true } : Number) 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/mismatch_record_poly_row_var.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::ForallParametricityViolation' 6 | # 7 | # [test.metadata.expectation] 8 | # tail = '{ ; r }' 9 | # violating_type = '{ x : String }' 10 | let f : forall r. { x : String } -> { ; r } = 11 | fun x => x 12 | in f { x = 1, y = 2 } 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/no_implicit_polymorphism.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = '_a -> _b' 9 | # inferred = 'Dyn' 10 | (fun id => { a : Number = id 4, b : Bool = id true }) (fun x => x) 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_array_elem_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | match { 11 | [x] => x ++ "a", 12 | [x, y] => y + 1, 13 | } : _ 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_array_rest_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | ["hello", "world"] |> match { 11 | [] => 0, 12 | [x] => 1, 13 | [x, ..rest] => std.array.at 0 rest, 14 | } : _ 15 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_non_bool_guard.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Bool' 9 | # inferred = 'Number' 10 | ( 11 | {foo = 1, bar = 2} 12 | |> match { 13 | {foo, bar} if 1+1 => foo + bar, 14 | _ => 0, 15 | } 16 | ) : _ 17 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_not_an_array.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Array _a' 9 | # inferred = 'String' 10 | "hello" |> match { 11 | [] => 0, 12 | [x] => 1, 13 | [x, ..] => 2, 14 | } : _ 15 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_or_closed_enum.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::ArrowTypeMismatch' 5 | # 6 | # [test.metadata.expectation.cause] 7 | # error = 'TypecheckError::RecordRowMismatch' 8 | match { 9 | {field = 'Foo x} 10 | or {field = 'Bar x} 11 | or {field = 'Baz x} => 12 | null, 13 | }: forall a r. {field: [| 'Foo a, 'Bar a, 'Baz a; r |]} -> Dyn 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_or_type_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # 3 | # [test.metadata] 4 | # error = 'TypecheckError::TypeMismatch' 5 | # 6 | # [test.metadata.expectation] 7 | # expected = 'Number' 8 | # inferred = 'Bool' 9 | match { 10 | 1 or false => null, 11 | }: _ 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_unbound_identifier_guard.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::UnboundIdentifier' 6 | # 7 | # [test.metadata.expectation] 8 | # identifier = 'baz' 9 | ( 10 | {foo = 1, bar = 2} 11 | |> match { 12 | {foo, bar} if foo+bar+baz == 0 => foo + bar, 13 | _ => 0, 14 | } 15 | ) : _ 16 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_variant_arg_mismatch.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'String' 9 | # inferred = 'Number' 10 | match { 11 | 'Foo x => x ++ "a", 12 | 'Bar y => y + 1, 13 | } : _ 14 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/pattern_variant_arg_mismatch_wildcard.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::EnumRowMismatch' 6 | match { 7 | 'Foo x => let _ = x + 1 in null, 8 | 'Foo y => let _ = y ++ "a" in null, 9 | 'Foo _ => null, 10 | } : _ 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/piecewise_signature.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | { foo : Number, foo = "bar" } 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/primitive_mismatch_bool_number.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Bool' 10 | true : Number 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/primitive_mismatch_number_bool.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Bool' 9 | # inferred = 'Number' 10 | 34.5 : Bool 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/primitive_mismatch_string_number.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | "hello" : Number 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/record-typed-field-path.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'ParseError::TypedFieldWithoutDefinition' 6 | { x.y : Number } -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/record_dictionary_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test1 : {foo : Number} = {foo = 5} in 3 | let _ = (std.record.insert "bar" 5 test1) : {_ : Number} in 4 | let test2 : {foo : Number, bar : Number} = {foo = 5, bar = 5} in 5 | let _ = (std.record.insert "baz" 5 test2) : {_ : Number} in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/record_subtyping.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test : _ = 3 | let test_func : {a : {_ : Number}} -> {a : {_ : Number}} = fun a => a in 4 | test_func {a = {foo = 5}} 5 | in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/record_subtyping_multiple_components.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test : _ = 3 | let test_func : {a : {_ : Number}, b : {_ : String}} -> {a : {_ : Number}, b : {_ : String}} = fun a => a in 4 | test_func {a = {foo = 5}, b = {a = "test"}} 5 | in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/record_subtyping_with_tail.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let test : _ = 3 | let test_func : forall b. {a : {_ : Number}; b} -> {a : {_ : Number}; b} = fun a => a in 4 | test_func {a = {foo = 5}, b = 5} 5 | in 6 | true 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/recursive_let.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | let rec f : Number -> Number = 11 | fun x => f "hmm" 12 | in null 13 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/regression-rrows-unification-loops.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | let f : forall a b. (a -> b -> b) -> b -> Dyn = fun x b => null in 3 | let _ign = (f (fun result acc => if result.success then acc else result)) : _ in 4 | # we only care about typechecking here 5 | true 6 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/shallow_type_inference.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'Dyn' 10 | let x = (1 + 1) in (x + 1 : Number) 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/shallow_type_inference_strict_mode.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'pass' 2 | # eval = 'typecheck_strict' 3 | let x = (1 + 1) in (x + 1 : Number) 4 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/strict_mode.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck_strict' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | 1 + "foo" 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/strict_mode_import.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck_strict' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = 'Number' 9 | # inferred = 'String' 10 | import "../lib/import_typecheck_strict.ncl" 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/type_in_term_position.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::CtrTypeInTermPos' 6 | (let c = Number -> (4 + 1) in 3): _ 7 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/unannotated_bindings_type_as_dyn.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = '_a -> _b' 9 | # inferred = 'Dyn' 10 | let id = fun x => x 11 | in (id 4 : Number) 12 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/unbound_variable.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::UnboundIdentifier' 6 | # 7 | # [test.metadata.expectation] 8 | # identifier = 'i_am_unbound' 9 | i_am_unbound 10 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/unsound_generalization_fun.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::VarLevelMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # type_var = 'c' 9 | (fun x => let y : forall c d. c -> d = fun z => x z in y) : _ 10 | 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/unsound_generalization_record_rows.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::VarLevelMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # type_var = 'tail' 9 | ( 10 | fun r => 11 | let foo = r.foo in 12 | let g : forall tail. { foo : _; tail } = r in 13 | g.baz 14 | ) : _ 15 | 16 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/unsound_generalization_simple.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::VarLevelMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # type_var = 'a' 9 | (fun x => let y : forall a. a = x in y) : _ 10 | 11 | -------------------------------------------------------------------------------- /core/tests/integration/inputs/typecheck/wildcard_apparent_ty_is_dyn.ncl: -------------------------------------------------------------------------------- 1 | # test.type = 'error' 2 | # eval = 'typecheck' 3 | # 4 | # [test.metadata] 5 | # error = 'TypecheckError::TypeMismatch' 6 | # 7 | # [test.metadata.expectation] 8 | # expected = '_a -> _b' 9 | # inferred = 'Dyn' 10 | let f : _ -> _ = fun x => x + 1 in 11 | let g : Number = f 0 in 12 | g 13 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { fromGit ? true }: 2 | (import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) { 3 | src = if fromGit then builtins.fetchGit ./. else ./.; 4 | }).defaultNix 5 | -------------------------------------------------------------------------------- /examples/fibonacci/README.md: -------------------------------------------------------------------------------- 1 | # Fibonacci 2 | 3 | This is a basic example of a recursive function: fibonnacci. This is the naive, 4 | exponential version of fibonacci: don't call it on a big value! 5 | 6 | ## Run 7 | 8 | ```console 9 | nickel eval fibonacci.ncl 10 | ``` 11 | -------------------------------------------------------------------------------- /examples/fibonacci/fibonacci.ncl: -------------------------------------------------------------------------------- 1 | # test = 'pass' 2 | 3 | # This is the naive, exponential version of fibonacci: don't call it on a large 4 | # number! 5 | let rec fibonacci = match { 6 | 0 => 0, 7 | 1 => 1, 8 | n => fibonacci (n - 1) + fibonacci (n - 2), 9 | } 10 | in 11 | 12 | fibonacci 10 13 | -------------------------------------------------------------------------------- /examples/foreach-pattern/README.md: -------------------------------------------------------------------------------- 1 | # Foreach Pattern 2 | 3 | This example shows how a _foreach pattern_ works in Nickel using 4 | `std.array.map`. A second example combines a yaml-import with the map function. 5 | 6 | ## Run 7 | 8 | ```console 9 | nickel export foreach-pattern.ncl 10 | ``` 11 | 12 | Second example: 13 | 14 | ```console 15 | nickel export foreach-pattern-on-import.ncl 16 | ``` 17 | -------------------------------------------------------------------------------- /examples/foreach-pattern/data_users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | users: 3 | - jane 4 | - pete 5 | - richie 6 | - ellen 7 | -------------------------------------------------------------------------------- /examples/foreach-pattern/foreach-pattern-on-import.ncl: -------------------------------------------------------------------------------- 1 | # test = 'ignore' 2 | { 3 | posix_users = 4 | (import "data_users.yml").users 5 | |> std.array.map (fun name => 6 | { 7 | username = name, 8 | email = "%{name}@nickel-lang.org" 9 | } 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /examples/foreach-pattern/foreach-pattern.ncl: -------------------------------------------------------------------------------- 1 | # test = 'pass' 2 | { 3 | user = 4 | ["jane", "pete", "richie"] 5 | |> std.array.map (fun name => 6 | { 7 | username = name, 8 | email = "%{name}@nickel-lang.org", 9 | } 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /examples/imports/README.md: -------------------------------------------------------------------------------- 1 | # Various Imports 2 | 3 | This example shows how Nickel can transparently import common serialization formats. 4 | 5 | ## Run 6 | 7 | ```console 8 | nickel export imports.ncl 9 | ``` 10 | -------------------------------------------------------------------------------- /examples/imports/data_groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [ 3 | "desktop-users", 4 | "administrators", 5 | "terminal-users" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/imports/data_machines.toml: -------------------------------------------------------------------------------- 1 | machines = [ 2 | "VAX-11", 3 | "PDP-1", 4 | "Bomba" 5 | ] 6 | -------------------------------------------------------------------------------- /examples/imports/data_users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | users: 3 | - jane 4 | - pete 5 | - richie 6 | - ellen 7 | -------------------------------------------------------------------------------- /examples/merge-priorities/README.md: -------------------------------------------------------------------------------- 1 | # Merge priorities 2 | 3 | This example is a variant of the merge example that makes use of merge 4 | priorities. The code to run lies in `main.ncl`. The default value 5 | `firewall.enabled` defined in `security.ncl` is overwritten in the final 6 | configuration. 7 | 8 | ## Run 9 | 10 | ```console 11 | nickel export main.ncl 12 | ``` 13 | -------------------------------------------------------------------------------- /examples/merge-priorities/security.ncl: -------------------------------------------------------------------------------- 1 | # test = 'ignore' 2 | { 3 | server.host.options | priority 10 = "TLS", 4 | 5 | # force make it impossible to override this value with false 6 | firewall = { 7 | enabled | force = true, 8 | type | default = "iptables", 9 | open_ports | priority 5 = [21, 80, 443], 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /examples/merge-priorities/server.ncl: -------------------------------------------------------------------------------- 1 | # test = 'ignore' 2 | { 3 | server.host = { 4 | ip | default = "182.168.1.1", 5 | port | default = 80, 6 | name | default = "hello-world.net", 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /examples/merge/README.md: -------------------------------------------------------------------------------- 1 | # Merge 2 | 3 | This example shows how to merge separate modules into one configuration. The 4 | code to run lies in `main.ncl`. The default value `firewall.enabled` defined in 5 | `security.ncl` is overridden in the final configuration. 6 | 7 | ## Run 8 | 9 | ```console 10 | nickel export main.ncl 11 | ``` 12 | -------------------------------------------------------------------------------- /examples/merge/main.ncl: -------------------------------------------------------------------------------- 1 | # test = 'pass' 2 | 3 | # Merge several blocks into one final configuration. In a real world case, one 4 | # would also want contracts to validate the shape of the data. 5 | let 6 | server = import "server.ncl", 7 | security = import "security.ncl", 8 | in 9 | # Disabling firewall in the final result 10 | server & security & { firewall.enabled = false } 11 | -------------------------------------------------------------------------------- /examples/merge/security.ncl: -------------------------------------------------------------------------------- 1 | # test = 'ignore' 2 | { 3 | server.host.options = "TLS", 4 | 5 | firewall.enabled | default = true, 6 | firewall.type = "iptables", 7 | firewall.open_ports = [21, 80, 443], 8 | } 9 | -------------------------------------------------------------------------------- /examples/merge/server.ncl: -------------------------------------------------------------------------------- 1 | # test = 'ignore' 2 | { 3 | server.host = { 4 | ip = "182.168.1.1", 5 | port = 80, 6 | name = "hello-world.net", 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /examples/polymorphism/polymorphism.ncl: -------------------------------------------------------------------------------- 1 | # test = 'pass' 2 | 3 | # First projection, statically typed 4 | let first : forall a b. a -> b -> a = fun x y => x in 5 | # Evaluation function, statically typed 6 | let eval : forall a b. (a -> b) -> a -> b = fun f x => f x in 7 | let id : forall a. a -> a = fun x => x in 8 | (eval id (first 5 10) == 5 : Bool) 9 | -------------------------------------------------------------------------------- /lsp/nls/src/requests/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod completion; 2 | pub mod formatting; 3 | pub mod goto; 4 | pub mod hover; 5 | pub mod rename; 6 | pub mod symbols; 7 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/completion-field-disambiguation.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | let C = { foo | Number | doc "Some doc" } in 3 | { 4 | foo | String, 5 | bar = { 6 | f 7 | } | C 8 | } 9 | ### [[request]] 10 | ### type = "Completion" 11 | ### textDocument.uri = "file:///main.ncl" 12 | ### position = { line = 4, character = 5 } 13 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/completion-incomplete-record-field-nested.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | { 3 | field.foo. 4 | } | { field = { foo = { bar } } } 5 | ### [[request]] 6 | ### type = "Completion" 7 | ### textDocument.uri = "file:///main.ncl" 8 | ### position = { line = 1, character = 12 } 9 | ### context = { triggerKind = 2, triggerCharacter = "." } 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/completion-incomplete-record-field.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | { 3 | field. 4 | } | { field = { foo } } 5 | ### [[request]] 6 | ### type = "Completion" 7 | ### textDocument.uri = "file:///main.ncl" 8 | ### position = { line = 1, character = 8 } 9 | ### context = { triggerKind = 2, triggerCharacter = "." } 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/completion-incomplete-record-value.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | let baz = { bar = 1 } in 3 | { 4 | field.foo = baz. 5 | } | { field = { foo } } 6 | ### [[request]] 7 | ### type = "Completion" 8 | ### textDocument.uri = "file:///main.ncl" 9 | ### position = { line = 2, character = 18 } 10 | ### context = { triggerKind = 2, triggerCharacter = "." } 11 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/completion-match-typed.ncl: -------------------------------------------------------------------------------- 1 | ### /input.ncl 2 | fun x => match { y => y.fo } 3 | : { foo: Number, fo: Number } -> Number 4 | ### [[request]] 5 | ### type = "Completion" 6 | ### textDocument.uri = "file:///input.ncl" 7 | ### position = { line = 0, character = 26 } 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/diagnostics-array.ncl: -------------------------------------------------------------------------------- 1 | ### /diagnostics-array.ncl 2 | [ 3 | [ 4 | "a", 5 | ] | Array Number, 6 | [ 7 | { num = "str" } 8 | ] | Array { num | Number }, 9 | [ 10 | [ "a" ] 11 | ] | Array (Array Number), 12 | ] 13 | ### diagnostic = ["file:///diagnostics-array.ncl"] 14 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/diagnostics-basic.ncl: -------------------------------------------------------------------------------- 1 | ### /diagnostics-basic.ncl 2 | { 3 | num | Number = "a", 4 | num2 = 'hi, 5 | } | { num2 | Number, other | String, num } 6 | ### diagnostic = ["file:///diagnostics-basic.ncl"] 7 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/diagnostics-recursion.ncl: -------------------------------------------------------------------------------- 1 | ### /diagnostics-recursion.ncl 2 | let rec foo = { bar = foo, quux | String = 1 } in 3 | [ 4 | foo, 5 | foo.bar.bar.bar.bar.bar.baz 6 | ] 7 | ### diagnostic = ["file:///diagnostics-recursion.ncl"] 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/diagnostics-typecheck.ncl: -------------------------------------------------------------------------------- 1 | ### /diagnostics.ncl 2 | 5 : String 3 | ### diagnostic = ["file:///diagnostics.ncl"] 4 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/external_import.json: -------------------------------------------------------------------------------- 1 | { 2 | "someData": "someValue" 3 | } 4 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/external_import.yaml: -------------------------------------------------------------------------------- 1 | someData: someValue 2 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/formatting.ncl: -------------------------------------------------------------------------------- 1 | ### /formatting.ncl 2 | { foo = "bar", 3 | baz = 7} 4 | ### [[request]] 5 | ### type = "Formatting" 6 | ### textDocument.uri = "file:///formatting.ncl" 7 | ### [request.options] 8 | ### tabSize = 2 9 | ### insertSpaces = true 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/hover-double-def.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | { foo, foo } | { foo | doc "The field Foo" } 3 | ### [[request]] 4 | ### type = "Hover" 5 | ### textDocument.uri = "file:///main.ncl" 6 | ### position = { line = 0, character = 3 } 7 | ### [[request]] 8 | ### type = "Hover" 9 | ### textDocument.uri = "file:///main.ncl" 10 | ### position = { line = 0, character = 8 } 11 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/hover_field_typed_block_regression_1574.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | let map: Array Number = std.array.map (fun x => 1) [] in map 3 | ### [[request]] 4 | ### type = "Hover" 5 | ### textDocument.uri = "file:///main.ncl" 6 | ### position = { line = 0, character = 34 } 7 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/import_external_format.ncl: -------------------------------------------------------------------------------- 1 | ### /external_import.ncl 2 | let foo = import "external_import.json" in 3 | let bar = import "external_import.yaml" in 4 | foo & bar 5 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/no-crash-on-pretty-print.ncl: -------------------------------------------------------------------------------- 1 | ### /main.ncl 2 | { 3 | multiple_of 4 | : Number -> Dyn -> [| 'Ok, 'Error { message | String, notes] } |] 5 | = 1 6 | } 7 | ### diagnostic = ["file:///main.ncl"] 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/inputs/symbols-recursion.ncl: -------------------------------------------------------------------------------- 1 | ### /syms.ncl 2 | let rec foo = { bar = foo } in foo 3 | ### # In principle there are infinitely many symbols, but we bound the recursion instead 4 | ### # of crashing. 5 | ### [[request]] 6 | ### type = "Symbols" 7 | ### textDocument.uri = "file:///syms.ncl" 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-array.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [foo] 6 | [bar] 7 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-dict.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [foo (Number)] 6 | [foo (Number)] 7 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-field-disambiguation.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [foo (Number) [Some doc]] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-fun-parameter-contract.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [baz, foo ({ bar })] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-incomplete-record-field-nested.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [bar] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-incomplete-record-field.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [foo] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-incomplete-record-value.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [bar] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-incomplete.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [config, std] 6 | [foo, verified, version] 7 | [foo, verified, version] 8 | [foo, verified, version] 9 | [really] 10 | [really] 11 | [foo, really, verified, version] 12 | ["has a space", lalala] 13 | [falala] 14 | 15 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-inside-enum.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [bar] 6 | [baz] 7 | [inner] 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-match-typed.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [fo (Number), foo (Number)] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-match.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [p, payload, std] 6 | [bar] 7 | [bar] 8 | [p, payload, std, y] 9 | [] 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-nested.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [one] 6 | [two] 7 | [three] 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__completion-patterns.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [extra, foo] 6 | [bar, more] 7 | [baz, most] 8 | [bar (Dyn), more] 9 | [baz, most] 10 | [baz, most] 11 | [foo] 12 | [bar] 13 | [baz] 14 | [std] 15 | [extra, foo, std] 16 | [bar, extra, foo, more, std] 17 | [inner, innermost, outer, std] 18 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__diagnostics-basic.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [1:8-1:14: "expected type", 1:17-1:20: "contract broken by the value of `num`", 1:17-1:20: "applied to this expression", 2:9-2:12: "contract broken by the value of `num2`", 2:9-2:12: "applied to this expression", 3:13-3:19: "expected type"] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__diagnostics-recursion.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [0:14-0:46: "this record lacks the field `baz`", 0:34-0:40: "expected type", 0:43-0:44: "contract broken by the value of `quux`", 0:43-0:44: "applied to this expression", 3:2-3:29: "missing field `baz`\nDid you mean `bar`?", 3:2-3:29: "this requires the field `baz` to exist"] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__diagnostics-typecheck.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [0:0-0:1: "incompatible types\nExpected an expression of type `String`\nFound an expression of type `Number`\nThese types are not compatible", 0:0-0:1: "this expression"] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__diagnostics-undefined-fields.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__formatting.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [<0:0-2:0> { 6 | foo = "bar", 7 | baz = 7 8 | } 9 | ] 10 | 11 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-cross-file.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///dep.ncl:0:0-0:15 6 | file:///goto.ncl:1:2-1:8 7 | file:///dep.ncl:0:2-0:5 8 | [file:///goto.ncl:3:9-3:12] 9 | 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-let-block.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///goto.ncl:0:4-0:5 6 | file:///goto.ncl:0:4-0:5 7 | file:///goto.ncl:3:2-3:3 8 | file:///goto.ncl:2:2-2:3 9 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-let-rec.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///goto.ncl:0:4-0:5 6 | file:///goto.ncl:3:2-3:3 7 | file:///goto.ncl:3:2-3:3 8 | file:///goto.ncl:2:2-2:3 9 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-multiple.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [file:///goto.ncl:0:32-0:35, file:///goto.ncl:1:24-1:27, file:///goto.ncl:2:17-2:20] 6 | file:///goto.ncl:1:36-1:40 7 | [file:///goto.ncl:1:24-1:27, file:///goto.ncl:2:17-2:20] 8 | 9 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-pattern.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///goto.ncl:2:4-2:9 6 | None 7 | file:///goto.ncl:2:4-2:9 8 | file:///goto.ncl:2:14-2:17 9 | file:///goto.ncl:6:4-6:9 10 | file:///goto.ncl:2:14-2:17 11 | file:///goto.ncl:9:19-9:22 12 | 13 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-record.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///goto.ncl:0:15-0:18 6 | file:///goto.ncl:0:24-0:27 7 | file:///goto.ncl:0:32-0:35 8 | file:///goto.ncl:0:32-0:35 9 | 10 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__goto-scoping.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///goto.ncl:0:4-0:10 6 | file:///goto.ncl:2:4-2:10 7 | [file:///goto.ncl:0:4-0:10, file:///goto.ncl:2:13-2:19] 8 | [file:///goto.ncl:2:13-2:19] 9 | [file:///goto.ncl:2:4-2:10, file:///goto.ncl:3:0-3:6] 10 | [file:///goto.ncl:3:0-3:6] 11 | 12 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__hover-basic.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | <6:0-6:6>[```nickel 6 | Dyn 7 | ```] 8 | <6:0-6:10>[```nickel 9 | Dyn 10 | ```, middle] 11 | <6:0-6:14>[```nickel 12 | Number 13 | ```, innermost] 14 | <1:2-1:5>[```nickel 15 | Dyn 16 | ```, middle] 17 | <2:4-2:7>[```nickel 18 | Number 19 | ```, innermost] 20 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__hover-cousin.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | <1:2-1:5>[```nickel 6 | Dyn 7 | ```, outer] 8 | <1:10-1:13>[```nickel 9 | Number 10 | ```, inner] 11 | <2:9-2:12>[```nickel 12 | Dyn 13 | ```, outer] 14 | <2:9-2:16>[```nickel 15 | Number 16 | ```, inner] 17 | <3:6-3:10>[```nickel 18 | Dyn 19 | ```, longer path] 20 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__hover-double-def.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | <0:2-0:5>[```nickel 6 | Dyn 7 | ```, The field Foo] 8 | <0:7-0:10>[```nickel 9 | Dyn 10 | ```, The field Foo] 11 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__hover-pattern-typed.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | <0:7-0:8>[```nickel 6 | Number 7 | ```] 8 | <0:15-0:16>[```nickel 9 | Number 10 | ```] 11 | <0:26-0:27>[```nickel 12 | Number 13 | ```] 14 | 15 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__import_external_format.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__import_invalidation.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///base.ncl:1:2-1:5 6 | None 7 | 8 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__no-crash-on-pretty-print.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | [2:63-2:64: "unexpected token", 3:6-3:7: "incompatible types\nExpected an expression of type `Number -> Dyn -> [| 'Ok, 'Error { message | String, , } |]`\nFound an expression of type `Number`\nThese types are not compatible", 3:6-3:7: "this expression"] 6 | -------------------------------------------------------------------------------- /lsp/nls/tests/snapshots/main__lsp__nls__tests__inputs__offsets.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: lsp/nls/tests/main.rs 3 | expression: output 4 | --- 5 | file:///offsets.ncl:1:45-1:48 6 | [file:///offsets.ncl:1:45-1:48, file:///offsets.ncl:2:2-2:5] 7 | 8 | -------------------------------------------------------------------------------- /lsp/vscode-extension/.vscodeignore: -------------------------------------------------------------------------------- 1 | **/* 2 | !images 3 | !out/extension.js 4 | !language-configuration.json 5 | !package.json 6 | !syntaxes/ 7 | !LICENSE 8 | -------------------------------------------------------------------------------- /lsp/vscode-extension/images/nickel-logo-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tweag/nickel/44bdce177e5d66a7a32345607bea6649c4f70df4/lsp/vscode-extension/images/nickel-logo-256.png -------------------------------------------------------------------------------- /lsp/vscode-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2019", 5 | "lib": ["ES2019"], 6 | "outDir": "out", 7 | "rootDir": "src", 8 | "sourceMap": true 9 | }, 10 | "include": ["src"], 11 | "exclude": ["node_modules", ".vscode-test"] 12 | } 13 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/branch-leaf/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "branch-leaf", 3 | description = "A package with no dependencies, available at a git branch", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/branch-leaf/branch.txt: -------------------------------------------------------------------------------- 1 | cành 2 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/leaf/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies", 4 | version = "0.1.0", 5 | minimal_nickel_version = "1.9.0", 6 | authors = ["Joe"], 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/tag-leaf/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies, available at a git tag", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/tag-leaf/tag.txt: -------------------------------------------------------------------------------- 1 | mytag 2 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/with-subdirs/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "with-subdirs", 3 | description = "A package in a git repo with other packages in subdirectories", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/with-subdirs/leaf-subdir/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf-subdir", 3 | description = "A package in a subdirectory of a git repo", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/git/with-subdirs/subdir-with-path-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "subdir-with-path-dep", 3 | description = "A package in a subdir of a git repo, depending on packages in other directories", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Path "../leaf-subdir", 9 | parent = 'Path "..", 10 | }, 11 | } | std.package.Manifest 12 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/index/github/example/leaf/0.1.0/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies", 4 | version = "0.1.0", 5 | minimal_nickel_version = "1.9.0", 6 | authors = ["Joe"], 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/index/github/example/leaf/0.1.1/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies", 4 | version = "0.1.1", 5 | minimal_nickel_version = "1.9.0", 6 | authors = ["Joe"], 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/index/github/example/leaf/0.2.0/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies", 4 | version = "0.2.0", 5 | minimal_nickel_version = "1.9.0", 6 | authors = ["Joe"], 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/double-path-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "double-path-dep", 3 | description = "A package with a single path dependency, which has a further path dependency", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | dep = 'Path "../single-path-dep" 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/duplicate-lock-name/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "duplicate-lock-name", 3 | description = "A package having two different identically-named path packages in its dep graph", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Path "../single-path-dep" 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/duplicate-path/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "duplicate-path", 3 | description = "A package having two different routes in the dependency graph to the same path package", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | dep = 'Path "../single-path-dep", 9 | leafy = 'Path "../leaf", 10 | }, 11 | } | std.package.Manifest 12 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/leaf/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "leaf", 3 | description = "A package with no dependencies", 4 | version = "0.1.0", 5 | minimal_nickel_version = "1.9.0", 6 | authors = ["Joe"], 7 | dependencies = {}, 8 | } | std.package.Manifest 9 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/path-to-index-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "path-to-index-dep", 3 | description = "A package with a path dependency that has an index dependency", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | dep = 'Path "../single-index-dep", 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/single-git-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "single-git-dep", 3 | description = "A package with a git dependency", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Git { url = "https://example.com/leaf" } 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/single-index-compat-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "single-index-compat-dep", 3 | description = "A package with an index dependency that doesn't have an exact constraint", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Index { package = "github:example/leaf", version = "0.1.0" } 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/single-index-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "single-index-dep", 3 | description = "A package with an index dependency", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Index { package = "github:example/leaf", version = "=0.1.0" } 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/integration/inputs/path/single-path-dep/Nickel-pkg.ncl: -------------------------------------------------------------------------------- 1 | { 2 | name = "single-path-dep", 3 | description = "A package with a single path dependency", 4 | version = "0.1.0", 5 | authors = ["Joe"], 6 | minimal_nickel_version = "1.9.0", 7 | dependencies = { 8 | leaf = 'Path "../leaf" 9 | }, 10 | } | std.package.Manifest 11 | -------------------------------------------------------------------------------- /package/tests/snapshots/integration__package__tests__integration__inputs__path__leaf__Nickel-pkg.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: package/tests/integration.rs 3 | expression: lock_contents 4 | --- 5 | { 6 | "dependencies": {}, 7 | "packages": {} 8 | } 9 | -------------------------------------------------------------------------------- /package/tests/snapshots/integration__package__tests__integration__inputs__path__single-path-dep__Nickel-pkg.ncl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: package/tests/integration.rs 3 | expression: lock_contents 4 | --- 5 | { 6 | "dependencies": { 7 | "leaf": { 8 | "name": "leaf" 9 | } 10 | }, 11 | "packages": { 12 | "leaf": { 13 | "precise": "Path", 14 | "dependencies": {} 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /py-nickel/README.md: -------------------------------------------------------------------------------- 1 | # pynickel 2 | 3 | Python bindings to use Nickel. 4 | 5 | ## Install 6 | 7 | ```shell 8 | pip install py-nickel 9 | ``` 10 | 11 | ## Use 12 | 13 | ```python 14 | import nickel 15 | 16 | result = nickel.run("let x = 1 in { y = x + 2 }") 17 | print(result) 18 | # { 19 | # "y": 3 20 | # } 21 | ``` 22 | -------------------------------------------------------------------------------- /py-nickel/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | pyo3_build_config::add_extension_module_link_args(); 3 | } 4 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | # The `default.nix` in flake-compat reads `flake.nix` and `flake.lock` from `src` and 2 | # returns an attribute set of the shape `{ defaultNix, shellNix }` 3 | 4 | (import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) { 5 | src = ./.; 6 | }).shellNix 7 | -------------------------------------------------------------------------------- /spec/type-system/Makefile: -------------------------------------------------------------------------------- 1 | OTT_FILES = grammar.ott rules.ott 2 | # OTT_OPTS = -tex_show_meta false -tex_wrap false -picky_multiple_parses false -tex_suppress_ntr Q 3 | OTT_TEX = type-system.tex 4 | 5 | all: type-system.pdf 6 | 7 | clean: 8 | rm -f *.aux *.bbl *.ptb *.pdf *.toc *.out *.run.xml 9 | 10 | $(OTT_TEX): $(OTT_FILES) 11 | ott $(OTT_OPTS) -o $@ $^ 12 | 13 | %.pdf : %.tex $(OTT_TEX) 14 | latexmk -pdf $(notdir $*) 15 | -------------------------------------------------------------------------------- /utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod annotated_test; 2 | pub mod bench; 3 | pub mod project_root; 4 | pub mod test_program; 5 | 6 | pub use nickel_lang_core; 7 | -------------------------------------------------------------------------------- /wasm-repl/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub use nickel_lang_core::*; 2 | --------------------------------------------------------------------------------