Skip to content

Commit 4dec6e7

Browse files
committed
Address missing changes for module checking
1 parent 4412c65 commit 4dec6e7

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
@@ -417,7 +417,10 @@ extends Importer:
417417
raise(ErrorReport(msg"Multiple declarations of symbol '$name'" -> N ::
418418
decls.map(msg"declared here" -> _.toLoc)))
419419
val sig = decls.collectFirst:
420-
case td if td.signature.isDefined => td.signature.get
420+
case td
421+
if td.annotatedResultType.isDefined
422+
&& td.paramLists.isEmpty
423+
=> td.annotatedResultType.get
421424
sig.foreach: sig =>
422425
newSignatureTrees += name -> sig
423426

@@ -535,34 +538,29 @@ extends Importer:
535538
case R(id) =>
536539
val sym = members.getOrElse(id.name, die)
537540
val owner = ctx.outer
538-
val isModMember = owner.fold(false)(_.isInstanceOf[ModuleSymbol])
541+
val isModMember = owner.exists(_.isInstanceOf[ModuleSymbol])
539542
val tdf = ctx.nest(N).givenIn:
540543
// * Add type parameters to context
541544
val (tps, newCtx1) = td.typeParams match
542545
case S(t) => typeParams(t)
543546
case N => (N, ctx)
544547
// * Add parameters to context
545-
val (pss, newCtx) =
548+
val (pss, newCtx) =
546549
td.paramLists.foldLeft(Ls[ParamList](), newCtx1):
547550
case ((pss, ctx), ps) =>
548551
val (qs, newCtx) = params(ps)(using ctx)
549552
(pss :+ ParamList(ParamListFlags.empty, qs), newCtx)
550553
// * Elaborate signature
551-
val st = td.signature.orElse(newSignatureTrees.get(id.name))
554+
val st = td.annotatedResultType.orElse(newSignatureTrees.get(id.name))
552555
val s = st.map(term(_)(using newCtx))
553556
val b = rhs.map(term(_)(using newCtx))
554557
val r = FlowSymbol(s"‹result of ${sym}", nextUid)
555558
val tdf = TermDefinition(owner, k, sym, pss, s, b, r,
556559
TermDefFlags.empty.copy(isModMember = isModMember))
557560
sym.defn = S(tdf)
558-
559-
// the return type of the function
560-
val result = td.head match
561-
case InfixApp(_, Keyword.`:`, rhs) => S(term(rhs)(using newCtx))
562-
case _ => N
563561

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

789787
/** Checks if a term evaluates to a module value. */
790788
def evalsToModule(t: Term): Bool =
791789
def isModule(t: Tree): Bool = t match
792790
case TypeDef(Mod, _, _, _) => true
793791
case _ => false
794-
def returnsModule(t: TermDef): Bool = t.signature match
792+
def returnsModule(t: TermDef): Bool = t.annotatedResultType match
795793
case S(TypeDef(Mod, _, N, N)) => true
796794
case _ => false
797795
t match
798796
case Term.Blk(_, res) => evalsToModule(res)
799797
case Term.App(lhs, rhs) => lhs.symbol match
800-
case S(sym: BlockMemberSymbol) => sym.trmTree.fold(false)(returnsModule)
798+
case S(sym: BlockMemberSymbol) => sym.trmTree.exists(returnsModule)
801799
case _ => false
802800
case t => t.symbol match
803-
case S(sym: BlockMemberSymbol) => sym.modTree.fold(false)(isModule)
801+
case S(sym: BlockMemberSymbol) => sym.modTree.exists(isModule)
804802
case _ => false
805803

806804
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)