diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 5a0e03330ef2..0d1a579de036 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -367,6 +367,7 @@ object Contexts { /** Is current phase after TyperPhase? */ final def isAfterTyper = base.isAfterTyper(phase) + final def isAfterInlining = base.isAfterInlining(phase) final def isTyper = base.isTyper(phase) /** Is this a context for the members of a class definition? */ diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala index ee9ee4006919..ba9ae4b8d96b 100644 --- a/compiler/src/dotty/tools/dotc/core/Phases.scala +++ b/compiler/src/dotty/tools/dotc/core/Phases.scala @@ -305,6 +305,8 @@ object Phases { } final def isAfterTyper(phase: Phase): Boolean = phase.id > typerPhase.id + final def isAfterInlining(phase: Phase): Boolean = + inliningPhase != NoPhase && phase.id > inliningPhase.id final def isTyper(phase: Phase): Boolean = phase.id == typerPhase.id } @@ -375,6 +377,7 @@ object Phases { val doCheckJava = skipIfJava && !isAfterLastJavaPhase for unit <- units do ctx.profiler.onUnit(this, unit): given unitCtx: Context = runCtx.fresh.setPhase(this.start).setCompilationUnit(unit).withRootImports + val previousTyperState = unitCtx.typerState.snapshot() if ctx.run.enterUnit(unit) then try if doCheckJava && unit.typedAsJava then @@ -384,6 +387,7 @@ object Phases { buf += unitCtx.compilationUnit catch case _: CompilationUnit.SuspendException => // this unit will be run again in `Run#compileSuspendedUnits` + unitCtx.typerState.resetTo(previousTyperState) case ex: Throwable if !ctx.run.enrichedErrorMessage => println(ctx.run.enrichErrorMessage(s"unhandled exception while running $phaseName on $unit")) throw ex diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 5e919a660579..1a82eed2de69 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2974,7 +2974,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer typedExpr(_, tpt1.tpe.widenExpr) val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) postProcessInfo(vdef1, sym) - vdef1.setDefTree + if (!ctx.isAfterInlining) vdef1.setDefTree migrate(ImplicitToGiven.valDef(vdef1)) @@ -3097,7 +3097,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer if (!sym.isOneOf(Synthetic | InlineProxy | Param) && sym.info.finalResultType.isRepeatedParam) report.error(em"Cannot return repeated parameter type ${sym.info.finalResultType}", sym.srcPos) mdef.ensureHasSym(sym) - mdef.setDefTree + if (!ctx.isAfterInlining) mdef.setDefTree + else mdef def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(using Context): Tree = ctx.profiler.onTypedDef(sym) { val TypeDef(name, rhs) = tdef diff --git a/tests/pos-macros/i22584/Macro.scala b/tests/pos-macros/i22584/Macro.scala index f0b9c7409520..46d4d39565de 100644 --- a/tests/pos-macros/i22584/Macro.scala +++ b/tests/pos-macros/i22584/Macro.scala @@ -22,7 +22,7 @@ object Macros { } } - val expected = "List(DefDef(boolean,List(List()),TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Boolean)],Select(This(Ident(MyClass1)),boolean)), DefDef(finalVal,List(List()),TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String)],Select(This(Ident(MyClass1)),finalVal)), DefDef(int,List(List()),TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int)],Select(This(Ident(MyClass1)),int)), DefDef(string,List(List()),TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String)],Select(This(Ident(MyClass1)),string)))" + val expected = "List(ValDef(boolean,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),object scala),class Boolean)],EmptyTree), ValDef(finalVal,Ident(String),Literal(Constant(result))), ValDef(int,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),object scala),class Int)],EmptyTree), ValDef(string,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],EmptyTree))" assert(caseFieldValOrDefDefs.toString == expected) '{ () } diff --git a/tests/pos/i21176-a/Macro.scala b/tests/pos/i21176-a/Macro.scala new file mode 100644 index 000000000000..bd937f6292ac --- /dev/null +++ b/tests/pos/i21176-a/Macro.scala @@ -0,0 +1,12 @@ +//> using options -Wsafe-init +import scala.quoted.* + +class Macro: + def tuple[T](name: String): (String, List[T]) = (name, List[T]()) + inline def nameTuple[T]: (String, List[T]) = tuple(Macro.named) + +object Macro: + def namedMacro(using q: Quotes): Expr[String] = + Expr("test") + + inline def named: String = ${Macro.namedMacro} diff --git a/tests/pos/i21176-a/Main.scala b/tests/pos/i21176-a/Main.scala new file mode 100644 index 000000000000..3af179c4b698 --- /dev/null +++ b/tests/pos/i21176-a/Main.scala @@ -0,0 +1,7 @@ +//> using options -Wsafe-init +class Test extends Macro: + val abc = nameTuple[Int] + +@main +def run(): Unit = + println(new Test().abc) diff --git a/tests/pos/i21176-b/Macro.scala b/tests/pos/i21176-b/Macro.scala new file mode 100644 index 000000000000..34e63d610bd5 --- /dev/null +++ b/tests/pos/i21176-b/Macro.scala @@ -0,0 +1,9 @@ +import scala.quoted.* + +class Macro: + inline def nameTuple[NameTuple_T]: (String, List[NameTuple_T]) = Macro.tuple[NameTuple_T](Macro.named) + +object Macro: + def namedMacro(using q: Quotes): Expr[String] = Expr("test") + inline def named: String = ${Macro.namedMacro} + def tuple[Tuple_T](name: String): (String, List[Tuple_T]) = (name, List.empty[Tuple_T]) diff --git a/tests/pos/i21176-b/Main.scala b/tests/pos/i21176-b/Main.scala new file mode 100644 index 000000000000..561f43b32dda --- /dev/null +++ b/tests/pos/i21176-b/Main.scala @@ -0,0 +1,2 @@ +class Test extends Macro: + val abc = nameTuple[Int]