@@ -113,16 +113,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
113113 }
114114 }
115115
116- def genThrow (expr : Tree ): BType = {
116+ def genThrow (expr : Tree ): Unit = {
117117 val thrownKind = tpeTK(expr)
118118 // `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable.
119119 // Similarly for scala.Nothing (again, as defined in src/libray-aux).
120120 assert(thrownKind.isNullType || thrownKind.isNothingType || thrownKind.asClassBType.isSubtypeOf(ThrowableReference ))
121121 genLoad(expr, thrownKind)
122122 lineNumber(expr)
123123 emit(asm.Opcodes .ATHROW ) // ICode enters here into enterIgnoreMode, we'll rely instead on DCE at ClassNode level.
124-
125- RT_NOTHING // always returns the same, the invoker should know :)
126124 }
127125
128126 /* Generate code for primitive arithmetic operations. */
@@ -319,13 +317,14 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
319317 generatedType = expectedType
320318
321319 case t @ WhileDo (_, _) =>
322- generatedType = genWhileDo(t)
320+ generatedType = genWhileDo(t, expectedType )
323321
324322 case t @ Try (_, _, _) =>
325323 generatedType = genLoadTry(t)
326324
327325 case t : Apply if t.fun.symbol eq defn.throwMethod =>
328- generatedType = genThrow(t.args.head)
326+ genThrow(t.args.head)
327+ generatedType = expectedType
329328
330329 case New (tpt) =>
331330 abort(s " Unexpected New( ${tpt.tpe.showSummary()}/ $tpt) reached GenBCode. \n " +
@@ -586,41 +585,47 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
586585 }
587586 } // end of genReturn()
588587
589- def genWhileDo (tree : WhileDo ): BType = tree match {
588+ def genWhileDo (tree : WhileDo , expectedType : BType ): BType = tree match {
590589 case WhileDo (cond, body) =>
591590
592591 val isInfinite = cond == tpd.EmptyTree
593592
594- val loop = new asm.Label
595- markProgramPoint(loop)
596-
597- if (isInfinite) {
598- genLoad(body, UNIT )
599- bc goTo loop
600- RT_NOTHING
601- } else {
602- val hasBody = cond match {
603- case Literal (value) if value.tag == UnitTag => false
604- case _ => true
605- }
606-
607- if (hasBody) {
608- val success = new asm.Label
609- val failure = new asm.Label
610- genCond(cond, success, failure, targetIfNoJump = success)
611- markProgramPoint(success)
612- genLoad(body, UNIT )
613- bc goTo loop
614- markProgramPoint(failure)
615- } else {
616- // this is the shape of do..while loops, so do something smart about them
617- val failure = new asm.Label
618- genCond(cond, loop, failure, targetIfNoJump = failure)
619- markProgramPoint(failure)
620- }
621-
593+ if isInfinite then
594+ body match
595+ case Labeled (bind, expr) if tpeTK(body) == UNIT =>
596+ // this is the shape of tailrec methods
597+ val loop = programPoint(bind.symbol)
598+ markProgramPoint(loop)
599+ genLoad(expr, UNIT )
600+ bc goTo loop
601+ case _ =>
602+ val loop = new asm.Label
603+ markProgramPoint(loop)
604+ genLoad(body, UNIT )
605+ bc goTo loop
606+ end match
607+ expectedType
608+ else
609+ body match
610+ case Literal (value) if value.tag == UnitTag =>
611+ // this is the shape of do..while loops
612+ val loop = new asm.Label
613+ markProgramPoint(loop)
614+ val exitLoop = new asm.Label
615+ genCond(cond, loop, exitLoop, targetIfNoJump = exitLoop)
616+ markProgramPoint(exitLoop)
617+ case _ =>
618+ val loop = new asm.Label
619+ val success = new asm.Label
620+ val failure = new asm.Label
621+ markProgramPoint(loop)
622+ genCond(cond, success, failure, targetIfNoJump = success)
623+ markProgramPoint(success)
624+ genLoad(body, UNIT )
625+ bc goTo loop
626+ markProgramPoint(failure)
627+ end match
622628 UNIT
623- }
624629 }
625630
626631 def genTypeApply (t : TypeApply ): BType = (t : @ unchecked) match {
0 commit comments