enso
enso copied to clipboard
[Do Not Merge Yet] Type Inference PoC - iteration 1 - most basic type inference
Pull Request Description
- Closes #8590
- It cannot be merged before #9361 is implemented, as it changes the IR structure in such a way that currently it cannot be saved without that fix. So merging it before this fix would break caches.
Important Notes
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
- [x] The documentation has been updated, if necessary.
- [ ] Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
- [x] All code follows the Scala, Java, and Rust style guides. In case you are using a language not listed above, follow the Rust style guide.
- All code has been tested:
- [x] Unit tests have been written where possible.
- [ ] If GUI codebase was changed, the GUI was tested when built using
./run ide build.
I will very much appreciate reviews on this PR.
Due to introducing a cyclic reference to the IR (by adding Expression inside of BindingsMap.Type (indirectly through Const -> Argument)), it cannot be merged before #9361 is available, because the new IR becomes unwritable.
However, getting a greenlight on it will allow me to merge it right away once #9361. It will also allow me to start followup work, basing on top of this PR as a foundation - so I really need your feedback if the foundations laid out here seem sensible to you or if I should change anything.
In 4130187d28749eb29a05b0adecc185852ad32d2f I added persistance for TypeInference pass and its related components. By default these are not included in the cache generation because the pass is disabled.
Just to test it works and see the impact, I ran the cache generation with inference enabled, through the following patch:
diff --git a/project/DistributionPackage.scala b/project/DistributionPackage.scala
--- a/project/DistributionPackage.scala (revision 4130187d28749eb29a05b0adecc185852ad32d2f)
+++ b/project/DistributionPackage.scala (date 1716553155231)
@@ -244,6 +244,7 @@
Platform.executableFileName(ensoExecutable.toString),
"--no-compile-dependencies",
"--no-global-cache",
+ "--enable-static-analysis",
"--compile",
path.toString
)
The Base.bindings cache seems to have grown from 30MB to ~31.1MB.
Even though this first iteration is extremely simple, it is already giving some fruit. It allowed me to statically detect the following problem within the Image library, that was not unit tested anywhere:
X:\NBO\enso\built-distribution\enso-engine-0.0.0-dev-windows-amd64\enso-0.0.0-dev\lib\Standard\Image\0.0.0-dev\src\Matrix.enso:381:21: warning: Invoking a value that has a non-function type (type Image) will result in a Not_Invokable error in runtime.
381 | to_image self = Image (Image.from_vector self.normalize.to_vector self.rows self.channels)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
and indeed, running the following example code:
from Standard.Base import all
from Standard.Image import all
main =
mat = Matrix.identity 32 32 channels=3
IO.println mat
img = mat.to_image
IO.println img
r = img.write (File.new "tmp.png")
IO.println r
yields
(Matrix.Value Mat [ 32*32*CV_64FC3, isCont=true, isSubmat=false, nativeObj=0x1a02050ecb0, dataAddr=0x19fcab4c000 ])
Execution finished with an error: Type error: expected a function, but got Image.
at <enso> Matrix.to_image(Matrix.enso:381:21-94)
at <enso> img.main(img.enso:7:11-22)
so our type checker has found a real error based on the static knowledge :)
The problem is fixed in commit be6173cfe30d4dd01459f8aeb7fc98d30b694736 - now the type checker does not issue any warnings (for now...)
Now the output is:
(Matrix.Value Mat [ 32*32*CV_64FC3, isCont=true, isSubmat=false, nativeObj=0x217196ed0d0, dataAddr=0x21726f4dbc0 ])
(Image.Value Mat [ 32*32*CV_8UC3, isCont=true, isSubmat=false, nativeObj=0x217196f0410, dataAddr=0x21726fbcb40 ])
Writing the image to a file: X:\NBO\enso\tmp.png
X:\NBO\enso\tmp.png
Split off persistance changes to #10101 , will rebase once that is merged.