Skip to content

Commit ebe2b51

Browse files
Move implicit argument resolution to resolution stage.
1 parent bdc637a commit ebe2b51

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1003
-976
lines changed

hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,12 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
198198
def warnStmt = if inStmtPos then
199199
raise:
200200
WarningReport(msg"Pure expression in statement position" -> t.toLoc :: Nil, S(t))
201+
202+
// Funny Scala: the non-exhaustive match is actually the second match
201203
t match
204+
case t: sem.Resolvable => t.instantiate
205+
case t => t
206+
match
202207
case st.UnitVal() => k(unit)
203208
case st.Lit(lit) =>
204209
warnStmt
@@ -605,13 +610,6 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
605610
case sem.Fld(sem.FldFlags.benign(), idx, S(rhs)) => L(idx -> rhs)
606611
case arg @ sem.Fld(flags, value, asc) => TODO(s"Other argument forms: $arg")
607612
case spd: Spd => R(true -> spd.term)
608-
case ca: sem.CtxArg => ca.term match
609-
case S(t) =>
610-
R(false -> t)
611-
case N =>
612-
// * All contextual arguments should have been
613-
// * populated by implicit resolution before lowering.
614-
lastWords(s"Found unpopulated contextual argument: ${ca}.")
615613
// * The straightforward way to lower arguments creates too much recursion depth
616614
// * and makes Lowering stack overflow when lowering functions with lots of arguments.
617615
/*

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

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,6 @@ extends Importer:
290290

291291
def term(tree: Tree, inAppPrefix: Bool = false, inTyAppPrefix: Bool = false): Ctxl[Term] =
292292
trace[Term](s"Elab term ${tree.showDbg}", r => s"~> $r"):
293-
def maybeApp(t: Term): Ctxl[Term] =
294-
if !inAppPrefix && !inTyAppPrefix // to ensure that nested App/TyApp are only wrapped once.
295-
then maybeFunctionApp(t)
296-
else t
297293
tree.desugared match
298294
case unt @ Unt() => unit.withLocOf(unt)
299295
case Bra(k, e) =>
@@ -379,13 +375,13 @@ extends Importer:
379375
msg"Unsupported handle binding shape" ->
380376
h.toLoc :: Nil))
381377
Term.Error
382-
case id @ Ident("this") => maybeApp:
378+
case id @ Ident("this") =>
383379
ctx.getOuter match
384380
case S(sym) => sym.ref(id)
385381
case N =>
386382
raise(ErrorReport(msg"Cannot use 'this' outside of an object scope." -> tree.toLoc :: Nil))
387383
Term.Error
388-
case id @ Ident(name) => maybeApp:
384+
case id @ Ident(name) =>
389385
ctx.get(name) match
390386
case S(elem) => elem.ref(id)
391387
case N =>
@@ -394,7 +390,7 @@ extends Importer:
394390
case N =>
395391
raise(ErrorReport(msg"Name not found: $name" -> tree.toLoc :: Nil))
396392
Term.Error
397-
case TyApp(lhs, targs) => maybeApp:
393+
case TyApp(lhs, targs) =>
398394
Term.TyApp(term(lhs, inTyAppPrefix = true), targs.map {
399395
case Modified(Keyword.`in`, inLoc, arg) => Term.WildcardTy(S(term(arg)), N)
400396
case Modified(Keyword.`out`, outLoc, arg) => Term.WildcardTy(N, S(term(arg)))
@@ -507,13 +503,11 @@ extends Importer:
507503
val sym = FlowSymbol("‹app-res›")
508504
val lt = term(lhs, inAppPrefix = true)
509505
val rt = term(rhs)
510-
maybeApp:
511-
Term.App(lt, rt)(tree, sym)
506+
Term.App(lt, rt)(tree, sym)
512507
case SynthSel(pre, nme) =>
513508
val preTrm = term(pre)
514509
val sym = resolveField(nme, preTrm.symbol, nme)
515-
maybeApp:
516-
Term.SynthSel(preTrm, nme)(sym)
510+
Term.SynthSel(preTrm, nme)(sym)
517511
case Sel(pre, nme) =>
518512
val preTrm = term(pre)
519513
val sym = resolveField(nme, preTrm.symbol, nme)
@@ -535,8 +529,7 @@ extends Importer:
535529
val loc = tree.toLoc.getOrElse(???)
536530
Term.Lit(Tree.StrLit(loc.origin.fileName.toString))
537531
else
538-
maybeApp:
539-
Term.Sel(preTrm, nme)(sym)
532+
Term.Sel(preTrm, nme)(sym)
540533
case MemberProj(ct, nme) =>
541534
val c = cls(ct, inAppPrefix = false)
542535
val f = c.symbol.flatMap(_.asCls) match
@@ -711,69 +704,6 @@ extends Importer:
711704
// case _ =>
712705
// ???
713706

714-
/**
715-
* Function (as opposed to method) applications
716-
* that may require further elaboration with type information.
717-
*/
718-
def maybeFunctionApp(t: Term): Ctxl[Term] =
719-
// * Some function definitions might not be fully elaborated yet.
720-
// * We need to do some very lightweight tree parsing here.
721-
case class Param(ctx: Bool)(tree: Tree)
722-
case class ParamList(ps: Ls[Param], ctx: Bool)(tree: Tree)
723-
def param(tree: Tree): Param = tree match
724-
case Tree.Modified(Keyword.`using`, _, tree) => Param(true)(tree)
725-
case _ => Param(false)(tree)
726-
def paramList(tree: Tree.Tup): ParamList =
727-
val ps = tree.fields.map(param)
728-
ParamList(ps, ps.exists(_.ctx))(tree)
729-
730-
/**
731-
* Zips a `fun` application term along with its parameter lists,
732-
* inserting any missing contextual argument lists.
733-
*
734-
* M.foo -> M.foo(<using> ...)
735-
* M.foo(a, b) -> M.foo(<using> ...)(a, b)(<using> ...)
736-
*
737-
* Note: This *doesn't* handle explicit contextual arguments.
738-
*/
739-
def zip(t: Term, paramLists: Ls[ParamList]): Term = (t, paramLists) match
740-
case (t, ps :: pss) if ps.ctx =>
741-
val appTree = new Tree.App(Tree.Empty(), Tree.Empty())
742-
val tupTree = new Tree.Tup(Nil)
743-
val args = Term.Tup(ps.ps.map(_ => CtxArgImpl()))(tupTree)
744-
Term.App(zip(t, pss), args)(appTree, FlowSymbol("‹app-res›"))
745-
case (t @ Term.App(lhs, rhs), ps :: pss) =>
746-
Term.App(zip(lhs, pss), rhs)(t.tree, t.resSym)
747-
case (t, params :: pRest) =>
748-
// LHS is not a app but it still expects more param lists - a partial application.
749-
// Just suppose it is legal and don't fail here.
750-
// TODO: Check in the implicit resolver.
751-
t
752-
case (_, Nil) => t
753-
754-
/**
755-
* An extractor that extracts the (tree) definition of a `fun`.
756-
*/
757-
object FunctionTreeDef:
758-
def unapply(t: Term): Opt[Tree.TermDef] = t.symbol match
759-
case S(sym: BlockMemberSymbol) => sym.trmTree match
760-
case S(tree @ Tree.TermDef(k = Fun)) => S(tree)
761-
case _ => N
762-
case _ => N
763-
764-
t match
765-
// f[T](foo)(bar)
766-
case semantics.Apps(Term.TyApp(FunctionTreeDef(tree), _), argss) =>
767-
trace[Term](s"Elab `fun` application ${t.showDbg}", r => s"~> $r"):
768-
zip(t, tree.paramLists.map(paramList).reverse)
769-
// f(foo)(bar)
770-
case semantics.Apps(FunctionTreeDef(tree), argss) =>
771-
trace[Term](s"Elab `fun` application ${t.showDbg}", r => s"~> $r"):
772-
zip(t, tree.paramLists.map(paramList).reverse)
773-
// The definition does not exist.
774-
case _ =>
775-
t
776-
777707
def fld(tree: Tree): Ctxl[Elem] = tree match
778708
case InfixApp(id: Ident, Keyword.`:`, rhs) =>
779709
Fld(FldFlags.empty, Term.Lit(StrLit(id.name).withLocOf(id)), S(term(rhs)))

0 commit comments

Comments
 (0)