Skip to content

Commit 9c97e7c

Browse files
committed
Address missing changes for module checking
1 parent 1b78690 commit 9c97e7c

File tree

7 files changed

+53
-43
lines changed

7 files changed

+53
-43
lines changed

hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,10 @@ extends Importer:
419419
raise(ErrorReport(msg"Multiple declarations of symbol '$name'" -> N ::
420420
decls.map(msg"declared here" -> _.toLoc)))
421421
val sig = decls.collectFirst:
422-
case td if td.signature.isDefined => td.signature.get
422+
case td
423+
if td.annotatedResultType.isDefined
424+
&& td.paramLists.isEmpty
425+
=> td.annotatedResultType.get
423426
sig.foreach: sig =>
424427
newSignatureTrees += name -> sig
425428

@@ -537,34 +540,29 @@ extends Importer:
537540
case R(id) =>
538541
val sym = members.getOrElse(id.name, die)
539542
val owner = ctx.outer
540-
val isModMember = owner.fold(false)(_.isInstanceOf[ModuleSymbol])
543+
val isModMember = owner.exists(_.isInstanceOf[ModuleSymbol])
541544
val tdf = ctx.nest(N).givenIn:
542545
// * Add type parameters to context
543546
val (tps, newCtx1) = td.typeParams match
544547
case S(t) => typeParams(t)
545548
case N => (N, ctx)
546549
// * Add parameters to context
547-
val (pss, newCtx) =
550+
val (pss, newCtx) =
548551
td.paramLists.foldLeft(Ls[ParamList](), newCtx1):
549552
case ((pss, ctx), ps) =>
550553
val (qs, newCtx) = params(ps)(using ctx)
551554
(pss :+ ParamList(ParamListFlags.empty, qs), newCtx)
552555
// * Elaborate signature
553-
val st = td.signature.orElse(newSignatureTrees.get(id.name))
556+
val st = td.annotatedResultType.orElse(newSignatureTrees.get(id.name))
554557
val s = st.map(term(_)(using newCtx))
555558
val b = rhs.map(term(_)(using newCtx))
556559
val r = FlowSymbol(s"‹result of ${sym}", nextUid)
557560
val tdf = TermDefinition(owner, k, sym, pss, s, b, r,
558561
TermDefFlags.empty.copy(isModMember = isModMember))
559562
sym.defn = S(tdf)
560-
561-
// the return type of the function
562-
val result = td.head match
563-
case InfixApp(_, Keyword.`:`, rhs) => S(term(rhs)(using newCtx))
564-
case _ => N
565563

566564
// indicates if the function really returns a module
567-
val em = b.fold(false)(ModuleChecker.evalsToModule)
565+
val em = b.exists(ModuleChecker.evalsToModule)
568566
// indicates if the function marks its result as "module"
569567
val mm = st match
570568
case Some(TypeDef(Mod, _, N, N)) => true
@@ -786,23 +784,23 @@ extends Importer:
786784
def isTypeParam(t: Term): Bool = t.symbol
787785
.filter(_.isInstanceOf[VarSymbol])
788786
.flatMap(_.asInstanceOf[VarSymbol].decl)
789-
.fold(false)(_.isInstanceOf[TyParam])
787+
.exists(_.isInstanceOf[TyParam])
790788

791789
/** Checks if a term evaluates to a module value. */
792790
def evalsToModule(t: Term): Bool =
793791
def isModule(t: Tree): Bool = t match
794792
case TypeDef(Mod, _, _, _) => true
795793
case _ => false
796-
def returnsModule(t: TermDef): Bool = t.signature match
794+
def returnsModule(t: TermDef): Bool = t.annotatedResultType match
797795
case S(TypeDef(Mod, _, N, N)) => true
798796
case _ => false
799797
t match
800798
case Term.Blk(_, res) => evalsToModule(res)
801799
case Term.App(lhs, rhs) => lhs.symbol match
802-
case S(sym: BlockMemberSymbol) => sym.trmTree.fold(false)(returnsModule)
800+
case S(sym: BlockMemberSymbol) => sym.trmTree.exists(returnsModule)
803801
case _ => false
804802
case t => t.symbol match
805-
case S(sym: BlockMemberSymbol) => sym.modTree.fold(false)(isModule)
803+
case S(sym: BlockMemberSymbol) => sym.modTree.exists(isModule)
806804
case _ => false
807805

808806
class VarianceTraverser(var changed: Bool = true) extends Traverser:

hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ trait TypeOrTermDef:
216216

217217
def head: Tree
218218

