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..a588cc67e03f --- /dev/null +++ b/tests/neg-macros/quote-sym-newtype/Macro_1.scala @@ -0,0 +1,35 @@ +//> using options -experimental -Yno-experimental +import scala.quoted.* + +inline def testMacro = ${ testImpl } + +transparent inline def transparentTestMacro = ${ testImpl } + +def testImpl(using Quotes): Expr[Object] = { + import quotes.reflect.* + + def makeTypesForClass(owner: Symbol): List[Symbol] = + List( + // type Foo1 >: Int <: String + Symbol.newTypeAlias( + owner, + "Foo", + Flags.EmptyFlags, + TypeBounds(TypeRepr.of[Int], TypeRepr.of[String]), + Symbol.noSymbol + ), + // type Foo1 >: [X] =>> Int <: Any + Symbol.newTypeAlias( + owner, + "Foo1", + Flags.EmptyFlags, + TypeBounds(TypeLambda.apply(List("X"), _ => List(TypeBounds.empty), _ => TypeRepr.of[Int]), TypeRepr.of[Any]), + 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("Foo")), TypeDef(clsSymbol.typeMember("Foo1")))) + + 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..19f7a9da2da8 --- /dev/null +++ b/tests/neg-macros/quote-sym-newtype/Test_2.scala @@ -0,0 +1,4 @@ +//> using options -experimental -Yno-experimental +def test = + testMacro // error + transparentTestMacro // error diff --git a/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala b/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala index b38a4304b9d2..84d53b703b42 100644 --- a/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala +++ b/tests/pos-macros/quote-sym-newboundedtype/Macro_1.scala @@ -8,15 +8,51 @@ 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 tp1 >: [X] =>> Int <: Any + Symbol.newBoundedType( + owner, + "tpe1", + Flags.EmptyFlags, + TypeBounds.lower(typeLambda), + Symbol.noSymbol + ), + // type Bla >: Nothing <: [X] =>> Int + Symbol.newBoundedType( + owner, + "tpe2", + Flags.EmptyFlags, + TypeBounds.upper(typeLambda), + Symbol.noSymbol + ), + // type Bar >: [X] =>> Int <: [X] =>> Int + Symbol.newBoundedType( + owner, + "tpe3", + 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")), + TypeDef(clsSymbol.typeMember("tpe3")), + )) 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] }