diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 6126ca6587d0..d8d4e2b2662c 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -615,11 +615,11 @@ object Semantic { def checkArgsWithParametricity() = val methodType = atPhaseBeforeTransforms { meth.info.stripPoly } - var allArgsPromote = true + var allArgsHot = true val allParamTypes = methodType.paramInfoss.flatten.map(_.repeatedToSingle) val errors = allParamTypes.zip(args).flatMap { (info, arg) => val errors = Reporter.errorsIn { arg.promote } - allArgsPromote = allArgsPromote && errors.isEmpty + allArgsHot = allArgsHot && errors.isEmpty info match case typeParamRef: TypeParamRef => val bounds = typeParamRef.underlying.bounds @@ -632,7 +632,7 @@ object Semantic { if isWithinBounds && !otherParamContains then Nil else errors case _ => errors } - (errors, allArgsPromote) + (errors, allArgsHot) // fast track if the current object is already initialized if promoted.isCurrentObjectPromoted then Hot @@ -640,13 +640,13 @@ object Semantic { else if meth eq defn.Any_asInstanceOf then value else value match { case Hot => - if isSyntheticApply(meth) then + if isSyntheticApply(meth) && meth.hasSource then val klass = meth.owner.companionClass.asClass instantiate(klass, klass.primaryConstructor, args) else if receiver.typeSymbol.isStaticOwner then - val (errors, allArgsPromote) = checkArgsWithParametricity() - if allArgsPromote then + val (errors, allArgsHot) = checkArgsWithParametricity() + if allArgsHot then Hot: Value else if errors.nonEmpty then reporter.reportAll(errors) diff --git a/tests/init/neg/some-this.scala b/tests/init/neg/some-this.scala deleted file mode 100644 index f572b997c168..000000000000 --- a/tests/init/neg/some-this.scala +++ /dev/null @@ -1,2 +0,0 @@ -class X: - val some = Some(this) // error \ No newline at end of file diff --git a/tests/init/pos/i9795/A.scala b/tests/init/pos/i9795/A.scala new file mode 100644 index 000000000000..33c13b2eb592 --- /dev/null +++ b/tests/init/pos/i9795/A.scala @@ -0,0 +1,7 @@ +class A: + // Safe initialization check only allows capturing `this` either through primary constructor or synthetic `apply` + // `Some` case class comes from Scala 2 stdlib, which is not visible, hence the warning + // For reference: + // https://github.com/lampepfl/dotty/pull/12711 + // https://github.com/lampepfl/dotty/pull/14283 + val some = Some(this)