Skip to content

Commit 4c24f08

Browse files
Separate module parameters from regular parameters
Module parameters are function parameters that have module identifiers as their type annotations. Module parameters must have an explicit and concrete type.
1 parent 0b75584 commit 4c24f08

File tree

3 files changed

+50
-23
lines changed

3 files changed

+50
-23
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,12 @@ extends Importer:
325325
def fld(tree: Tree): Ctxl[Fld] = tree match
326326
case InfixApp(lhs, Keyword.`:`, rhs) =>
327327
Fld(FldFlags.empty, term(lhs), S(term(rhs)))
328-
case _ => Fld(FldFlags.empty, term(tree), N)
329-
328+
case _ =>
329+
val t = term(tree)
330+
t.symbol.flatMap(_.asMod) match
331+
case S(_) => Fld(FldFlags.empty.copy(mod = true), t, N)
332+
case N => Fld(FldFlags.empty, t, N)
333+
330334
def unit: Term.Lit = Term.Lit(UnitLit(true))
331335

332336

@@ -607,6 +611,8 @@ extends Importer:
607611
case InfixApp(lhs: Ident, Keyword.`:`, rhs) =>
608612
Param(FldFlags.empty, fieldOrVarSym(ParamBind, lhs), S(term(rhs))) :: Nil
609613
case App(Ident(","), list) => params(list)._1
614+
case TypeDef(Mod, inner, _, _) => param(inner)
615+
.map(p => p.copy(flags = p.flags.copy(mod = true)))
610616
case TermDef(ImmutVal, inner, _) => param(inner)
611617

612618
def params(t: Tree): Ctxl[(Ls[Param], Ctx)] = t match
@@ -678,7 +684,7 @@ extends Importer:
678684
class VarianceTraverser(var changed: Bool = true) extends Traverser:
679685
override def traverseType(pol: Pol)(trm: Term): Unit = trm match
680686
case Term.TyApp(lhs, targs) =>
681-
lhs.symbol.flatMap(_.asTpe) match
687+
lhs.symbol.flatMap(sym => sym.asTpe orElse sym.asMod) match
682688
case S(sym: ClassSymbol) =>
683689
sym.defn match
684690
case S(td: ClassDef) =>
@@ -690,6 +696,17 @@ extends Importer:
690696
if !tp.isCovariant then traverseType(pol.!)(targ)
691697
case N =>
692698
TODO(sym->sym.uid)
699+
case S(sym: ModuleSymbol) =>
700+
sym.defn match
701+
case S(td: ModuleDef) =>
702+
if td.tparams.sizeCompare(targs) =/= 0 then
703+
raise(ErrorReport(msg"Wrong number of type arguments" -> trm.toLoc :: Nil)) // TODO BE
704+
td.tparams.zip(targs).foreach:
705+
case (tp, targ) =>
706+
if !tp.isContravariant then traverseType(pol)(targ)
707+
if !tp.isCovariant then traverseType(pol.!)(targ)
708+
case N =>
709+
TODO(sym->sym.uid)
693710
case S(sym: TypeAliasSymbol) =>
694711
// TODO dedup with above...
695712
sym.defn match

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,9 @@ final case class Param(flags: FldFlags, sym: LocalSymbol & NamedSymbol, sign: Op
315315
// def showDbg: Str = flags.showDbg + sym.name + ": " + sign.showDbg
316316
def showDbg: Str = flags.showDbg + sym + sign.fold("")(": " + _.showDbg)
317317

318-
object FldFlags { val empty: FldFlags = FldFlags(false, false, false) }
318+
object FldFlags {
319+
val empty: FldFlags = FldFlags(false, false, false, false)
320+
}
319321

320322
final case class ParamListFlags(ctx: Bool):
321323
def showDbg: Str = (if ctx then "ctx " else "")

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

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ fun f2(m: M): Int = m.foo(42)
155155
//│ flags = ParamListFlags of false
156156
//│ params = Ls of
157157
//│ Param:
158-
//│ flags = ()
158+
//│ flags = (module)
159159
//│ sym = m@42
160160
//│ sign = S of Sel:
161161
//│ prefix = Ref of globalThis:block#1
@@ -296,30 +296,38 @@ id(IntMT)
296296
// Good: module parameters must have an explicit and concrete type.
297297
// Mod[T] is a concrete type and Mod is a module, therefore t is a module parameter.
298298
fun idMod[T](t: MT[T]): MT[T] = t
299-
//│ FAILURE: Unexpected exception
300-
//│ /!!!\ Uncaught error: scala.NotImplementedError: an implementation is missing
301-
//│ at: scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
302-
//│ at: hkmc2.semantics.Elaborator$VarianceTraverser.traverseType(Elaborator.scala:708)
303-
//│ at: hkmc2.semantics.Elaborator$Traverser.traverseType$$anonfun$10(Elaborator.scala:750)
304-
//│ at: scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
305-
//│ at: scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
306-
//│ at: scala.Option.foreach(Option.scala:437)
307-
//│ at: hkmc2.semantics.Elaborator$Traverser.traverseType(Elaborator.scala:750)
308-
//│ at: hkmc2.semantics.Elaborator.go$4$$anonfun$1$$anonfun$1(Elaborator.scala:660)
309-
//│ at: scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
310-
//│ at: scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
299+
//│ Elaborated tree:
300+
//│ Blk:
301+
//│ stats = Ls of
302+
//│ TermDefinition:
303+
//│ owner = S of globalThis:block#12
304+
//│ k = Fun
305+
//│ sym = member:idMod
306+
//│ params = Ls of
307+
//│ ParamList:
308+
//│ flags = ParamListFlags of false
309+
//│ params = Ls of
310+
//│ Param:
311+
//│ flags = (module)
312+
//│ sym = t@60
313+
//│ sign = S of Sel:
314+
//│ prefix = Ref of globalThis:block#8
315+
//│ nme = Ident of "MT"
316+
//│ sign = N
317+
//│ body = S of Ref of t@60
318+
//│ resSym = ‹result of member:idMod›@61
319+
//│ flags = ()
320+
//│ res = Lit of UnitLit of true
311321

312322
// OK
313323
idMod(IntMT)
314-
//│ FAILURE: Unexpected type error
315-
//│ ╔══[ERROR] Name not found: idMod
316-
//│ ║ l.313: idMod(IntMT)
317-
//│ ╙── ^^^^^
318324
//│ Elaborated tree:
319325
//│ Blk:
320326
//│ stats = Nil
321327
//│ res = App:
322-
//│ lhs = Error
328+
//│ lhs = Sel:
329+
//│ prefix = Ref of globalThis:block#12
330+
//│ nme = Ident of "idMod"
323331
//│ rhs = Tup of Ls of
324332
//│ Fld:
325333
//│ flags = ()
@@ -344,7 +352,7 @@ fun f3(x: M) = x
344352
//│ flags = ParamListFlags of false
345353
//│ params = Ls of
346354
//│ Param:
347-
//│ flags = ()
355+
//│ flags = (module)
348356
//│ sym = x@65
349357
//│ sign = S of Sel:
350358
//│ prefix = Ref of globalThis:block#1

0 commit comments

Comments
 (0)