Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
983fa6e
Experiment: disable boxed type capture subtyping
jiribenes Nov 21, 2025
1f2e83f
Also disable other subtyping (inside of type constructors)
b-studios Nov 21, 2025
ff5b598
Also check object implementations against the expected type
b-studios Nov 21, 2025
622ff5e
Disable coercions in contravariant positions
b-studios Nov 24, 2025
041fab4
Drive-by: drop unused transformed program to avoid transforming twice
b-studios Nov 26, 2025
63d9a89
Only allow coercions in certain positions
b-studios Nov 28, 2025
fa4e1e3
WIP add motif to matches in core and drop subtyping / merging there
b-studios Nov 28, 2025
0639b24
Add some coercions (probably some are missing, still)
b-studios Nov 30, 2025
1a03a2b
Change error since now we infer Unit after coercing
b-studios Nov 30, 2025
9365d4c
Drop annotated type on Val and Let in core
b-studios Nov 30, 2025
6005a10
Drop bottom coercer since it should not be necessary anymore
b-studios Dec 1, 2025
cfcf08a
Add assertion that normalizer is type preserving and fix a bug using it
b-studios Dec 1, 2025
3124cfc
Annotate hole with type, check normalization preserves type and some …
b-studios Dec 2, 2025
ec22b60
Implement type equality and use it in some core phases
b-studios Dec 3, 2025
5e8312c
Sketch type checking for core, which doubles as free variable computa…
b-studios Dec 3, 2025
f9dba55
Typecheck constructors with existentials
b-studios Dec 3, 2025
289e729
Finish type checking of expressions
b-studios Dec 3, 2025
cf85cac
All operations on Free need to maintain the invariants
b-studios Dec 3, 2025
2d69f1d
Helpers for blocklits and implementations
b-studios Dec 3, 2025
e130ca0
Typecheck reset and region
b-studios Dec 3, 2025
4003b95
Replace inferTpe and inferCapt by typecheck
b-studios Dec 3, 2025
2538955
Add tpe and capt to Operation
b-studios Dec 3, 2025
2ebfea7
Collect constraints about constructors
b-studios Dec 4, 2025
0efe13b
Implement regions and mutable state
b-studios Dec 4, 2025
4bea573
Try implementing typing of pattern matching
b-studios Dec 4, 2025
c3573bb
Change Shift to allow (at least) type checking of uni-directional resume
b-studios Dec 4, 2025
3cae5bb
Implement calls
b-studios Dec 4, 2025
25906f9
Fill in more typechecking cases
b-studios Dec 4, 2025
a239c5a
Don't check captures for now to have a migration path forward
b-studios Dec 4, 2025
e2bc07b
Fix missing substitution
b-studios Dec 4, 2025
c5450fe
Drop duplicate free variable computation
b-studios Dec 4, 2025
83fbcb3
Annotate existential type params
b-studios Dec 4, 2025
d2b5fd5
Fix a few more bugs
b-studios Dec 4, 2025
2337e05
Require existential type parameters to be annotated on methods
b-studios Dec 5, 2025
4ebce71
Fix a few bugs in stlib and examples now that we don't have subtyping…
b-studios Dec 5, 2025
e912132
Fix more errors after deprecating subtyping
b-studios Dec 5, 2025
a101cb5
Add some missing coercions to polymorphism boxing
b-studios Dec 5, 2025
01ae20a
WIP trying to fix polymorphism boxing
b-studios Dec 5, 2025
1912a7e
Update numbers in VMTests, but parsing_dollars is getting worse
b-studios Dec 5, 2025
8604af9
Distinguish between unreachable and not implemented in JS and Chez
b-studios Dec 5, 2025
96b08ad
Fix some TestRenamer tests
b-studios Dec 5, 2025
2c33798
Improve errors in reparse tests
b-studios Dec 5, 2025
af3a255
Prettyprint and parse character literals
b-studios Dec 5, 2025
e90d019
Make characters reparsable
b-studios Dec 5, 2025
e874b92
Not only fix test renamer, but also renamer
b-studios Dec 5, 2025
e580713
Fix type inference tests for now
b-studios Dec 5, 2025
5ee1032
Fix pattern matching tests
b-studios Dec 5, 2025
1e38338
Fix type annotations in optimizer tests
b-studios Dec 5, 2025
f236ba6
Empty matches are unreachable in chez scheme
b-studios Dec 5, 2025
7c74eb5
Fix LSP Tests: vals are not annotated anymore
b-studios Dec 5, 2025
9b2faf4
Uniform representation
phischu Dec 5, 2025
6deea9a
Proper union of sets
phischu Dec 6, 2025
51f0c9f
Also note reference allocated in region
phischu Dec 6, 2025
0e82ac6
Add free variables of scrutinee
phischu Dec 6, 2025
7608ed7
Rebox when resuming
phischu Dec 6, 2025
4870440
Unbox in async calls
phischu Dec 6, 2025
963ef5b
Fix expected result
phischu Dec 9, 2025
00aba2c
Bring back the top
phischu Dec 9, 2025
4cfc257
Translate top and bottom types
phischu Dec 9, 2025
520cab1
Add a test
phischu Dec 10, 2025
470fb59
Merge branch 'master' into experiment/no-box-subtyping
phischu Dec 10, 2025
f0c5ca2
Bring back operations on Unit
phischu Dec 11, 2025
2bba3b5
Deduplicate rts code
phischu Dec 11, 2025
b273661
Increase JVM stack size
phischu Dec 12, 2025
a99a389
Try to minimize diff a bit
b-studios Dec 13, 2025
4eeb7c9
allow clang-21
b-studios Dec 14, 2025
7cf9396
CI: Add macOS LLVM smoke tests (#1256)
jiribenes Dec 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .github/actions/setup-effekt/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inputs:
required: false
default: '18'
install-dependencies:
description: 'Whether to install system dependencies (Linux only)'
description: 'Whether to install system dependencies (Linux & macOS only)'
required: false
default: 'false'
install-valgrind:
Expand All @@ -41,6 +41,7 @@ runs:
with:
node-version: ${{ inputs.node-version }}


# Only run the following on Linux-based runners
- name: Update apt database
if: ${{ inputs.install-dependencies == 'true' && runner.os == 'Linux' }}
Expand All @@ -66,3 +67,17 @@ runs:
if: ${{ inputs.install-dependencies == 'true' && runner.os == 'Linux' }}
run: sudo apt-get install -y libuv1-dev
shell: bash


# Only run the following on macOS-based runners
- name: Install LLVM ${{ inputs.llvm-version }} (macOS)
if: ${{ inputs.install-dependencies == 'true' && runner.os == 'macOS' }}
run: |
brew install llvm@${{ inputs.llvm-version }}
echo "$(brew --prefix llvm@${{ inputs.llvm-version }})/bin" >> $GITHUB_PATH
shell: bash

- name: Install libuv (macOS)
if: ${{ inputs.install-dependencies == 'true' && runner.os == 'macOS' }}
run: brew install libuv
shell: bash
21 changes: 20 additions & 1 deletion .github/workflows/ci-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,25 @@ jobs:
- name: Run Windows smoke test
run: sbt "effektJVM/testOnly effekt.JavaScriptTests -- --tests=.*examples[\\/]*pos[\\/]*sideeffects.*"

macos-llvm-tests:
name: "macOS LLVM Smoke Tests"
needs: build-and-compile
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
with:
submodules: 'true'

- uses: ./.github/actions/setup-effekt
with:
install-dependencies: 'true'

- name: Compile project
run: sbt Test/compile

- name: Run macOS LLVM smoke tests (with debug)
run: EFFEKT_DEBUG=1 sbt "effektJVM/testOnly effekt.LLVMTests -- --tests=.*benchmarks[\\/]*input_output[\\/].*"

js-tests:
name: "JS Backend"
needs: build-and-compile
Expand Down Expand Up @@ -146,5 +165,5 @@ jobs:

- uses: ./.github/actions/restore-build-cache

- name: Run LLVM backend tests
- name: Run LLVM backend tests (with debug & valgrind)
run: EFFEKT_VALGRIND=1 EFFEKT_DEBUG=1 sbt effektJVM/testBackendLLVM
4 changes: 3 additions & 1 deletion .jvmopts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
-Xms1g
-Xmx4g
-Xms1g
-Xss32m
-Xmx8g
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ lazy val effekt: CrossProject = crossProject(JSPlatform, JVMPlatform).in(file("e
val osName = System.getProperty("os.name").toLowerCase
val shebang =
if (osName.contains("win"))
"#! /usr/bin/env java -jar\n"
"#! /usr/bin/env java -Xss32m -jar\n"
else
"#! /usr/bin/env -S java -jar\n"
"#! /usr/bin/env -S java -Xss32m -jar\n"

IO.write(binary, shebang)
IO.append(binary, IO.readBytes(jarfile))
Expand Down
2 changes: 1 addition & 1 deletion effekt/jvm/src/main/scala/effekt/Runner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ object LLVMRunner extends Runner[String] {

override def includes(path: File): List[File] = List(path / ".." / "llvm")

lazy val clangCmd = discoverExecutable(List("clang-20", "clang-19", "clang-18", "clang"), List("--version"))
lazy val clangCmd = discoverExecutable(List("clang-21", "clang-20", "clang-19", "clang-18", "clang"), List("--version"))

def checkSetup(): Either[String, Unit] =
clangCmd.getOrElseAborting { return Left("Cannot find clang. This is required to use the LLVM backend.") }
Expand Down
2 changes: 1 addition & 1 deletion effekt/jvm/src/test/scala/effekt/LSPTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ class LSPTests extends FunSuite {
| Nil,
| Nil,
| List(
| Val(foo_whatever, Data(Int_whatever, Nil), Return(Literal(42, Data(Int_whatever, Nil))))
| Val(foo_whatever, Return(Literal(42, Data(Int_whatever, Nil))))
| ),
| List(foo_whatever)
|)""".stripMargin
Expand Down
8 changes: 4 additions & 4 deletions effekt/jvm/src/test/scala/effekt/core/OptimizerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class OptimizerTests extends CoreTests {
test("inline toplevel"){
val input =
""" def foo = { () => return 42 }
| def main = { () => (foo : () => Unit @ {})() }
| def main = { () => (foo : () => Int @ {})() }
|""".stripMargin

val expected =
Expand All @@ -164,7 +164,7 @@ class OptimizerTests extends CoreTests {
test("inline with argument"){
val input =
""" def foo = { (n: Int) => return n:Int }
| def main = { () => (foo : (Int) => Unit @ {})(42) }
| def main = { () => (foo : (Int) => Int @ {})(42) }
|""".stripMargin

val expected =
Expand All @@ -181,7 +181,7 @@ class OptimizerTests extends CoreTests {
| (f : (Int) => Int @ {f})(1)
| }
| def main = { () =>
| (hof : (){f : (Int) => Int} => Int @ {})(){ (foo : (Int) => Unit @ {}) }
| (hof : (){f : (Int) => Int} => Int @ {})(){ (foo : (Int) => Int @ {}) }
| }
|""".stripMargin

Expand All @@ -199,7 +199,7 @@ class OptimizerTests extends CoreTests {
| (f : (Int) => Int @ {f})(1)
| }
| def main = { () =>
| (hof : (){f : (Int) => Int} => Int @ {})(){ (foo : (Int) => Unit @ {}) }
| (hof : (){f : (Int) => Int} => Int @ {})(){ (foo : (Int) => Int @ {}) }
| }
|""".stripMargin

Expand Down
19 changes: 9 additions & 10 deletions effekt/jvm/src/test/scala/effekt/core/PatternMatchingTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package effekt
package core
import effekt.symbols
import kiama.util.StringSource

import PatternMatchingCompiler.*
import core.Type.{TBoolean, TInt, TUnit}
import core.Type.{ TBoolean, TInt, TString, TUnit }

class PatternMatchingTests extends CoreTests {

Expand Down Expand Up @@ -47,7 +46,7 @@ class PatternMatchingTests extends CoreTests {
}

test("Sanity check: compiling empty list of clauses") {
assertEquals(compile(Nil), core.Hole(effekt.source.Span.missing))
assertEquals(compile(Nil, TUnit), core.Hole(TUnit, effekt.source.Span.missing))
}

test("Simple guard") {
Expand All @@ -71,16 +70,16 @@ class PatternMatchingTests extends CoreTests {
Clause(
List(
Condition.Patterns(Map(sc -> Pattern.Any(x.id))),
Condition.Val(p.id, TBoolean, trivalPredicate),
Condition.Val(p.id, trivalPredicate),
Condition.Predicate(p)),
b1, Nil, List(x)),
Clause(
List(
Condition.Patterns(Map(sc -> Pattern.Ignore()))),
b2, Nil, List())))
b2, Nil, List())), TString)

val expected =
Val(p.id, TBoolean, trivalPredicate,
Val(p.id, trivalPredicate,
If(p,
jump(b1, sc),
jump(b2)))
Expand Down Expand Up @@ -125,21 +124,21 @@ class PatternMatchingTests extends CoreTests {
Clause(
List(
Condition.Patterns(Map(opt -> Pattern.Tag(SomeC, List(), List(SomeC, NoneC), List(Pattern.Any(v.id) -> TInt)))),
Condition.Val(p.id, TBoolean, trivalPredicate),
Condition.Val(p.id, trivalPredicate),
Condition.Predicate(p)),
b1, Nil, List(v)),
Clause(
List(
Condition.Patterns(Map(opt -> Pattern.Ignore()))),
b2, Nil, List())))
b2, Nil, List())), TUnit)

// opt match {
// case Some(tmp) => val p = return v > 0; if (p) { b1(tmp) } else { b2() }
// case _ => b2()
// }
val expected = Match(opt,
val expected = Match(opt, TUnit,
List((SomeC, BlockLit(Nil, Nil, List(ValueParam(tmp.id, tmp.tpe)), Nil,
Val(p.id, TBoolean, trivalPredicate, If(p,
Val(p.id, trivalPredicate, If(p,
App(b1, Nil, List(tmp), Nil),
App(b2, Nil, Nil, Nil)))))),
Some(App(b2, Nil, Nil, Nil)))
Expand Down
176 changes: 0 additions & 176 deletions effekt/jvm/src/test/scala/effekt/core/PolymorphismBoxingTests.scala

This file was deleted.

Loading
Loading