From 0d9dd7c7e366be71ca795b89b48def8b0d201a05 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 7 Nov 2016 17:05:14 +0100 Subject: [PATCH 1/3] Use inline flag instead of @inline annotation Convert `@inline` annotations to `inline` flags, not the other way round as was done before. --- src/dotty/tools/dotc/ast/Desugar.scala | 3 +-- src/dotty/tools/dotc/core/SymDenotations.scala | 5 +---- .../tools/dotc/core/tasty/TreeUnpickler.scala | 2 +- src/dotty/tools/dotc/typer/Namer.scala | 17 ++++------------- src/dotty/tools/dotc/typer/Typer.scala | 5 ++--- 5 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 639dac930b6f..349fbfb2c1a9 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -615,8 +615,7 @@ object desugar { */ def makeClosure(params: List[ValDef], body: Tree, tpt: Tree = TypeTree(), inlineable: Boolean)(implicit ctx: Context) = { var mods = synthetic - if (inlineable) - mods = mods.withAddedAnnotation(New(ref(defn.InlineAnnotType), Nil).withPos(body.pos)) + if (inlineable) mods |= Inline Block( DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(mods), Closure(Nil, Ident(nme.ANON_FUN), EmptyTree)) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index a25be0a1fac9..fb6a401000b4 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -751,10 +751,7 @@ object SymDenotations { // def isOverridable: Boolean = !!! need to enforce that classes cannot be redefined def isSkolem: Boolean = name == nme.SKOLEM - def isInlineMethod(implicit ctx: Context): Boolean = - is(Method, butNot = Accessor) && - !isCompleting && // don't force method type; recursive inlines are ignored anyway. - hasAnnotation(defn.InlineAnnot) + def isInlineMethod(implicit ctx: Context): Boolean = is(InlineMethod, butNot = Accessor) // ------ access to related symbols --------------------------------- diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index a0d788955ee8..d2605afea91b 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -474,7 +474,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle sym.completer.withDecls(newScope) forkAt(templateStart).indexTemplateParams()(localContext(sym)) } - else if (annots.exists(_.symbol == defn.InlineAnnot)) + else if (sym.isInlineMethod) sym.addAnnotation(LazyBodyAnnotation { ctx0 => implicit val ctx: Context = localContext(sym)(ctx0).addMode(Mode.ReadPositions) // avoids space leaks by not capturing the current context diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 9da0e2edccf4..725979496a25 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -521,6 +521,7 @@ class Namer { typer: Typer => mergeCompanionDefs() val ctxWithStats = (ctx /: stats) ((ctx, stat) => indexExpanded(stat)(ctx)) createCompanionLinks(ctxWithStats) + //stats foreach enterAnnotations ctxWithStats } @@ -568,19 +569,9 @@ class Namer { typer: Typer => val cls = typedAheadAnnotation(annotTree) val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree)) denot.addAnnotation(ann) - if (cls == defn.InlineAnnot) { - hasInlineAnnot = true - addInlineInfo(denot, original) - } - } - if (!hasInlineAnnot && denot.is(InlineMethod)) { - // create a @inline annotation. Currently, the inlining trigger - // is really the annotation, not the flag. This is done so that - // we can still compile inline methods from Scala2x. Once we stop - // being compatible with Scala2 we should revise the logic to - // be based on the flag. Then creating a separate annotation becomes unnecessary. - denot.addAnnotation(Annotation(defn.InlineAnnot)) - addInlineInfo(denot, original) + if (cls == defn.InlineAnnot && denot.is(Method, butNot = Accessor)) + denot.setFlag(Inline) + if (denot.isInlineMethod) addInlineInfo(denot, original) } case _ => } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 95f0c5614a79..a93262314d22 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1142,7 +1142,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) if (sym.is(Inline, butNot = DeferredOrParamAccessor)) - checkInlineConformant(rhs1, "right-hand side of inline value") + checkInlineConformant(rhs1, em"right-hand side of inline $sym") patchIfLazy(vdef1) vdef1 } @@ -1176,8 +1176,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx) // Overwrite inline body to make sure it is not evaluated twice - if (sym.hasAnnotation(defn.InlineAnnot)) - Inliner.registerInlineInfo(sym, _ => rhs1) + if (sym.isInlineMethod) Inliner.registerInlineInfo(sym, _ => rhs1) if (sym.isAnonymousFunction) { // If we define an anonymous function, make sure the return type does not From 678242f86cf8bc50cd15656f3b1058f711e0e3d8 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 7 Nov 2016 17:47:41 +0100 Subject: [PATCH 2/3] Address reviewer comments --- src/dotty/tools/dotc/typer/Namer.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 725979496a25..405cf73b5c77 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -521,7 +521,6 @@ class Namer { typer: Typer => mergeCompanionDefs() val ctxWithStats = (ctx /: stats) ((ctx, stat) => indexExpanded(stat)(ctx)) createCompanionLinks(ctxWithStats) - //stats foreach enterAnnotations ctxWithStats } From 2e02b292cca07f8b619aba0e03dca878e22c415f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 7 Nov 2016 18:42:17 +0100 Subject: [PATCH 3/3] Separate addInlineInfo and addAnnotations --- src/dotty/tools/dotc/typer/Namer.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 405cf73b5c77..dd7326fae49a 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -570,13 +570,12 @@ class Namer { typer: Typer => denot.addAnnotation(ann) if (cls == defn.InlineAnnot && denot.is(Method, butNot = Accessor)) denot.setFlag(Inline) - if (denot.isInlineMethod) addInlineInfo(denot, original) } case _ => } - private def addInlineInfo(denot: SymDenotation, original: untpd.Tree) = original match { - case original: untpd.DefDef => + private def addInlineInfo(denot: SymDenotation) = original match { + case original: untpd.DefDef if denot.isInlineMethod => Inliner.registerInlineInfo( denot, implicit ctx => typedAheadExpr(original).asInstanceOf[tpd.DefDef].rhs @@ -589,6 +588,7 @@ class Namer { typer: Typer => */ def completeInCreationContext(denot: SymDenotation): Unit = { addAnnotations(denot) + addInlineInfo(denot) denot.info = typeSig(denot.symbol) Checking.checkWellFormed(denot.symbol) }