diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 7 |
3 files changed, 16 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 415cd5d6a..42eede5e9 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -344,6 +344,7 @@ object Checking { fail(i"only classes can have declared but undefined members$varNote") checkWithDeferred(Private) checkWithDeferred(Final) + checkWithDeferred(Inline) } if (sym.isValueClass && sym.is(Trait) && !sym.isRefinementClass) fail(i"$sym cannot extend AnyVal") @@ -479,6 +480,13 @@ trait Checking { tp } + /** Check that `tree` is a pure expression of constant type */ + def checkInlineConformant(tree: Tree, what: => String)(implicit ctx: Context): Unit = + tree.tpe.widenTermRefExpr match { + case tp: ConstantType if isPureExpr(tree) => // ok + case _ => ctx.error(em"$what must be a constant expression", tree.pos) + } + /** Check that class does not define same symbol twice */ def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = { val seen = new mutable.HashMap[Name, List[Symbol]] { @@ -543,6 +551,7 @@ trait NoChecking extends Checking { override def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type = tp override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = () override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp + override def checkInlineConformant(tree: Tree, what: => String)(implicit ctx: Context) = () override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = () override def checkParentCall(call: Tree, caller: ClassSymbol)(implicit ctx: Context) = () override def checkSimpleKinded(tpt: Tree)(implicit ctx: Context): Tree = tpt diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index a33061453..2e714ab6d 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -891,7 +891,7 @@ class Namer { typer: Typer => // println(s"final inherited for $sym: ${inherited.toString}") !!! // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}") - def isInline = sym.is(Final, butNot = Method | Mutable) + def isInline = sym.is(FinalOrInline, butNot = Method | Mutable) // Widen rhs type and approximate `|' but keep ConstantTypes if // definition is inline (i.e. final in Scala2). diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index d99d85fba..58fb47f2c 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1140,6 +1140,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case rhs => typedExpr(rhs, tpt1.tpe) } val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) + if (sym.is(Inline, butNot = DeferredOrParamAccessor)) + checkInlineConformant(rhs1, "right-hand side of inline value") patchIfLazy(vdef1) vdef1 } @@ -1808,7 +1810,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } tree } - else if (tree.tpe <:< pt) + else if (tree.tpe <:< pt) { + if (pt.hasAnnotation(defn.InlineParamAnnot)) + checkInlineConformant(tree, "argument to inline parameter") if (Inliner.hasBodyToInline(tree.symbol) && !ctx.owner.ownersIterator.exists(_.isInlineMethod) && !ctx.settings.YnoInline.value && @@ -1822,6 +1826,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit tree.asInstance(pt) else tree + } else if (wtp.isInstanceOf[MethodType]) missingArgs else { typr.println(i"adapt to subtype ${tree.tpe} !<:< $pt") |