Add typed Kotlin mutable-list removal

ober

ff78ab1c8ca7eaba47143bead627ae7facc75ba2

diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index 8e12162..ff7a3e1 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -1725,6 +1725,45 @@
                    (list (cons 'inner-type inner-type))))
             (append errors type-errors))))))
 
+  (def (infer-mutable-list-remove args env type-names expr)
+    (if (not (= (length args) 2))
+      (values #f (bad-constructor-arity expr 'mutable-list-remove! 2 args))
+      (let-values ([(arg-irs errors) (infer-args args env type-names)])
+        (let* ([types (ir-list-types arg-irs)]
+               [list-type (car types)]
+               [value-type (cadr types)]
+               [inner-type (mutable-list-inner-type list-type)]
+               [type-errors
+                (append
+                  (if inner-type
+                    '()
+                    (list
+                      (make-check-error
+                        'argument-type-mismatch
+                        "mutable-list-remove! expects a MutableList value"
+                        expr
+                        (and (pair? args) (expr-source (car args))))))
+                  (if (or (not inner-type)
+                          (and value-type
+                               (type-assignable? value-type inner-type)))
+                    '()
+                    (list
+                      (make-check-error
+                        'argument-type-mismatch
+                        "mutable-list-remove! value must match the list element type"
+                        expr
+                        (and (pair? (cdr args))
+                             (expr-source (cadr args)))))))]
+               [ok? (and (all-irs-valid? arg-irs)
+                         (null? errors)
+                         (null? type-errors))])
+          (values
+            (and ok?
+                 (make-typed-ir-call 'Unit (expr-source expr)
+                   'jvm-mutable-list-remove 'mutable-list-remove! arg-irs
+                   (list (cons 'inner-type inner-type))))
+            (append errors type-errors))))))
+
   (def (infer-mutable-list-set args env type-names expr)
     (if (not (= (length args) 3))
       (values #f (bad-constructor-arity expr 'mutable-list-set! 3 args))
@@ -2277,6 +2316,8 @@
               (infer-mutable-list-empty args env type-names expr)]
              [(mutable-list-add!)
               (infer-mutable-list-add args env type-names expr)]
+             [(mutable-list-remove!)
+              (infer-mutable-list-remove args env type-names expr)]
              [(mutable-list-set!)
               (infer-mutable-list-set args env type-names expr)]
              [(bytes-build)
diff --git a/lib/jerboa/typed/core.ss b/lib/jerboa/typed/core.ss
index 6178575..fa2a57a 100644
--- a/lib/jerboa/typed/core.ss
+++ b/lib/jerboa/typed/core.ss
@@ -135,6 +135,7 @@
       jvm-list-ref
       jvm-mutable-list-empty
       jvm-mutable-list-add
+      jvm-mutable-list-remove
       jvm-mutable-list-set
       record-ctor
       record-pred
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index 5113836..c2ba1b2 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -338,6 +338,12 @@
              (make-kt-expr-stmt
                (make-kt-member-call (car args) 'add (list (cadr args)))))
            (make-kt-lit 'Unit '()))]
+        [(jvm-mutable-list-remove)
+         (make-kt-block
+           (list
+             (make-kt-expr-stmt
+               (make-kt-member-call (car args) 'remove (list (cadr args)))))
+           (make-kt-lit 'Unit '()))]
         [(jvm-mutable-list-set)
          (make-kt-block
            (list
diff --git a/tests/test-typed-checker.ss b/tests/test-typed-checker.ss
index 8ebff4b..707a1eb 100644
--- a/tests/test-typed-checker.ss
+++ b/tests/test-typed-checker.ss
@@ -861,6 +861,36 @@
          (Pane-id x))))
   '(argument-type-mismatch))
 
+(test "mutable-list remove accepts matching element"
+  (error-kinds
+    '(typed-library (body mutable-list-remove-ok)
+       (export remove-cell!)
+       (record Cell
+         ((id : Nat)))
+       (def (remove-cell! (cells : (MutableList Cell)) (cell : Cell)) : Unit
+         (mutable-list-remove! cells cell))))
+  '())
+
+(test "mutable-list remove rejects immutable list receiver"
+  (error-kinds
+    '(typed-library (body mutable-list-remove-receiver)
+       (export remove-cell!)
+       (record Cell
+         ((id : Nat)))
+       (def (remove-cell! (cells : (List Cell)) (cell : Cell)) : Unit
+         (mutable-list-remove! cells cell))))
+  '(argument-type-mismatch))
+
+(test "mutable-list remove rejects wrong element type"
+  (error-kinds
+    '(typed-library (body mutable-list-remove-element)
+       (export remove-name!)
+       (record Cell
+         ((id : Nat)))
+       (def (remove-name! (cells : (MutableList Cell)) (name : String)) : Unit
+         (mutable-list-remove! cells name))))
+  '(argument-type-mismatch))
+
 (test "variant constructor and predicate calls"
   (error-kinds
     '(typed-library (body variant-ok)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index e8ba46b..6d14afe 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -548,7 +548,7 @@
 (define list-form
   '(typed-library (sample typed lists)
      (export make-Cell Cell? Cell-x listCount firstX secondName
-             emptyCells appendCell replaceCell)
+             emptyCells appendCell removeCell replaceCell)
      (type Int32)
      (type Float32)
      (record Cell
@@ -564,6 +564,8 @@
        (mutable-list-empty Cell))
      (def (appendCell (cells : (MutableList Cell)) (cell : Cell)) : Unit
        (mutable-list-add! cells cell))
+     (def (removeCell (cells : (MutableList Cell)) (cell : Cell)) : Unit
+       (mutable-list-remove! cells cell))
      (def (replaceCell (cells : (MutableList Cell)) (cell : Cell)) : Unit
        (mutable-list-set! cells (int32 0) cell))))
 
@@ -587,6 +589,9 @@
 (test-contains "MutableList add lowers to Kotlin add"
   list-kotlin
   "cells.add(cell)")
+(test-contains "MutableList remove lowers to Kotlin remove"
+  list-kotlin
+  "cells.remove(cell)")
 (test-contains "MutableList set lowers to indexed assignment"
   list-kotlin
   "cells[0] = cell")