219-
lazy val (symbName, name, paramLists, typeParams, signature)
219+
lazy val (symbName, name, paramLists, typeParams, annotatedResultType)
220220
: (Opt[Tree], Diagnostic \/ Ident, Ls[Tup], Opt[TyTup], Opt[Tree]) =
221221
def rec(t: Tree, symbName: Opt[Tree]):
222222
(Opt[Tree], Diagnostic \/ Ident, Ls[Tup], Opt[TyTup], Opt[Tree]) =
Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
class C with {
1+
:js
2+
3+
class C with
24
// regular method foo
35
fun foo(x) = x
4-
}
56

6-
module M with {
7+
module M with
78
// module method foo
89
fun foo(x) = x
910
// module method self
1011
fun self(): module M = M
11-
}
1212

1313
:e
1414
fun f1(module m)
@@ -23,57 +23,72 @@ fun f2[T](module m: T)
2323
//│ ╙── ^^^^
2424

2525
:e
26-
module N with {
26+
module N with
2727
fun f3() = M
28-
}
2928
//│ ╔══[ERROR] Function returning module values must have explicit return types.
3029
//│ ║ l.27: fun f3() = M
3130
//│ ╙── ^^^^
3231

3332
:e
34-
module N with {
33+
module N with
3534
fun f4[T](): module T = M
36-
}
3735
//│ ╔══[ERROR] Function returning module values must have concrete return types.
38-
//│ ║ l.35: fun f4[T](): module T = M
36+
//│ ║ l.34: fun f4[T](): module T = M
3937
//│ ╙── ^^^^^^^^^^^^^^^^^
4038

4139
:e
42-
module N with {
40+
module N with
4341
fun f5(): M = M
44-
}
4542
//│ ╔══[ERROR] The return type of functions returning module values must be prefixed with module keyword.
46-
//│ ║ l.43: fun f5(): M = M
43+
//│ ║ l.41: fun f5(): M = M
4744
//│ ╙── ^^^^^^^
4845

4946

50-
fun f6(m: M)
47+
fun f6(m: M) = m
5148

5249
:e
5350
f6(M)
5451
//│ ╔══[ERROR] Only module parameters may receive module arguments (values).
55-
//│ ║ l.53: f6(M)
52+
//│ ║ l.50: f6(M)
5653
//│ ╙── ^
54+
//│ = M { class: [class M] }
5755

5856
:e
5957
f6(M.self())
6058
//│ ╔══[ERROR] Only module parameters may receive module arguments (values).
61-
//│ ║ l.59: f6(M.self())
59+
//│ ║ l.57: f6(M.self())
6260
//│ ╙── ^^^^^^^^
61+
//│ = M { class: [class M] }
6362

6463
:e
6564
fun f7(): module M
6665
//│ ╔══[ERROR] Only module methods may return module values.
67-
//│ ║ l.65: fun f7(): module M
66+
//│ ║ l.64: fun f7(): module M
6867
//│ ╙── ^^^^^^^^^^^^^^
6968

7069

71-
fun ok1(module m: M)
70+
:todo // should be an error
71+
:e
72+
fun f8(module m: M) = m
73+
74+
:e
75+
fun f9(module m: M): module M = m
76+
//│ ╔══[ERROR] Only module methods may return module values.
77+
//│ ║ l.75: fun f9(module m: M): module M = m
78+
//│ ╙── ^^^^^^^^^^^^^^^^^^^^^^^^^
79+
80+
module Test with
81+
fun ok1(module m: M): module M = m
7282

73-
module N with {
83+
let ok1 = Test.ok1
84+
//│ ok1 = [Function: ok1]
85+
86+
module N with
7487
fun ok2(): module M = M
75-
}
7688

7789
ok1(M)
90+
//│ = M { class: [class M] }
7891

7992
ok1(M.self())
93+
//│ = M { class: [class M] }
94+

