Skip to content

Commit 2a47d89

Browse files
committed
Fix compilation
1 parent a431955 commit 2a47d89

File tree

2 files changed

+53
-50
lines changed

2 files changed

+53
-50
lines changed

compiler/src/dotty/tools/dotc/transform/init/Checker.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class Checker extends MiniPhase {
5252
val obj = Objekt(cls, fields = mutable.Map.empty, outers = mutable.Map(cls -> Hot))
5353
given Promoted = Promoted.empty
5454
given Trace = Trace.empty
55+
given Env = Env.empty
5556
heap.update(thisRef, obj)
5657
val res = eval(tpl, thisRef, cls)
5758
res.errors.foreach(_.issue)

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ class Semantic {
233233
def select(f: Symbol, source: Tree): Contextual[Result] =
234234
value.select(f, source) ++ errors
235235

236-
def call(meth: Symbol, superType: Type, source: Tree): Contextual[Result] =
237-
value.call(meth, superType, source) ++ errors
236+
def call(meth: Symbol, args: List[Value], superType: Type, source: Tree): Contextual[Result] =
237+
value.call(meth, args, superType, source) ++ errors
238238

239-
def instantiate(klass: ClassSymbol, ctor: Symbol, source: Tree): Contextual[Result] =
240-
value.instantiate(klass, ctor, source) ++ errors
239+
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[Value], source: Tree): Contextual[Result] =
240+
value.instantiate(klass, ctor, args, source) ++ errors
241241
}
242242

243243
/** The state that threads through the interpreter */
244-
type Contextual[T] = (Context, Trace, Promoted) ?=> T
244+
type Contextual[T] = (Env, Context, Trace, Promoted) ?=> T
245245

246246
// ----- Error Handling -----------------------------------
247247

