-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Proper type instantiation discipline (#1473)
* Proper type instantiation discipline This commit is the last missing piece (at least for the time being) toward a reasonable bidirectional typechecking algorithm that properly handle higher-rank types. Instantiation of polymorphic types has been ad-hoc and full of issues. Simple programs such as: ```nickel let r : { id : forall a. a -> a } = { id = fun r => r } in r.id "x" ``` or ```nickel let eval : forall a. (forall b. b -> b) -> a -> a = fun f x => f x in (eval (fun x => x) 1) : Number ``` wouldn't typecheck. Previously introduced variable levels were required before we could change that. This commit is building on the variable level to use a proper instantiation discipline from the specification of the Nickel type system located in this repository, and the original inspiration, [A Quick Look at Impredicativity]() (although type instantiation is currently predicative, the general structure of the bidirectional type system is similar). Doing so, we also move code between `check` and `infer` to better reflect the specification: `infer` is not wrapper around check + unification anymore, but it actually implements infer rules (function application, primop application, variable and annotation). Instantiation is taken care of when switching from infer mode to check mode within `subsumption` and at function application. * Add test for unsound generalization And fix the error expectation for `TypecheckError::VarLevelMismatch` that still had the old longer name `VariableLevelMismatch`. * Update core/tests/integration/main.rs Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io> * Update core/src/typecheck/mod.rs * Update core/src/typecheck/mod.rs * Post-rebase fixup + clippy warnings * Formatting of Nickel test files --------- Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
- Loading branch information
Showing
13 changed files
with
273 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 0 additions & 14 deletions
14
core/tests/integration/typecheck/fail/mismatch_nested_forall_variable.ncl
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
core/tests/integration/typecheck/fail/unsound_generalization_monomorphic_id.ncl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# test.type = 'error' | ||
# eval = 'typecheck' | ||
# | ||
# [test.metadata] | ||
# error = 'TypecheckError::ArrowTypeMismatch' | ||
# | ||
# [test.metadata.expectation.sub_error] | ||
# error = 'TypecheckError::VarLevelMismatch' | ||
# | ||
# [test.metadata.expectation.sub_error.expectation] | ||
# type_var = 'b' | ||
( | ||
let eval : forall a. (forall b. b -> b) -> a -> a = fun f x => f x | ||
in | ||
# because g isn't annotated, it doesn't get a polymorphic type, but a | ||
# monomorphic _a -> _a | ||
let g = fun x => x | ||
in eval g | ||
) : _ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
core/tests/integration/typecheck/pass/forall_inside_row_type.ncl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# test.type = 'pass' | ||
# eval = 'typecheck' | ||
|
||
# regression test for https://github.com/tweag/nickel/issues/1027 | ||
let r : { id : forall a. a -> a } = { id = fun r => r } in | ||
r.id "x" |
12 changes: 12 additions & 0 deletions
12
core/tests/integration/typecheck/pass/higher_rank_coeval.ncl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# test.type = 'pass' | ||
# eval = 'typecheck' | ||
let co_eval : ((forall a. a -> a) -> Number) -> Number = ( | ||
( | ||
fun eval => | ||
let id : forall b. b -> b = fun y => y | ||
in eval id | ||
) | ||
) | ||
in | ||
(co_eval (fun id => id 3)) : _ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# test.type = 'pass' | ||
# eval = 'typecheck' | ||
let eval : forall a. (forall b. b -> b) -> a -> a = fun f x => f x | ||
in | ||
(eval (fun x => x)) : _ | ||
|