hkmc2/shared/src/test/mlscript/bbml/bbBorrowing.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ letreg of r =>
6161
123
6262
if next(it) > 0 then () => 0 else () => clear(b)
6363
k()
64-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref($scrut@123),Lit(BoolLit(true)),Else(Lam(List(),Lit(IntLit(0))))),Else(Lam(List(),App(Sel(Ref(globalThis:block#5),Ident(clear)),Tup(List(Fld(‹›,Ref(b@112),None))))))) (of class hkmc2.semantics.Split$Cons)
64+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref($scrut@102),Lit(BoolLit(true)),Else(Lam(List(),Lit(IntLit(0))))),Else(Lam(List(),App(Sel(Ref(globalThis:block#5),Ident(clear)),Tup(List(Fld(‹›,Ref(b@91),None))))))) (of class hkmc2.semantics.Split$Cons)
6565

6666
:e
6767
letreg of r =>

hkmc2/shared/src/test/mlscript/bbml/bbCheck.mls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ high(x => x + 1)
103103

104104
:fixme
105105
(if false then x => x else y => y): [A] -> A -> A
106-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref($scrut@88),Lit(BoolLit(true)),Else(Lam(List(Param(‹›,x@89,None)),Ref(x@89)))),Else(Lam(List(Param(‹›,y@87,None)),Ref(y@87)))) (of class hkmc2.semantics.Split$Cons)
106+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref($scrut@87),Lit(BoolLit(true)),Else(Lam(List(Param(‹›,x@88,None)),Ref(x@88)))),Else(Lam(List(Param(‹›,y@86,None)),Ref(y@86)))) (of class hkmc2.semantics.Split$Cons)
107107

108108

109109
fun baz: Int -> (([A] -> A -> A), Int) -> Int

hkmc2/shared/src/test/mlscript/bbml/bbGPCE.mls

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fun power(x) = case
77
0 then `1.0
88
n then x `*. power(x)(n - 1)
99
power
10-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@35),Lit(IntLit(0)),Else(Quoted(Lit(DecLit(1.0))))),Let(n@36,Ref(caseScrut@35),Else(Quoted(App(Ref(builtin:*),Tup(List(Fld(‹›,Unquoted(Ref(x@33)),None), Fld(‹›,Unquoted(App(App(Sel(Ref(globalThis:block#0),Ident(power)),Tup(List(Fld(‹›,Ref(x@33),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@36),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),None)))))))) (of class hkmc2.semantics.Split$Cons)
10+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@34),Lit(IntLit(0)),Else(Quoted(Lit(DecLit(1.0))))),Let(n@35,Ref(caseScrut@34),Else(Quoted(App(Ref(builtin:*),Tup(List(Fld(‹›,Unquoted(Ref(x@32)),None), Fld(‹›,Unquoted(App(App(Sel(Ref(globalThis:block#0),Ident(power)),Tup(List(Fld(‹›,Ref(x@32),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@35),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),None)))))))) (of class hkmc2.semantics.Split$Cons)
1111

1212

1313
fun id: [A] -> A -> A
@@ -57,7 +57,7 @@ fun body(x, y) = case
5757
fun gib_naive(n) =
5858
(x, y) `=> body(x, y)(n)
5959
let gn5 = run(gib_naive(5))
60-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@88),Lit(IntLit(0)),Else(Ref(x@84))),Cons(Branch(Ref(caseScrut@88),Lit(IntLit(1)),Else(Ref(y@85))),Let(n@89,Ref(caseScrut@88),Else(App(App(Sel(Ref(globalThis:block#7),Ident(body)),Tup(List(Fld(‹›,Ref(y@85),None), Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@84)),None), Fld(‹›,Unquoted(Ref(y@85)),None))))),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@89),None), Fld(‹›,Lit(IntLit(1)),None)))),None)))))))) (of class hkmc2.semantics.Split$Cons)
60+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@82),Lit(IntLit(0)),Else(Ref(x@78))),Cons(Branch(Ref(caseScrut@82),Lit(IntLit(1)),Else(Ref(y@79))),Let(n@83,Ref(caseScrut@82),Else(App(App(Sel(Ref(globalThis:block#7),Ident(body)),Tup(List(Fld(‹›,Ref(y@79),None), Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@78)),None), Fld(‹›,Unquoted(Ref(y@79)),None))))),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@83),None), Fld(‹›,Lit(IntLit(1)),None)))),None)))))))) (of class hkmc2.semantics.Split$Cons)
6161

6262
fun bind(rhs, k) = `let x = rhs `in k(x)
6363
bind
@@ -70,7 +70,7 @@ fun body(x, y) = case
7070
0 then x
7171
1 then y
7272
n then bind of x `+ y, (z => body(y, z)(n - 1)): [C] -> CodeBase[out Int, out C, out Any] -> CodeBase[out C, out Any]
73-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@116),Lit(IntLit(0)),Else(Ref(x@113))),Cons(Branch(Ref(caseScrut@116),Lit(IntLit(1)),Else(Ref(y@114))),Let(n@117,Ref(caseScrut@116),Else(App(Sel(Ref(globalThis:block#8),Ident(bind)),Tup(List(Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@113)),None), Fld(‹›,Unquoted(Ref(y@114)),None))))),None), Fld(‹›,Lam(List(Param(‹›,z@120,None)),App(App(Sel(Ref(globalThis:block#9),Ident(body)),Tup(List(Fld(‹›,Ref(y@114),None), Fld(‹›,Ref(z@120),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@117),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),Some(Forall(List(QuantVar(C@124,None,None)),FunTy(Tup(List(Fld(‹›,TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@124))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))),TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Ref(C@124))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))))))))))) (of class hkmc2.semantics.Split$Cons)
73+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@109),Lit(IntLit(0)),Else(Ref(x@106))),Cons(Branch(Ref(caseScrut@109),Lit(IntLit(1)),Else(Ref(y@107))),Let(n@110,Ref(caseScrut@109),Else(App(Sel(Ref(globalThis:block#8),Ident(bind)),Tup(List(Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@106)),None), Fld(‹›,Unquoted(Ref(y@107)),None))))),None), Fld(‹›,Lam(List(Param(‹›,z@113,None)),App(App(Sel(Ref(globalThis:block#9),Ident(body)),Tup(List(Fld(‹›,Ref(y@107),None), Fld(‹›,Ref(z@113),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@110),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),Some(Forall(List(QuantVar(C@117,None,None)),FunTy(Tup(List(Fld(‹›,TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@117))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))),TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Ref(C@117))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))))))))))) (of class hkmc2.semantics.Split$Cons)
7474

7575
fun bind: [G] -> (CodeBase[out Int, out G, out Any], [C] -> CodeBase[out Int, out C, out Any] -> CodeBase[out Int, out C | G, out Any]) -> CodeBase[out Int, out G, out Any]
7676
fun bind(rhs, k) = `let x = rhs `in k(x)
@@ -85,7 +85,7 @@ fun body(x, y) = case
8585
1 then y
8686
n then bind of x `+ y, (z => body(y, z)(n - 1)): [C] -> CodeBase[out Int, out C, out Any] -> CodeBase[out Int, out C, out Any]
8787
body
88-
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@146),Lit(IntLit(0)),Else(Ref(x@143))),Cons(Branch(Ref(caseScrut@146),Lit(IntLit(1)),Else(Ref(y@144))),Let(n@147,Ref(caseScrut@146),Else(App(Sel(Ref(globalThis:block#10),Ident(bind)),Tup(List(Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@143)),None), Fld(‹›,Unquoted(Ref(y@144)),None))))),None), Fld(‹›,Lam(List(Param(‹›,z@150,None)),App(App(Sel(Ref(globalThis:block#11),Ident(body)),Tup(List(Fld(‹›,Ref(y@144),None), Fld(‹›,Ref(z@150),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@147),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),Some(Forall(List(QuantVar(C@154,None,None)),FunTy(Tup(List(Fld(‹›,TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@154))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))),TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@154))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))))))))))) (of class hkmc2.semantics.Split$Cons)
88+
//│ /!!!\ Uncaught error: scala.MatchError: Cons(Branch(Ref(caseScrut@136),Lit(IntLit(0)),Else(Ref(x@133))),Cons(Branch(Ref(caseScrut@136),Lit(IntLit(1)),Else(Ref(y@134))),Let(n@137,Ref(caseScrut@136),Else(App(Sel(Ref(globalThis:block#10),Ident(bind)),Tup(List(Fld(‹›,Quoted(App(Sel(Ref(globalThis:import#bbPredef),Ident(+)),Tup(List(Fld(‹›,Unquoted(Ref(x@133)),None), Fld(‹›,Unquoted(Ref(y@134)),None))))),None), Fld(‹›,Lam(List(Param(‹›,z@140,None)),App(App(Sel(Ref(globalThis:block#11),Ident(body)),Tup(List(Fld(‹›,Ref(y@134),None), Fld(‹›,Ref(z@140),None)))),Tup(List(Fld(‹›,App(Sel(Ref(globalThis:import#bbPredef),Ident(-)),Tup(List(Fld(‹›,Ref(n@137),None), Fld(‹›,Lit(IntLit(1)),None)))),None))))),Some(Forall(List(QuantVar(C@144,None,None)),FunTy(Tup(List(Fld(‹›,TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@144))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))),TyApp(Sel(Ref(globalThis:import#bbPredef),Ident(CodeBase)),List(WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Int)))), WildcardTy(None,Some(Ref(C@144))), WildcardTy(None,Some(Sel(Ref(globalThis:import#Prelude),Ident(Any)))))),None))))))))))) (of class hkmc2.semantics.Split$Cons)
8989

9090
fun gib(n) = (x, y) `=> body(x, y)(n)
9191
let g5 = run(gib(5))

hkmc2/shared/src/test/mlscript/bbml/bbTODOs.mls

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ fun id: [A] -> A -> A => x = x
2424
//│ ╔══[ERROR] Name not found: x
2525
//│ ║ l.20: fun id: [A] -> A -> A => x = x
2626
//│ ╙── ^
27-
//│ ╔══[ERROR] Name not found: x
28-
//│ ║ l.20: fun id: [A] -> A -> A => x = x
29-
//│ ╙── ^
3027
//│ /!!!\ Uncaught error: scala.MatchError: Lam(List(Param(‹›,A@36,None)),Error) (of class hkmc2.semantics.Term$Lam)
3128

3229

0 commit comments

Comments
 (0)