@@ -282,9 +282,8 @@ class Semantic {
282282

283283
def widen: Value =
284284
a match
285+
case _: Addr | _: Fun => Cold
285286
case RefSet(refs) => refs.map(_.widen).join
286-
case _: Addr => Cold
287-
case Fun(e, params, thisV, klass, env) => Fun(e, params, thisV.widen, klass, env)
288287
case _ => a
289288

290289

@@ -308,7 +307,7 @@ class Semantic {
308307
case addr: Addr =>
309308
val target = if needResolve then resolve(addr.klass, field) else field
310309
if target.is(Flags.Lazy) then
311-
value.call(target, superType = NoType, source, needResolve = false)
310+
value.call(target, Nil, superType = NoType, source, needResolve = false)
312311
else
313312
val obj = heap(addr)
314313
if obj.fields.contains(target) then
@@ -330,8 +329,9 @@ class Semantic {
330329
val error = AccessNonInit(target, trace.add(source).toVector)
331330
Result(Hot, error :: Nil)
332331

333-
case _: Fun =>
334-
???
332+
case fun: Fun =>
333+
report.error("unexpected tree in selecting a function, fun = " + fun.expr.show, source)
334+
Result(Hot, Nil)
335335

336336
case RefSet(refs) =>
337337
val resList = refs.map(_.select(field, source))
@@ -340,7 +340,7 @@ class Semantic {
340340
Result(value2, errors)
341341
}
342342

343-
def call(meth: Symbol, superType: Type, source: Tree, needResolve: Boolean = true): Contextual[Result] =
343+
def call(meth: Symbol, args: List[Value], superType: Type, source: Tree, needResolve: Boolean = true): Contextual[Result] =
344344
value match {
345345
case Hot =>
346346
Result(Hot, Errors.empty)
@@ -362,7 +362,7 @@ class Semantic {
362362
val cls = target.owner.enclosingClass.asClass
363363
if target.isPrimaryConstructor then
364364
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
365-
eval(tpl, addr, cls, cacheResult = true)(using ctx, trace.add(cls.defTree), promoted)
365+
eval(tpl, addr, cls, cacheResult = true)(using env, ctx, trace.add(cls.defTree), promoted)
366366
else
367367
val rhs = target.defTree.asInstanceOf[ValOrDefDef].rhs
368368
eval(rhs, addr, cls, cacheResult = true)
@@ -378,20 +378,20 @@ class Semantic {
378378
else
379379
value.select(target, source, needResolve = false)
380380

381-
case Fun(body, thisV, klass) =>
381+
case Fun(body, params, thisV, klass, env) =>
382382
// meth == NoSymbol for poly functions
383383
if meth.name.toString == "tupled" then Result(value, Nil) // a call like `fun.tupled`
384384
else eval(body, thisV, klass, cacheResult = true)
385385

386386
case RefSet(refs) =>
387-
val resList = refs.map(_.call(meth, superType, source))
387+
val resList = refs.map(_.call(meth, args, superType, source))
388388
val value2 = resList.map(_.value).join
389389
val errors = resList.flatMap(_.errors)
390390
Result(value2, errors)
391391
}
392392

393393
/** Handle a new expression `new p.C` where `p` is abstracted by `value` */
394-
def instantiate(klass: ClassSymbol, ctor: Symbol, source: Tree): Contextual[Result] =
394+
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[Value], source: Tree): Contextual[Result] =
395395
value match {
396396
case Hot =>
397397
Result(Hot, Errors.empty)
@@ -403,21 +403,22 @@ class Semantic {
403403
case addr: Addr =>
404404
// widen the outer to finitize addresses
405405
val outer = addr match
406-
case Warm(_, _: Warm) => Cold
406+
case Warm(_, _: Warm, _, _) => Cold
407407
case _ => addr
408408

409-
val value = Warm(klass, outer)
409+
val value = Warm(klass, outer, ctor, args.widen)
410410
if !heap.contains(value) then
411411
val obj = Objekt(klass, fields = mutable.Map.empty, outers = mutable.Map(klass -> outer))
412412
heap.update(value, obj)
413-
val res = value.call(ctor, superType = NoType, source)
413+
val res = value.call(ctor, args, superType = NoType, source)
414414
Result(value, res.errors)
415415

416-
case Fun(body, thisV, klass) =>
417-
??? // impossible
416+
case Fun(body, params, thisV, klass, env) =>
417+
report.error("unexpected tree in instantiating a function, fun = " + body.show, source)
418+
Result(Hot, Nil)
418419

419420
case RefSet(refs) =>
420-
val resList = refs.map(_.instantiate(klass, ctor, source))
421+
val resList = refs.map(_.instantiate(klass, ctor, args, source))
421422
val value2 = resList.map(_.value).join
422423
val errors = resList.flatMap(_.errors)
423424
Result(value2, errors)
@@ -490,7 +491,7 @@ class Semantic {
490491
errors
491492
}
492493

493-
case fun @ Fun(body, thisV, klass) =>
494+
case fun @ Fun(body, params, thisV, klass, env) =>
494495
if promoted.contains(fun) then Nil
495496
else
496497
val res = eval(body, thisV, klass)
@@ -550,7 +551,8 @@ class Semantic {
550551
val trace2 = trace.add(m.defTree)
551552
locally {
552553
given Trace = trace2
553-
val res = warm.call(m, superType = NoType, source = source)
554+
val args = m.info.paramInfoss.flatten.map(_ => Hot)
555+
val res = warm.call(m, args, superType = NoType, source = source)
554556
buffer ++= res.ensureHot(msg, source).errors
555557
}
556558
buffer.nonEmpty
@@ -611,18 +613,15 @@ class Semantic {
611613
exprs.map { expr => eval(expr, thisV, klass) }
612614

613615
/** Evaluate arguments of methods */
614-
def evalArgs(args: List[Arg], thisV: Addr, klass: ClassSymbol): Contextual[List[Error]] =
616+
def evalArgs(args: List[Arg], thisV: Addr, klass: ClassSymbol): Contextual[(List[Error], List[Value])] =
615617
val ress = args.map { arg =>
616-
val res =
617-
if arg.isByName then
618-
val fun = Fun(arg.tree, thisV, klass)
619-
Result(fun, Nil)
620-
else
621-
eval(arg.tree, thisV, klass)
622-
623-
res.ensureHot("May only use initialized value as arguments", arg.tree)
618+
if arg.isByName then
619+
val fun = Fun(arg.tree, Nil, thisV, klass, env)
620+
Result(fun, Nil)
621+
else
622+
eval(arg.tree, thisV, klass)
624623
}
625-
ress.flatMap(_.errors)
624+
(ress.flatMap(_.errors), ress.map(_.value))
626625

627626
/** Handles the evaluation of different expressions
628627
*
@@ -640,31 +639,31 @@ class Semantic {
640639

641640
case NewExpr(tref, New(tpt), ctor, argss) =>
642641
// check args
643-
val errors = evalArgs(argss.flatten, thisV, klass)
642+
val (errors, args) = evalArgs(argss.flatten, thisV, klass)
644643

645644
val cls = tref.classSymbol.asClass
646645
val res = outerValue(tref, thisV, klass, tpt)
647646
val trace2 = trace.add(expr)
648647
locally {
649648
given Trace = trace2
650-
(res ++ errors).instantiate(cls, ctor, expr)
649+
(res ++ errors).instantiate(cls, ctor, args, expr)
651650
}
652651

653652
case Call(ref, argss) =>
654653
// check args
655-
val errors = evalArgs(argss.flatten, thisV, klass)
654+
val (errors, args) = evalArgs(argss.flatten, thisV, klass)
656655

657656
val trace2: Trace = trace.add(expr)
658657

659658
ref match
660659
case Select(supert: Super, _) =>
661660
val SuperType(thisTp, superTp) = supert.tpe
662661
val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass, ref)
663-
Result(thisValue2, errors).call(ref.symbol, superTp, expr)(using ctx, trace2)
662+
Result(thisValue2, errors).call(ref.symbol, args, superTp, expr)(using env, ctx, trace2)
664663

665664
case Select(qual, _) =>
666665
val res = eval(qual, thisV, klass) ++ errors
667-
res.call(ref.symbol, superType = NoType, source = expr)(using ctx, trace2)
666+
res.call(ref.symbol, args, superType = NoType, source = expr)(using env, ctx, trace2)
668667

669668
case id: Ident =>
670669
id.tpe match
@@ -673,10 +672,10 @@ class Semantic {
673672
val enclosingClass = id.symbol.owner.enclosingClass.asClass
674673
val thisValue2 = resolveThis(enclosingClass, thisV, klass, id)
675674
// local methods are not a member, but we can reuse the method `call`
676-
thisValue2.call(id.symbol, superType = NoType, expr, needResolve = false)
675+
thisValue2.call(id.symbol, args, superType = NoType, expr, needResolve = false)
677676
case TermRef(prefix, _) =>
678677
val res = cases(prefix, thisV, klass, id) ++ errors
679-
res.call(id.symbol, superType = NoType, source = expr)(using ctx, trace2)
678+
res.call(id.symbol, args, superType = NoType, source = expr)(using env, ctx, trace2)
680679

681680
case Select(qualifier, name) =>
682681
eval(qualifier, thisV, klass).select(expr.symbol, expr)
@@ -703,11 +702,12 @@ class Semantic {
703702
eval(rhs, thisV, klass).ensureHot("May only assign fully initialized value", rhs)
704703

705704
case closureDef(ddef) =>
706-
val value = Fun(ddef.rhs, thisV, klass)
705+
val params = ddef.termParamss.head.map(_.symbol)
706+
val value = Fun(ddef.rhs, params, thisV, klass, env)
707707
Result(value, Nil)
708708

709709
case PolyFun(body) =>
710-
val value = Fun(body, thisV, klass)
710+
val value = Fun(body, Nil, thisV, klass, env)
711711
Result(value, Nil)
712712

713713
case Block(stats, expr) =>
@@ -860,7 +860,7 @@ class Semantic {
860860
}
861861
}
862862

863-
def superCall(tref: TypeRef, ctor: Symbol, source: Tree): Unit =
863+
def superCall(tref: TypeRef, ctor: Symbol, args: List[Value], source: Tree): Unit =
864864
val cls = tref.classSymbol.asClass
865865
// update outer for super class
866866
val res = outerValue(tref, thisV, klass, source)
@@ -870,23 +870,25 @@ class Semantic {
870870
// follow constructor
871871
if cls.hasSource then
872872
printer.println("init super class " + cls.show)
873-
val res2 = thisV.call(ctor, superType = NoType, source)(using ctx, trace.add(source))
873+
val res2 = thisV.call(ctor, args, superType = NoType, source)(using env, ctx, trace.add(source))
874874
errorBuffer ++= res2.errors
875875

876876
// parents
877877
def initParent(parent: Tree) = parent match {
878878
case tree @ Block(stats, NewExpr(tref, New(tpt), ctor, argss)) => // can happen
879879
eval(stats, thisV, klass).foreach { res => errorBuffer ++= res.errors }
880-
errorBuffer ++= evalArgs(argss.flatten, thisV, klass)
881-
superCall(tref, ctor, tree)
880+
val (erros, args) = evalArgs(argss.flatten, thisV, klass)
881+
errorBuffer ++= erros
882+
superCall(tref, ctor, args, tree)
882883

883884
case tree @ NewExpr(tref, New(tpt), ctor, argss) => // extends A(args)
884-
errorBuffer ++= evalArgs(argss.flatten, thisV, klass)
885-
superCall(tref, ctor, tree)
885+
val (erros, args) = evalArgs(argss.flatten, thisV, klass)
886+
errorBuffer ++= erros
887+
superCall(tref, ctor, args, tree)
886888

887889
case _ => // extends A or extends A[T]
888890
val tref = typeRefOf(parent.tpe)
889-
superCall(tref, tref.classSymbol.primaryConstructor, parent)
891+
superCall(tref, tref.classSymbol.primaryConstructor, Nil, parent)
890892
}
891893

892894
// see spec 5.1 about "Template Evaluation".
@@ -913,7 +915,7 @@ class Semantic {
913915
// term arguments to B. That can only be done in a concrete class.
914916
val tref = typeRefOf(klass.typeRef.baseType(mixin).typeConstructor)
915917
val ctor = tref.classSymbol.primaryConstructor
916-
if ctor.exists then superCall(tref, ctor, superParent)
918+
if ctor.exists then superCall(tref, ctor, Nil, superParent)
917919
}
918920

919921

0 commit comments

Comments
 (0)