From 68cf53058a4419b00f7830229b36fb726679494a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 14 Aug 2018 12:01:14 +0200 Subject: [PATCH 1/2] Add Constant type Constant is s subtype of Singleton types that only allow constants for which the value is known at compile time. --- .../dotty/tools/dotc/core/Definitions.scala | 8 +++++ .../dotty/tools/dotc/core/TypeComparer.scala | 1 + .../src/dotty/tools/dotc/core/Types.scala | 8 +++++ tests/neg/constant-types.scala | 20 +++++++++++++ tests/pos/constant-types.scala | 30 +++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 tests/neg/constant-types.scala create mode 100644 tests/pos/constant-types.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 38e949aa3f4b..a15ead1f3236 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -410,6 +410,13 @@ class Definitions { List(AnyClass.typeRef), EmptyScope) lazy val SingletonType: TypeRef = SingletonClass.typeRef + lazy val ConstantClass: ClassSymbol = + // TODO needs to be synthetic as is SingletonClass? + enterCompleteClassSymbol( + ScalaPackageClass, tpnme.Constant, PureInterfaceCreationFlags | Final, + List(SingletonType), EmptyScope) + lazy val ConstantType: TypeRef = ConstantClass.typeRef + lazy val SeqType: TypeRef = if (isNewCollections) ctx.requiredClassRef("scala.collection.immutable.Seq") else ctx.requiredClassRef("scala.collection.Seq") @@ -1209,6 +1216,7 @@ class Definitions { NullClass, NothingClass, SingletonClass, + ConstantClass, EqualsPatternClass) lazy val syntheticCoreClasses = syntheticScalaClasses ++ List( diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 84400206a7b6..d6829b2aeaba 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -393,6 +393,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { if (base.exists && base.ne(tp1)) return isSubType(base, tp2, if (tp1.isRef(cls2)) approx else approx.addLow) if (cls2 == defn.SingletonClass && tp1.isStable) return true + if (cls2 == defn.ConstantClass && tp1.isConstant) return true } else if (cls2.is(JavaDefined)) { // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 63d82eab1047..8834479eaf5e 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -158,6 +158,14 @@ object Types { case _ => false } + /** Does this type denote a constant type */ + final def isConstant(implicit ctx: Context): Boolean = stripTypeVar match { + case _: ConstantType => true + case tp: ExprType => tp.resultType.isConstant + case tp: AnnotatedType => tp.parent.isConstant + case _ => false + } + /** Is this type a (possibly refined or applied or aliased) type reference * to the given type symbol? * @sym The symbol to compare to. It must be a class symbol or abstract type. diff --git a/tests/neg/constant-types.scala b/tests/neg/constant-types.scala new file mode 100644 index 000000000000..7abbb1b5ce9f --- /dev/null +++ b/tests/neg/constant-types.scala @@ -0,0 +1,20 @@ +object Constants { + + def f[C <: Constant](c: C): Unit = () + val x = 1 + f(x) // error + + def fBool(c: Boolean & Constant): Unit = () + val b = true + fBool(b) // error + + + def fInt(c: Int & Constant): Unit = () + val i = 3 + fInt(i) // error + + def fChar(c: Char & Constant): Unit = () + val c = 'c' + fChar(c) // error + +} diff --git a/tests/pos/constant-types.scala b/tests/pos/constant-types.scala new file mode 100644 index 000000000000..93684e745aeb --- /dev/null +++ b/tests/pos/constant-types.scala @@ -0,0 +1,30 @@ +object Constants { + + def f[C <: Constant](c: C): Unit = () + f(true) + f(1) + f(2L) + f(1.2f) + f(1.2d) + f('a') + f("abc") + + def fBool(c: Boolean & Constant): Unit = () + fBool(true) + fBool(false) + transparent def bb: Boolean = true + fBool(bb) + + def fInt(c: Int & Constant): Unit = () + fInt(1) + fInt(2) + transparent def ii: Int = 4 + fInt(ii) + + def fChar(c: Char & Constant): Unit = () + fChar('a') + fChar('b') + transparent def cc: Char = 'd' + fChar(cc) + +} From ca6b5e1b8d6d78e9fef0e042d521f1e0e14762d7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 14 Aug 2018 17:07:07 +0200 Subject: [PATCH 2/2] Remove transparent parameters and use Constant types instead --- bench/tests/power-macro/PowerMacro.scala | 2 +- .../dotty/tools/dotc/core/Definitions.scala | 3 --- .../src/dotty/tools/dotc/core/Flags.scala | 3 --- .../src/dotty/tools/dotc/core/Types.scala | 11 ++-------- .../dotty/tools/dotc/parsing/Parsers.scala | 9 ++++----- .../tools/dotc/transform/PostTyper.scala | 2 ++ .../tools/dotc/transform/ReifyQuotes.scala | 4 ++-- .../dotty/tools/dotc/transform/Splicer.scala | 4 ++-- .../src/dotty/tools/dotc/typer/Inliner.scala | 3 +-- .../src/dotty/tools/dotc/typer/Typer.scala | 2 -- .../internal/TransparentParam.scala | 6 ------ tests/neg/i4433.scala | 2 +- tests/neg/inlinevals-2.scala | 20 +++++++++++++++++++ tests/neg/inlinevals.scala | 19 ++++-------------- tests/neg/quote-error-2/Macro_1.scala | 2 +- tests/neg/quote-error/Macro_1.scala | 2 +- tests/neg/quote-exception/Macro_1.scala | 2 +- tests/neg/quote-macro-complex-arg-0.scala | 2 +- tests/neg/quote-splice-interpret-1.scala | 2 +- tests/pos/constant-types.scala | 8 ++++---- tests/pos/i1570.decompiled | 4 ++-- tests/pos/i1570.scala | 4 ++-- tests/pos/i3898b/quoted_1.scala | 2 +- tests/pos/i3898c/quoted_1.scala | 2 +- tests/pos/i4846.scala | 2 +- tests/pos/power-macro/Macro_1.scala | 2 +- tests/pos/power-macro/PowerInlined-1_2.scala | 2 +- tests/pos/quote-lift-inline-params-b.scala | 2 +- .../quote-lift-inline-params/Macro_1.scala | 4 ++-- tests/pos/quote-nested-object/Macro_1.scala | 4 ++-- tests/run/i1569.scala | 2 +- tests/run/i4455/Macro_1.scala | 4 ++-- tests/run/i4735/Macro_1.scala | 2 +- tests/run/i4803/App_2.scala | 18 ++++++++--------- tests/run/i4803/Macro_1.scala | 2 +- tests/run/i4803b/App_2.scala | 10 +++++----- tests/run/i4803c/App_2.scala | 20 +++++++++---------- tests/run/i4803d/App_2.scala | 4 ++-- tests/run/lst/Lst.scala | 2 +- tests/run/quote-and-splice/Macros_1.scala | 4 ++-- tests/run/quote-simple-macro/quoted_1.scala | 2 +- .../run/quote-unrolled-foreach/quoted_1.scala | 2 +- tests/run/typelevel-patmat.scala | 2 +- tests/run/typelevel.scala | 4 ++-- 44 files changed, 101 insertions(+), 113 deletions(-) delete mode 100644 library/src/scala/annotation/internal/TransparentParam.scala create mode 100644 tests/neg/inlinevals-2.scala diff --git a/bench/tests/power-macro/PowerMacro.scala b/bench/tests/power-macro/PowerMacro.scala index 3a18f97e980e..0821732c1316 100644 --- a/bench/tests/power-macro/PowerMacro.scala +++ b/bench/tests/power-macro/PowerMacro.scala @@ -2,7 +2,7 @@ import scala.quoted.Expr object PowerMacro { - transparent def power(transparent n: Long, x: Double) = ~powerCode(n, '(x)) + transparent def power(n: Long & Constant, x: Double) = ~powerCode(n, '(x)) def powerCode(n: Long, x: Expr[Double]): Expr[Double] = if (n == 0) '(1.0) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index a15ead1f3236..9366ccd0eb48 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -415,7 +415,6 @@ class Definitions { enterCompleteClassSymbol( ScalaPackageClass, tpnme.Constant, PureInterfaceCreationFlags | Final, List(SingletonType), EmptyScope) - lazy val ConstantType: TypeRef = ConstantClass.typeRef lazy val SeqType: TypeRef = if (isNewCollections) ctx.requiredClassRef("scala.collection.immutable.Seq") @@ -741,8 +740,6 @@ class Definitions { def ImplicitNotFoundAnnot(implicit ctx: Context) = ImplicitNotFoundAnnotType.symbol.asClass lazy val ForceInlineAnnotType = ctx.requiredClassRef("scala.forceInline") def ForceInlineAnnot(implicit ctx: Context) = ForceInlineAnnotType.symbol.asClass - lazy val TransparentParamAnnotType = ctx.requiredClassRef("scala.annotation.internal.TransparentParam") - def TransparentParamAnnot(implicit ctx: Context) = TransparentParamAnnotType.symbol.asClass lazy val InvariantBetweenAnnotType = ctx.requiredClassRef("scala.annotation.internal.InvariantBetween") def InvariantBetweenAnnot(implicit ctx: Context) = InvariantBetweenAnnotType.symbol.asClass lazy val MigrationAnnotType = ctx.requiredClassRef("scala.annotation.migration") diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 8d894bdfa034..15a68e703f76 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -563,9 +563,6 @@ object Flags { /** A transparent implicit method */ final val TransparentImplicitMethod = allOf(Transparent, Implicit, Method) - /** A transparent parameter */ - final val TransparentParam = allOf(Transparent, Param) - /** An enum case */ final val EnumCase = allOf(Enum, Case) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8834479eaf5e..da22215a5ff1 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -3016,15 +3016,8 @@ object Types { * - add @inlineParam to transparent call-by-value parameters */ def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = { - def translateTransparent(tp: Type): Type = tp match { - case _: ExprType => tp - case _ => AnnotatedType(tp, Annotation(defn.TransparentParamAnnot)) - } - def paramInfo(param: Symbol) = { - val paramType = param.info.annotatedToRepeated - if (param.is(Transparent)) translateTransparent(paramType) else paramType - } - + def paramInfo(param: Symbol) = + param.info.annotatedToRepeated apply(params.map(_.name.asTermName))( tl => params.map(p => tl.integrate(params, paramInfo(p))), tl => tl.integrate(params, resultType)) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 18baba35ea6c..6ca12512f738 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1913,12 +1913,12 @@ object Parsers { /** ClsParamClauses ::= {ClsParamClause} [[nl] `(' [FunArgMods] ClsParams `)'] * ClsParamClause ::= [nl] `(' [`erased'] [ClsParams] ')' * ClsParams ::= ClsParam {`' ClsParam} - * ClsParam ::= {Annotation} [{Modifier} (`val' | `var') | `inline'] Param + * ClsParam ::= {Annotation} [{Modifier} (`val' | `var')] Param * DefParamClauses ::= {DefParamClause} [[nl] `(' [FunArgMods] DefParams `)'] * DefParamClause ::= [nl] `(' [`erased'] [DefParams] ')' * DefParams ::= DefParam {`,' DefParam} - * DefParam ::= {Annotation} [`inline'] Param - * Param ::= id `:' ParamType [`=' Expr] + * DefParam ::= {Annotation} Param + * Param ::= id :' ParamType [`=' Expr] */ def paramClauses(owner: Name, ofCaseClass: Boolean = false): List[List[ValDef]] = { var imods: Modifiers = EmptyModifiers @@ -1940,7 +1940,7 @@ object Parsers { addMod(mods, mod) } else { - if (!(mods.flags &~ (ParamAccessor | Transparent)).isEmpty) + if (!(mods.flags &~ ParamAccessor).isEmpty) syntaxError("`val' or `var' expected") if (firstClauseOfCaseClass) mods else mods | PrivateLocal @@ -1948,7 +1948,6 @@ object Parsers { } } else { - if (in.token == TRANSPARENT) mods = addModifier(mods) mods = atPos(start) { mods | Param } } atPos(start, nameStart) { diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index a5b78a2c0ebf..4813e4ff737f 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -254,6 +254,8 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase super.transform(_).asInstanceOf[Template])) } case tree: ValDef => + if (tree.symbol.is(Param) && !tree.symbol.owner.is(Transparent) && tree.tpt.tpe.derivesFrom(defn.ConstantClass)) + ctx.error("only parameters of transparent method can have Constant type", tree.pos) val tree1 = cpy.ValDef(tree)(rhs = normalizeErasedRhs(tree.rhs, tree.symbol)) transformMemberDef(tree1) super.transform(tree1) diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index d5766bc2e23d..ed684f601057 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -504,7 +504,7 @@ class ReifyQuotes extends MacroTransformWithImplicits { val captured = mutable.LinkedHashMap.empty[Symbol, Tree] val captured2 = capturer(captured) - outer.enteredSyms.foreach(sym => if (!sym.is(Transparent)) capturers.put(sym, captured2)) + outer.enteredSyms.foreach(sym => if (!sym.info.derivesFrom(defn.ConstantClass)) capturers.put(sym, captured2)) val tree2 = transform(tree) capturers --= outer.enteredSyms @@ -550,7 +550,7 @@ class ReifyQuotes extends MacroTransformWithImplicits { splice(ref(splicedType).select(tpnme.UNARY_~).withPos(tree.pos)) case tree: Select if tree.symbol.isSplice => splice(tree) - case tree: RefTree if tree.symbol.is(Transparent) && tree.symbol.is(Param) => + case tree: RefTree if tree.symbol.is(Param) && tree.tpe.derivesFrom(defn.ConstantClass) => tree case tree: RefTree if isCaptured(tree.symbol, level) => val t = capturers(tree.symbol).apply(tree) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index c0a077e441b2..bd02594789f2 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -240,9 +240,9 @@ object Splicer { def unexpectedTree(tree: tpd.Tree)(implicit env: Env): Boolean = { // Assuming that top-level splices can only be in transparent methods - // and splices are expanded at inline site, references to transparent values + // and splices are expanded at inline site, references to parameter wit constant type // will be know literal constant trees. - tree.symbol.is(Transparent) + tree.symbol.is(Param) && tree.tpe.derivesFrom(defn.ConstantClass) } } diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 10bf1c2032db..2f1686b36f47 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -221,10 +221,9 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { bindingsBuf: mutable.ListBuffer[MemberDef]): MemberDef = { val argtpe = arg.tpe.dealiasKeepAnnots val isByName = paramtp.dealias.isInstanceOf[ExprType] - val inlineFlag = if (paramtp.hasAnnotation(defn.TransparentParamAnnot)) Transparent else EmptyFlags val (bindingFlags, bindingType) = if (isByName) (Method, ExprType(argtpe.widen)) - else (inlineFlag, argtpe.widen) + else (EmptyFlags, argtpe.widen) val boundSym = newSym(name, bindingFlags, bindingType).asTerm val binding = if (isByName) DefDef(boundSym, arg.changeOwner(ctx.owner, boundSym)) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 240999864503..e7a1ca38437a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2385,8 +2385,6 @@ class Typer extends Namer readaptSimplified(Inliner.inlineCall(tree, pt)) } else if (tree.tpe <:< pt) { - if (pt.hasAnnotation(defn.TransparentParamAnnot)) - checkTransparentConformant(tree, isFinal = false, "argument to transparent parameter") if (ctx.typeComparer.GADTused && pt.isValueType) // Insert an explicit cast, so that -Ycheck in later phases succeeds. // I suspect, but am not 100% sure that this might affect inferred types, diff --git a/library/src/scala/annotation/internal/TransparentParam.scala b/library/src/scala/annotation/internal/TransparentParam.scala deleted file mode 100644 index 1560fa073449..000000000000 --- a/library/src/scala/annotation/internal/TransparentParam.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scala.annotation.internal - -import scala.annotation.Annotation - -/** An annotation produced by Namer to indicate a transparent parameter */ -final class TransparentParam() extends Annotation diff --git a/tests/neg/i4433.scala b/tests/neg/i4433.scala index 71cbf64ac00e..43999be975a7 100644 --- a/tests/neg/i4433.scala +++ b/tests/neg/i4433.scala @@ -1,6 +1,6 @@ object Foo { - transparent def g(transparent p: Int => Boolean): Boolean = ~{ // error + transparent def g(p: (Int => Boolean) & Constant): Boolean = ~{ // error if(p(5)) '(true) else '(false) } diff --git a/tests/neg/inlinevals-2.scala b/tests/neg/inlinevals-2.scala new file mode 100644 index 000000000000..248fb647c052 --- /dev/null +++ b/tests/neg/inlinevals-2.scala @@ -0,0 +1,20 @@ +object Test { + + def power0(x: Double, n: Int & Constant): Double = ??? // error + + transparent def power(x: Double, n: Int & Constant): Double = ??? // ok + + transparent val N = 10 + def X = 20 + + class C(x: Int & Constant, private val y: Int & Constant) // error // error + + transparent def foo(x: Int) = { + + def f(xs: List[Int] & Constant) = xs // error + + transparent val y = { println("hi"); 1 } // ok + transparent val z = x // ok + + } +} diff --git a/tests/neg/inlinevals.scala b/tests/neg/inlinevals.scala index c754991e567c..8b665c3d6aa2 100644 --- a/tests/neg/inlinevals.scala +++ b/tests/neg/inlinevals.scala @@ -1,35 +1,24 @@ object Test { - def power0(x: Double, transparent n: Int): Double = ??? // error - - transparent def power(x: Double, transparent n: Int): Double = ??? // ok + transparent def power(x: Double, n: Int & Constant): Double = ??? // ok transparent val N = 10 def X = 20 transparent transparent val twice = 30 // error: repeated modifier - class C(transparent x: Int, private transparent val y: Int) { // error // error + class C { transparent val foo: Int // error: abstract member may not be inline transparent def bar: Int // error: abstract member may not be inline } - power(2.0, N) // ok, since it's a by-name parameter + power(2.0, N) // ok, since parameter is inlined power(2.0, X) // error: argument to transparent parameter must be a constant expression transparent val M = X // error: rhs must be constant expression transparent val xs = List(1, 2, 3) // error: must be a constant expression - transparent def foo(x: Int) = { - - def f(transparent xs: List[Int]) = xs // error - - transparent val y = { println("hi"); 1 } // ok - transparent val z = x // ok - - } - - transparent def byname(transparent f: => String): Int = ??? // ok + transparent def byname(f: => String): Int = ??? // ok } diff --git a/tests/neg/quote-error-2/Macro_1.scala b/tests/neg/quote-error-2/Macro_1.scala index dd65339495db..18c3cf4ec0e8 100644 --- a/tests/neg/quote-error-2/Macro_1.scala +++ b/tests/neg/quote-error-2/Macro_1.scala @@ -1,7 +1,7 @@ import quoted._ object Macro_1 { - transparent def foo(transparent b: Boolean): Unit = ~fooImpl(b) + transparent def foo(b: Boolean & Constant): Unit = ~fooImpl(b) def fooImpl(b: Boolean): Expr[Unit] = '(println(~msg(b))) diff --git a/tests/neg/quote-error/Macro_1.scala b/tests/neg/quote-error/Macro_1.scala index aae163486c95..d9a190921219 100644 --- a/tests/neg/quote-error/Macro_1.scala +++ b/tests/neg/quote-error/Macro_1.scala @@ -1,7 +1,7 @@ import quoted._ object Macro_1 { - transparent def foo(transparent b: Boolean): Unit = ~fooImpl(b) + transparent def foo(b: Boolean & Constant): Unit = ~fooImpl(b) def fooImpl(b: Boolean): Expr[Unit] = if (b) '(println("foo(true)")) else QuoteError("foo cannot be called with false") diff --git a/tests/neg/quote-exception/Macro_1.scala b/tests/neg/quote-exception/Macro_1.scala index 3f18f2001cc0..915d06270955 100644 --- a/tests/neg/quote-exception/Macro_1.scala +++ b/tests/neg/quote-exception/Macro_1.scala @@ -1,7 +1,7 @@ import quoted._ object Macro_1 { - transparent def foo(transparent b: Boolean): Unit = ~fooImpl(b) + transparent def foo(b: Boolean & Constant): Unit = ~fooImpl(b) def fooImpl(b: Boolean): Expr[Unit] = if (b) '(println("foo(true)")) else ??? diff --git a/tests/neg/quote-macro-complex-arg-0.scala b/tests/neg/quote-macro-complex-arg-0.scala index d27dc66e6843..6f7571843cbf 100644 --- a/tests/neg/quote-macro-complex-arg-0.scala +++ b/tests/neg/quote-macro-complex-arg-0.scala @@ -1,6 +1,6 @@ import scala.quoted._ object Macros { - transparent def foo(transparent i: Int, dummy: Int, j: Int): Int = ~bar(i + 1, '(j)) // error: i + 1 is not a parameter or field reference + transparent def foo(i: Int & Constant, dummy: Int, j: Int): Int = ~bar(i + 1, '(j)) // error: i + 1 is not a parameter or field reference def bar(x: Int, y: Expr[Int]): Expr[Int] = '{ ~x.toExpr + ~y } } diff --git a/tests/neg/quote-splice-interpret-1.scala b/tests/neg/quote-splice-interpret-1.scala index 26fd25f5e299..868ddc08e9d7 100644 --- a/tests/neg/quote-splice-interpret-1.scala +++ b/tests/neg/quote-splice-interpret-1.scala @@ -2,7 +2,7 @@ import scala.quoted._ object Macros { - transparent def isZero(transparent n: Int): Boolean = ~{ // error + transparent def isZero(n: Int & Constant): Boolean = ~{ // error if (n == 0) '(true) else '(false) } diff --git a/tests/pos/constant-types.scala b/tests/pos/constant-types.scala index 93684e745aeb..5f2089c02940 100644 --- a/tests/pos/constant-types.scala +++ b/tests/pos/constant-types.scala @@ -1,6 +1,6 @@ object Constants { - def f[C <: Constant](c: C): Unit = () + transparent def f[C <: Constant](c: C): Unit = () f(true) f(1) f(2L) @@ -9,19 +9,19 @@ object Constants { f('a') f("abc") - def fBool(c: Boolean & Constant): Unit = () + transparent def fBool(c: Boolean & Constant): Unit = () fBool(true) fBool(false) transparent def bb: Boolean = true fBool(bb) - def fInt(c: Int & Constant): Unit = () + transparent def fInt(c: Int & Constant): Unit = () fInt(1) fInt(2) transparent def ii: Int = 4 fInt(ii) - def fChar(c: Char & Constant): Unit = () + transparent def fChar(c: Char & Constant): Unit = () fChar('a') fChar('b') transparent def cc: Char = 'd' diff --git a/tests/pos/i1570.decompiled b/tests/pos/i1570.decompiled index 31051997bd70..2d20b8c33596 100644 --- a/tests/pos/i1570.decompiled +++ b/tests/pos/i1570.decompiled @@ -1,5 +1,5 @@ /** Decompiled from out/posTestFromTasty/pos/i1570/Test.class */ object Test { - transparent def foo(n: scala.Int): scala.Int = Test.bar(n) - transparent def bar(n: scala.Int): scala.Int = n + transparent def foo(n: scala.Int & scala.Constant): scala.Int & scala.Constant = Test.bar(n) + transparent def bar(n: scala.Int & scala.Constant): scala.Int & scala.Constant = n } diff --git a/tests/pos/i1570.scala b/tests/pos/i1570.scala index c3fa7538d800..fa93d893b32e 100644 --- a/tests/pos/i1570.scala +++ b/tests/pos/i1570.scala @@ -1,4 +1,4 @@ object Test { - transparent def foo(transparent n: Int) = bar(n) - transparent def bar(transparent n: Int) = n + transparent def foo(n: Int & Constant) = bar(n) + transparent def bar(n: Int & Constant) = n } diff --git a/tests/pos/i3898b/quoted_1.scala b/tests/pos/i3898b/quoted_1.scala index ca551862af67..7369480aec5d 100644 --- a/tests/pos/i3898b/quoted_1.scala +++ b/tests/pos/i3898b/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { - transparent def ff(x: Int, transparent y: Int): String = ~impl('(x)) + transparent def ff(x: Int, y: Int & Constant): String = ~impl('(x)) def impl(x: Expr[Int]): Expr[String] = '("") } diff --git a/tests/pos/i3898c/quoted_1.scala b/tests/pos/i3898c/quoted_1.scala index ca551862af67..7369480aec5d 100644 --- a/tests/pos/i3898c/quoted_1.scala +++ b/tests/pos/i3898c/quoted_1.scala @@ -1,5 +1,5 @@ import scala.quoted._ object Macro { - transparent def ff(x: Int, transparent y: Int): String = ~impl('(x)) + transparent def ff(x: Int, y: Int & Constant): String = ~impl('(x)) def impl(x: Expr[Int]): Expr[String] = '("") } diff --git a/tests/pos/i4846.scala b/tests/pos/i4846.scala index c19ea709ebbf..e2b1d74d6584 100644 --- a/tests/pos/i4846.scala +++ b/tests/pos/i4846.scala @@ -1,6 +1,6 @@ import scala.quoted._ object Test { - transparent def foo(transparent x: Int): Int = ~fooImpl(x, '(x), '( '(x) ), '( '( '(x) ) )) + transparent def foo(x: Int & Constant): Int = ~fooImpl(x, '(x), '( '(x) ), '( '( '(x) ) )) def fooImpl(a: Int, b: Expr[Int], c: Expr[Expr[Int]], d: Expr[Expr[Expr[Int]]]): Expr[Int] = ??? } diff --git a/tests/pos/power-macro/Macro_1.scala b/tests/pos/power-macro/Macro_1.scala index 1881dcb467cc..48c0356defc3 100644 --- a/tests/pos/power-macro/Macro_1.scala +++ b/tests/pos/power-macro/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted.Expr object PowerMacro { - transparent def power(transparent n: Long, x: Double) = ~powerCode(n, '(x)) + transparent def power(n: Long & Constant, x: Double) = ~powerCode(n, '(x)) def powerCode(n: Long, x: Expr[Double]): Expr[Double] = if (n == 0) '(1.0) diff --git a/tests/pos/power-macro/PowerInlined-1_2.scala b/tests/pos/power-macro/PowerInlined-1_2.scala index ec46c956cc28..889610fbe06b 100644 --- a/tests/pos/power-macro/PowerInlined-1_2.scala +++ b/tests/pos/power-macro/PowerInlined-1_2.scala @@ -1,5 +1,5 @@ object PowerInlined1 { import PowerMacro._ - power(1, 5.0) // 1 quotes to unpickle + power(1L, 5.0) // 1 quotes to unpickle } diff --git a/tests/pos/quote-lift-inline-params-b.scala b/tests/pos/quote-lift-inline-params-b.scala index d1c90d375183..dbf07f396ec1 100644 --- a/tests/pos/quote-lift-inline-params-b.scala +++ b/tests/pos/quote-lift-inline-params-b.scala @@ -1,7 +1,7 @@ import scala.quoted.Expr import quoted.Liftable.{IntIsLiftable => _} object Macro { - transparent def foo(transparent n: Int): Int = ~{ + transparent def foo(n: Int & Constant): Int = ~{ '(n) } } \ No newline at end of file diff --git a/tests/pos/quote-lift-inline-params/Macro_1.scala b/tests/pos/quote-lift-inline-params/Macro_1.scala index 257adddc39e0..5555109ee02a 100644 --- a/tests/pos/quote-lift-inline-params/Macro_1.scala +++ b/tests/pos/quote-lift-inline-params/Macro_1.scala @@ -1,7 +1,7 @@ import scala.quoted.Expr object Macro { import quoted.Liftable.{IntIsLiftable => _} - transparent def foo(transparent n: Int): Int = ~{ + transparent def foo(n: Int & Constant): Int = ~{ '(n) } -} \ No newline at end of file +} diff --git a/tests/pos/quote-nested-object/Macro_1.scala b/tests/pos/quote-nested-object/Macro_1.scala index cda302351c2b..0de1c16f2fbe 100644 --- a/tests/pos/quote-nested-object/Macro_1.scala +++ b/tests/pos/quote-nested-object/Macro_1.scala @@ -6,7 +6,7 @@ object Macro { object Implementation { - transparent def plus(transparent n: Int, m: Int): Int = ~plus(n, '(m)) + transparent def plus(n: Int & Constant, m: Int): Int = ~plus(n, '(m)) def plus(n: Int, m: Expr[Int]): Expr[Int] = if (n == 0) m @@ -14,7 +14,7 @@ object Macro { object Implementation2 { - transparent def plus(transparent n: Int, m: Int): Int = ~plus(n, '(m)) + transparent def plus(n: Int & Constant, m: Int): Int = ~plus(n, '(m)) def plus(n: Int, m: Expr[Int]): Expr[Int] = if (n == 0) m diff --git a/tests/run/i1569.scala b/tests/run/i1569.scala index ef64021e016e..d2decf38b9f2 100644 --- a/tests/run/i1569.scala +++ b/tests/run/i1569.scala @@ -1,5 +1,5 @@ object Test { - transparent def foo(transparent n: => Int) = n + n + transparent def foo(n: => Int & Constant) = n + n def main(args: Array[String]): Unit = foo({ println("foo"); 42 }) } diff --git a/tests/run/i4455/Macro_1.scala b/tests/run/i4455/Macro_1.scala index 840f3677a5b3..554da1ae6b8b 100644 --- a/tests/run/i4455/Macro_1.scala +++ b/tests/run/i4455/Macro_1.scala @@ -1,8 +1,8 @@ import scala.quoted._ object Macros { - transparent def foo(transparent i: Int): Int = ~bar('(i)) + transparent def foo(i: Int & Constant): Int = ~bar('(i)) - transparent def foo2(transparent i: Int): Int = ~bar('(i + 1)) + transparent def foo2(i: Int & Constant): Int = ~bar('(i + 1)) def bar(x: Expr[Int]): Expr[Int] = x } diff --git a/tests/run/i4735/Macro_1.scala b/tests/run/i4735/Macro_1.scala index ffc609f8e3d2..ddae41d9e23f 100644 --- a/tests/run/i4735/Macro_1.scala +++ b/tests/run/i4735/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Macro { - transparent def unrolledForeach(transparent unrollSize: Int, seq: Array[Int], f: => Int => Unit): Unit = // or f: Int => Unit + transparent def unrolledForeach(unrollSize: Int & Constant, seq: Array[Int], f: => Int => Unit): Unit = // or f: Int => Unit ~unrolledForeachImpl(unrollSize, '(seq), '(f)) private def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ diff --git a/tests/run/i4803/App_2.scala b/tests/run/i4803/App_2.scala index fa550642c722..07cd0baa7219 100644 --- a/tests/run/i4803/App_2.scala +++ b/tests/run/i4803/App_2.scala @@ -1,20 +1,20 @@ class Num2(x: Double) { - transparent def power(transparent n: Long) = ~PowerMacro.powerCode('(x), n) + transparent def power(n: Long & Constant) = ~PowerMacro.powerCode('(x), n) } object Test { def main(args: Array[String]): Unit = { val n = new Num(1.5) - println(n.power(0)) - println(n.power(1)) - println(n.power(2)) - println(n.power(5)) + println(n.power(0L)) + println(n.power(1L)) + println(n.power(2L)) + println(n.power(5L)) val n2 = new Num2(1.5) - println(n.power(0)) - println(n.power(1)) - println(n.power(2)) - println(n.power(5)) + println(n.power(0L)) + println(n.power(1L)) + println(n.power(2L)) + println(n.power(5L)) } } diff --git a/tests/run/i4803/Macro_1.scala b/tests/run/i4803/Macro_1.scala index deae9bead04e..02990563b489 100644 --- a/tests/run/i4803/Macro_1.scala +++ b/tests/run/i4803/Macro_1.scala @@ -8,5 +8,5 @@ object PowerMacro { } class Num(x: Double) { - transparent def power(transparent n: Long) = ~PowerMacro.powerCode('(x), n) + transparent def power(n: Long & Constant) = ~PowerMacro.powerCode('(x), n) } diff --git a/tests/run/i4803b/App_2.scala b/tests/run/i4803b/App_2.scala index 2e93422e36cf..62b549b3beef 100644 --- a/tests/run/i4803b/App_2.scala +++ b/tests/run/i4803b/App_2.scala @@ -2,7 +2,7 @@ class Nums { class Num(x: Double) { - transparent def power(transparent n: Long) = ~PowerMacro.powerCode('(x), n) + transparent def power(n: Long & Constant) = ~PowerMacro.powerCode('(x), n) } } @@ -10,9 +10,9 @@ object Test { def main(args: Array[String]): Unit = { val nums = new Nums val n = new nums.Num(1.5) - println(n.power(0)) - println(n.power(1)) - println(n.power(2)) - println(n.power(5)) + println(n.power(0L)) + println(n.power(1L)) + println(n.power(2L)) + println(n.power(5L)) } } diff --git a/tests/run/i4803c/App_2.scala b/tests/run/i4803c/App_2.scala index f3b2655b8c2c..a59e0cf6f8b3 100644 --- a/tests/run/i4803c/App_2.scala +++ b/tests/run/i4803c/App_2.scala @@ -2,21 +2,21 @@ object Test { def main(args: Array[String]): Unit = { class Num(x: Double) { - transparent def power(transparent n: Long) = ~PowerMacro.powerCode('(x), n) + transparent def power(n: Long & Constant) = ~PowerMacro.powerCode('(x), n) } val n = new Num(1.5) - println(n.power(0)) - println(n.power(1)) - println(n.power(2)) - println(n.power(5)) + println(n.power(0L)) + println(n.power(1L)) + println(n.power(2L)) + println(n.power(5L)) - transparent def power(x: Double, transparent n: Long) = ~PowerMacro.powerCode('(x), n) + transparent def power(x: Double, n: Long & Constant) = ~PowerMacro.powerCode('(x), n) val x: Double = 1.5 - println(power(x, 0)) - println(power(x, 1)) - println(power(x, 2)) - println(power(x, 5)) + println(power(x, 0L)) + println(power(x, 1L)) + println(power(x, 2L)) + println(power(x, 5L)) } } diff --git a/tests/run/i4803d/App_2.scala b/tests/run/i4803d/App_2.scala index 293882746f0b..0bc5cc24ad47 100644 --- a/tests/run/i4803d/App_2.scala +++ b/tests/run/i4803d/App_2.scala @@ -11,7 +11,7 @@ object Test { } transparent def power2(x: Double) = { - transparent def power(x: Double, transparent n: Long) = ~PowerMacro.powerCode('(x), n) - power(x, 2) + transparent def power(x: Double, n: Long & Constant) = ~PowerMacro.powerCode('(x), n) + power(x, 2L) } } diff --git a/tests/run/lst/Lst.scala b/tests/run/lst/Lst.scala index 85ef6729c081..740eba58b5ea 100644 --- a/tests/run/lst/Lst.scala +++ b/tests/run/lst/Lst.scala @@ -37,7 +37,7 @@ class Lst[+T](val elems: Any) extends AnyVal { self => } } - transparent def foreachReversed(transparent op: T => Unit): Unit = locally { + transparent def foreachReversed(op: => T => Unit): Unit = locally { def sharedOp(x: T) = op(x) elems match { case null => diff --git a/tests/run/quote-and-splice/Macros_1.scala b/tests/run/quote-and-splice/Macros_1.scala index 7e35671af6eb..9282463e32f5 100644 --- a/tests/run/quote-and-splice/Macros_1.scala +++ b/tests/run/quote-and-splice/Macros_1.scala @@ -5,7 +5,7 @@ object Macros { transparent def macro1 = ~ macro1Impl def macro1Impl = '(3) - transparent def macro2(transparent p: Boolean) = ~ macro2Impl(p) + transparent def macro2(p: Boolean & Constant) = ~ macro2Impl(p) def macro2Impl(p: Boolean) = if (p) '(3) else '(4) transparent def macro3(n: Int) = ~ macro3Impl('(n)) @@ -17,7 +17,7 @@ object Macros { transparent def macro5(i: Int, j: Int) = ~ macro5Impl(j = '(j), i = '(i)) def macro5Impl(i: Expr[Int], j: Expr[Int]) = '{ ~i + ~j } - transparent def power(transparent n: Int, x: Double) = ~powerCode(n, '(x)) + transparent def power(n: Int & Constant, x: Double) = ~powerCode(n, '(x)) def powerCode(n: Int, x: Expr[Double]): Expr[Double] = if (n == 0) '(1.0) diff --git a/tests/run/quote-simple-macro/quoted_1.scala b/tests/run/quote-simple-macro/quoted_1.scala index 04a49e3289d2..45a47049259b 100644 --- a/tests/run/quote-simple-macro/quoted_1.scala +++ b/tests/run/quote-simple-macro/quoted_1.scala @@ -1,6 +1,6 @@ import scala.quoted._ object Macros { - transparent def foo(transparent i: Int, dummy: Int, j: Int): Int = ~bar(i, '(j)) + transparent def foo(i: Int & Constant, dummy: Int, j: Int): Int = ~bar(i, '(j)) def bar(x: Int, y: Expr[Int]): Expr[Int] = '{ ~x.toExpr + ~y } } diff --git a/tests/run/quote-unrolled-foreach/quoted_1.scala b/tests/run/quote-unrolled-foreach/quoted_1.scala index f5a8b5ee5049..c9cfb05b42be 100644 --- a/tests/run/quote-unrolled-foreach/quoted_1.scala +++ b/tests/run/quote-unrolled-foreach/quoted_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ object Macro { - transparent def unrolledForeach(transparent unrollSize: Int, seq: Array[Int])(f: => Int => Unit): Unit = // or f: Int => Unit + transparent def unrolledForeach(unrollSize: Int & Constant, seq: Array[Int])(f: => Int => Unit): Unit = // or f: Int => Unit ~unrolledForeachImpl(unrollSize, '(seq), '(f)) private def unrolledForeachImpl(unrollSize: Int, seq: Expr[Array[Int]], f: Expr[Int => Unit]): Expr[Unit] = '{ diff --git a/tests/run/typelevel-patmat.scala b/tests/run/typelevel-patmat.scala index 6bacf57e2037..ce54723b5712 100644 --- a/tests/run/typelevel-patmat.scala +++ b/tests/run/typelevel-patmat.scala @@ -21,7 +21,7 @@ object Test extends App { type HNil = HNil.type type Z = Z.type - transparent def ToNat(transparent n: Int): Typed[Nat] = + transparent def ToNat(n: Int & Constant): Typed[Nat] = if n == 0 then Typed(Z) else Typed(S(ToNat(n - 1).value)) diff --git a/tests/run/typelevel.scala b/tests/run/typelevel.scala index ee7bf50521f2..a6b987e31190 100644 --- a/tests/run/typelevel.scala +++ b/tests/run/typelevel.scala @@ -42,7 +42,7 @@ object Test extends App { type HNil = HNil.type type Z = Z.type - transparent def ToNat(transparent n: Int): ToNat[Nat] = + transparent def ToNat(n: Int & Constant): ToNat[Nat] = if n == 0 then new ToNat(Z) else { val n1 = ToNat(n - 1) @@ -101,7 +101,7 @@ object Test extends App { transparent val l1 = xs.length val l1a: 2 = l1 - transparent def index(xs: HList, transparent idx: Int): Any = + transparent def index(xs: HList, idx: Int & Constant): Any = if idx == 0 then xs.head else index(xs.tail, idx - 1)