From 5d06f9676517f18d7827316e58fc4b78dcab538c Mon Sep 17 00:00:00 2001 From: Jan Chyb Date: Tue, 8 Oct 2024 01:29:29 +0200 Subject: [PATCH] Address some review comments --- .../quoted/runtime/impl/QuotesImpl.scala | 4 +- .../quote-sym-newtype/Macro_1.scala | 47 +++++++++++++++++++ .../neg-macros/quote-sym-newtype/Test_2.scala | 6 +++ .../quote-sym-newboundedtype/Macro_1.scala | 39 ++++++++++++--- .../quote-sym-newtype-in-trait/Macro_1.scala | 25 ++++++++-- 5 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 tests/neg-macros/quote-sym-newtype/Macro_1.scala create mode 100644 tests/neg-macros/quote-sym-newtype/Test_2.scala diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 901e0038efd5..e8524a193e5a 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -2653,11 +2653,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def newTypeAlias(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr, privateWithin: Symbol): Symbol = checkValidFlags(flags.toTypeFlags, Flags.validTypeAliasFlags) assert(!tpe.isInstanceOf[Types.TypeBounds], "Passed `tpe` into newTypeAlias should not represent TypeBounds") - dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags | dotc.core.Flags.Deferred, dotc.core.Types.TypeAlias(tpe), privateWithin) + dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags, dotc.core.Types.TypeAlias(tpe), privateWithin) def newBoundedType(owner: Symbol, name: String, flags: Flags, tpe: TypeBounds, privateWithin: Symbol): Symbol = checkValidFlags(flags.toTypeFlags, Flags.validBoundedTypeFlags) - dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags, tpe, privateWithin) + dotc.core.Symbols.newSymbol(owner, name.toTypeName, flags | dotc.core.Flags.Deferred, tpe, privateWithin) def noSymbol: Symbol = dotc.core.Symbols.NoSymbol diff --git a/tests/neg-macros/quote-sym-newtype/Macro_1.scala b/tests/neg-macros/quote-sym-newtype/Macro_1.scala new file mode 100644 index 000000000000..953be0d5497b --- /dev/null +++ b/tests/neg-macros/quote-sym-newtype/Macro_1.scala @@ -0,0 +1,47 @@ +//> using options -experimental -Yno-experimental +import scala.quoted.* + +inline def testConflictingBounds = ${ testConflictingBoundsImpl } +inline def testConflictingBoundsWithTypeLambda = ${ testConflictingBoundsWithTypeLambdaImpl } + +transparent inline def transparentTestConflictingBounds = ${ testConflictingBoundsImpl } +transparent inline def transparentTestConflictingBoundsWithTypeLambda = ${ testConflictingBoundsWithTypeLambdaImpl } + + +def testConflictingBoundsImpl(using Quotes): Expr[Object] = { + import quotes.reflect.* + + def makeType(owner: Symbol): Symbol = + // type Foo >: Int <: String + Symbol.newBoundedType( + owner, + "Foo", + Flags.EmptyFlags, + TypeBounds(TypeRepr.of[Int], TypeRepr.of[String]), + Symbol.noSymbol + ) + makeClass(makeType) +} + +def testConflictingBoundsWithTypeLambdaImpl(using Quotes): Expr[Object] = { + import quotes.reflect.* + def makeType(owner: Symbol): Symbol = + // type Foo >: [X] =>> Int <: Any + Symbol.newBoundedType( + owner, + "Foo", + Flags.EmptyFlags, + TypeBounds(TypeLambda.apply(List("X"), _ => List(TypeBounds.empty), _ => TypeRepr.of[Int]), TypeRepr.of[Any]), + Symbol.noSymbol + ) + makeClass(makeType) +} + +def makeClass(using quotes: Quotes)(typeCons: quotes.reflect.Symbol => quotes.reflect.Symbol) = { + import quotes.reflect.* + val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => List(typeCons(sym)), None) + val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List(TypeDef(clsSymbol.typeMember("Foo")))) + + Block(List(classDef), Apply(Select(New(TypeIdent(clsSymbol)), clsSymbol.primaryConstructor), List.empty)).asExprOf[Object] +} + diff --git a/tests/neg-macros/quote-sym-newtype/Test_2.scala b/tests/neg-macros/quote-sym-newtype/Test_2.scala new file mode 100644 index 000000000000..60fef3cb7322 --- /dev/null +++ b/tests/neg-macros/quote-sym-newtype/Test_2.scala @@ -0,0 +1,6 @@ +//> using options -experimental -Yno-experimental +def test = + transparentTestConflictingBounds // error + transparentTestConflictingBoundsWithTypeLambda // error + // testConflictingBounds // should throw an error here also, to be implemented before stabilisation + // testConflictingBoundsWithTypeLambda // should throw an error here also, to be implemented before stabilisation diff --git a/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala b/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala index b38a4304b9d2..97b7d7566e9a 100644 --- a/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala +++ b/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala @@ -8,15 +8,42 @@ transparent inline def transparentTestMacro = ${ testImpl } def testImpl(using Quotes): Expr[Object] = { import quotes.reflect.* - def makeType(owner: Symbol): Symbol = - Symbol.newBoundedType(owner, "mytype", Flags.EmptyFlags, TypeBounds.lower(TypeRepr.of[String]), Symbol.noSymbol) + def makeBasicType(owner: Symbol): Symbol = + Symbol.newBoundedType(owner, "tpe", Flags.EmptyFlags, TypeBounds.lower(TypeRepr.of[String]), Symbol.noSymbol) - val typeDef = TypeDef(makeType(Symbol.spliceOwner)) + def makeTypesForClass(owner: Symbol): List[Symbol] = + val typeLambda = TypeLambda.apply(List("X"), _ => List(TypeBounds.empty), _ => TypeRepr.of[Int]) + List( + makeBasicType(owner), + // type Bla >: Nothing <: [X] =>> Int + Symbol.newBoundedType( + owner, + "tpe1", + Flags.EmptyFlags, + TypeBounds.upper(typeLambda), + Symbol.noSymbol + ), + // type Bar >: [X] =>> Int <: [X] =>> Int + Symbol.newBoundedType( + owner, + "tpe2", + Flags.EmptyFlags, + TypeBounds(typeLambda, typeLambda), + Symbol.noSymbol + ) + ) + + val typeDef = TypeDef(makeBasicType(Symbol.spliceOwner)) // Expr printer does not work here, see comment: // https://github.com/scala/scala3/pull/20347#issuecomment-2096824617 - assert(typeDef.toString == "TypeDef(mytype,TypeTree[TypeBounds(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class java)),object lang),String),TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any))])") + println(typeDef.toString) + assert(typeDef.toString == "TypeDef(tpe,TypeTree[TypeBounds(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class java)),object lang),String),TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any))])") - val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => List(makeType(sym)), None) - val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List(TypeDef(clsSymbol.typeMember("mytype")))) + val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => makeTypesForClass(sym), None) + val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List( + TypeDef(clsSymbol.typeMember("tpe")), + TypeDef(clsSymbol.typeMember("tpe1")), + TypeDef(clsSymbol.typeMember("tpe2")), + )) Block(List(classDef), Apply(Select(New(TypeIdent(clsSymbol)), clsSymbol.primaryConstructor), List.empty)).asExprOf[Object] } diff --git a/tests/pos-macros/quote-sym-newtype-in-trait/Macro_1.scala b/tests/pos-macros/quote-sym-newtype-in-trait/Macro_1.scala index 1d07c5080e26..60f0587b85a7 100644 --- a/tests/pos-macros/quote-sym-newtype-in-trait/Macro_1.scala +++ b/tests/pos-macros/quote-sym-newtype-in-trait/Macro_1.scala @@ -8,11 +8,28 @@ transparent inline def transparentTestMacro = ${ testImpl } def testImpl(using Quotes): Expr[Object] = { import quotes.reflect.* - def makeType(owner: Symbol): Symbol = - Symbol.newTypeAlias(owner, "mytype", Flags.EmptyFlags, TypeRepr.of[String], Symbol.noSymbol) + def makeBasicType(owner: Symbol): Symbol = + Symbol.newTypeAlias(owner, "tpe", Flags.EmptyFlags, TypeRepr.of[String], Symbol.noSymbol) - val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => List(makeType(sym)), None) - val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List(TypeDef(clsSymbol.typeMember("mytype")))) + def makeTypesForClass(owner: Symbol): List[Symbol] = + val typeLambda = TypeLambda.apply(List("X"), _ => List(TypeBounds.empty), _ => TypeRepr.of[Int]) + List( + makeBasicType(owner), + // type Foo = [X] =>> Int + Symbol.newTypeAlias( + owner, + "tpe1", + Flags.EmptyFlags, + typeLambda, + Symbol.noSymbol + ), + ) + + val clsSymbol = Symbol.newClass(Symbol.spliceOwner, "CLS", List(TypeRepr.of[Object]), sym => makeTypesForClass(sym), None) + val classDef: ClassDef = ClassDef(clsSymbol, List(TypeTree.of[Object]), List( + TypeDef(clsSymbol.typeMember("tpe")), + TypeDef(clsSymbol.typeMember("tpe1")), + )) Block(List(classDef), Apply(Select(New(TypeIdent(clsSymbol)), clsSymbol.primaryConstructor), List.empty)).asExprOf[Object] }