Skip to content

Commit 20a65e0

Browse files
FlandiaYingmanLPTK
authored andcommitted
Enforce rules on module parameters
1 parent c7206ef commit 20a65e0

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,15 @@ extends Importer:
640640
else VarSymbol(id, nextUid)
641641

642642
def param(t: Tree): Ctxl[Ls[Param]] = t match
643-
case TypeDef(Mod, inner, N, N) => param(inner)
644-
.map(p => p.copy(flags = p.flags.copy(mod = true)))
643+
case TypeDef(Mod, inner, N, N) =>
644+
val ps = param(inner).map(p => p.copy(flags = p.flags.copy(mod = true)))
645+
for p <- ps if p.flags.mod do p.sign match
646+
case N =>
647+
raise(ErrorReport(msg"Module parameters must have explicit types." -> t.toLoc :: Nil))
648+
case S(ret) if ModuleChecker.isTypeParam(ret) =>
649+
raise(ErrorReport(msg"Module parameters must have concrete types." -> t.toLoc :: Nil))
650+
case _ => ()
651+
ps
645652
case _ => t.param.map: (p, t) =>
646653
Param(FldFlags.empty, fieldOrVarSym(ParamBind, p), t.map(term))
647654

@@ -710,7 +717,15 @@ extends Importer:
710717
while trav.changed do
711718
trav.changed = false
712719
go(s)
720+
721+
object ModuleChecker:
713722

723+
/** Checks if a term is a reference to a type parameter. */
724+
def isTypeParam(t: Term): Bool = t.symbol
725+
.filter(_.isInstanceOf[VarSymbol])
726+
.flatMap(_.asInstanceOf[VarSymbol].decl)
727+
.fold(false)(_.isInstanceOf[TyParam])
728+
714729
class VarianceTraverser(var changed: Bool = true) extends Traverser:
715730
override def traverseType(pol: Pol)(trm: Term): Unit = trm match
716731
case Term.TyApp(lhs, targs) =>

hkmc2/shared/src/test/mlscript/basics/ModuleMethods.mls

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,18 @@ module M with {
77
// module method foo
88
fun foo(x) = x
99
}
10+
11+
:e
12+
fun f1(module m)
13+
//│ ╔══[ERROR] Module parameters must have explicit types.
14+
//│ ║ l.12: fun f1(module m)
15+
//│ ╙── ^
16+
17+
:e
18+
fun f2[T](module m: T)
19+
//│ ╔══[ERROR] Module parameters must have concrete types.
20+
//│ ║ l.18: fun f2[T](module m: T)
21+
//│ ╙── ^^^^
22+
23+
24+
fun ok1(module m: M)

0 commit comments

Comments
 (0)