@@ -13,6 +13,7 @@ import StdNames._
1313import NameOps ._
1414import Symbols ._
1515import Trees ._
16+ import TreeInfo ._
1617import ProtoTypes ._
1718import Constants ._
1819import Scopes ._
@@ -601,17 +602,20 @@ trait Checking {
601602 }
602603 }
603604
604- /** Check that `tree` is a pure expression of constant type */
605- def checkInlineConformant (tree : Tree , what : => String )(implicit ctx : Context ): Unit =
605+ /** Check that `tree` can be marked `inline` */
606+ def checkInlineConformant (tree : Tree , isFinal : Boolean , what : => String )(implicit ctx : Context ): Unit = {
607+ // final vals can be marked inline even if they're not pure, see Typer#patchFinalVals
608+ val purityLevel = if (isFinal) Idempotent else Pure
606609 tree.tpe match {
607610 case tp : TermRef if tp.symbol.is(InlineParam ) => // ok
608611 case tp => tp.widenTermRefExpr match {
609- case tp : ConstantType if isPureExpr (tree) => // ok
610- case tp if defn.isFunctionType(tp) && isPureExpr (tree) => // ok
612+ case tp : ConstantType if exprPurity (tree) >= purityLevel => // ok
613+ case tp if defn.isFunctionType(tp) && exprPurity (tree) >= purityLevel => // ok
611614 case _ =>
612615 if (! ctx.erasedTypes) ctx.error(em " $what must be a constant expression or a function " , tree.pos)
613616 }
614617 }
618+ }
615619
616620 /** Check that class does not declare same symbol twice */
617621 def checkNoDoubleDeclaration (cls : Symbol )(implicit ctx : Context ): Unit = {
@@ -867,7 +871,7 @@ trait NoChecking extends ReChecking {
867871 override def checkClassType (tp : Type , pos : Position , traitReq : Boolean , stablePrefixReq : Boolean )(implicit ctx : Context ): Type = tp
868872 override def checkImplicitParamsNotSingletons (vparamss : List [List [ValDef ]])(implicit ctx : Context ): Unit = ()
869873 override def checkFeasibleParent (tp : Type , pos : Position , where : => String = " " )(implicit ctx : Context ): Type = tp
870- override def checkInlineConformant (tree : Tree , what : => String )(implicit ctx : Context ) = ()
874+ override def checkInlineConformant (tree : Tree , isFinal : Boolean , what : => String )(implicit ctx : Context ) = ()
871875 override def checkNoDoubleDeclaration (cls : Symbol )(implicit ctx : Context ): Unit = ()
872876 override def checkParentCall (call : Tree , caller : ClassSymbol )(implicit ctx : Context ) = ()
873877 override def checkSimpleKinded (tpt : Tree )(implicit ctx : Context ): Tree = tpt
0 commit comments