Skip to content

Commit 064ba0e

Browse files
Enforce rules on module parameters
1 parent ffa00ac commit 064ba0e

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
@@ -638,8 +638,15 @@ extends Importer:
638638
else VarSymbol(id, nextUid)
639639

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

@@ -708,7 +715,15 @@ extends Importer:
708715
while trav.changed do
709716
trav.changed = false
710717
go(s)
718+
719+
object ModuleChecker:
711720

721+
/** Checks if a term is a reference to a type parameter. */
722+
def isTypeParam(t: Term): Bool = t.symbol
723+
.filter(_.isInstanceOf[VarSymbol])
724+
.flatMap(_.asInstanceOf[VarSymbol].decl)
725+
.fold(false)(_.isInstanceOf[TyParam])
726+
712727
class VarianceTraverser(var changed: Bool = true) extends Traverser:
713728
override def traverseType(pol: Pol)(trm: Term): Unit = trm match
714729
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)