This is an automated email from the ASF dual-hosted git repository.

He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git


The following commit(s) were added to refs/heads/main by this push:
     new b8625a6143 fix: resolve LogSource for getClass results on Scala 3 
(#3609)
b8625a6143 is described below

commit b8625a6143cd778af992497852e0c2fb55b7505e
Author: PJ Fanning <[email protected]>
AuthorDate: Sat Oct 10 06:26:26 2026 +0100

    fix: resolve LogSource for getClass results on Scala 3 (#3609)
    
    Motivation:
    On Scala 3, `Logging(system, getClass)` fails to compile with
    "Cannot find LogSource for Class[? <: Foo]". `getClass` returns a
    wildcard class type, which Scala 3 does not match against
    `LogSource.fromAnyClass[T]: LogSource[Class[T]]`. Scala 2.13 accepts it.
    
    Modification:
    - Make `object LogSource` extend a new `LogSourceCompat` trait.
    - The Scala 3 `LogSourceCompat` adds a lower priority
      `fromAnySubClass[T]: LogSource[Class[? <: T]]` implicit; the Scala 2.13
      version is empty because Scala 2 reports that implicit as ambiguous
      with `fromAnyClass`.
    - `fromAnyClass` is unchanged; changing its signature instead fails MiMa
      with an IncompatibleSignatureProblem.
    - Add `LogSourceSpec`.
    
    Result:
    `Logging(system, getClass)` and `LogSource(getClass, system)` compile
    on Scala 3.
    
    Tests:
    - `actor-tests/Test/testOnly org.apache.pekko.event.LogSourceSpec` on
      Scala 3.3.8 without the fix: compile error "Cannot find LogSource for
      Class[? <: ...LogsWithGetClass]"
    - `actor-tests/Test/testOnly org.apache.pekko.event.LogSourceSpec
      org.apache.pekko.event.LoggerSpec` with the fix: passed on 2.13.18
      and 3.3.8
    - `actor/mimaReportBinaryIssues`: passed on 2.13.18 and 3.3.8
    - scalafmt run on changed files
    
    References:
    Fixes #1538
---
 .../org/apache/pekko/event/LogSourceSpec.scala     | 56 ++++++++++++++++++++++
 .../org/apache/pekko/event/LogSourceCompat.scala   | 28 +++++++++++
 .../org/apache/pekko/event/LogSourceCompat.scala   | 33 +++++++++++++
 .../scala/org/apache/pekko/event/Logging.scala     |  2 +-
 4 files changed, 118 insertions(+), 1 deletion(-)

diff --git 
a/actor-tests/src/test/scala/org/apache/pekko/event/LogSourceSpec.scala 
b/actor-tests/src/test/scala/org/apache/pekko/event/LogSourceSpec.scala
new file mode 100644
index 0000000000..39aff56ff1
--- /dev/null
+++ b/actor-tests/src/test/scala/org/apache/pekko/event/LogSourceSpec.scala
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pekko.event
+
+import org.apache.pekko
+import pekko.testkit.PekkoSpec
+
+object LogSourceSpec {
+  class LogsWithGetClass(system: pekko.actor.ActorSystem) {
+    // `getClass` returns `Class[? <: LogsWithGetClass]`, which did not 
compile on Scala 3
+    val log: LoggingAdapter = Logging(system, getClass)
+    val logSource: (String, Class[?]) = LogSource(getClass, system)
+  }
+}
+
+class LogSourceSpec extends PekkoSpec {
+  import LogSourceSpec._
+
+  "LogSource" must {
+
+    "resolve an implicit LogSource for the result of getClass" in {
+      val subject = new LogsWithGetClass(system)
+      subject.logSource._1 should 
===(s"LogSourceSpec$$LogsWithGetClass($system)")
+      subject.logSource._2 should ===(classOf[LogsWithGetClass])
+      subject.log.isInstanceOf[BusLogging] should ===(true)
+    }
+
+    "resolve an implicit LogSource for a class literal" in {
+      val logSource: (String, Class[?]) = LogSource(classOf[LogsWithGetClass])
+      logSource._1 should ===("LogSourceSpec$LogsWithGetClass")
+      logSource._2 should ===(classOf[LogsWithGetClass])
+    }
+
+    "resolve an implicit LogSource for a wildcard class" in {
+      val c: Class[?] = classOf[LogsWithGetClass]
+      val logSource: (String, Class[?]) = LogSource(c)
+      logSource._1 should ===("LogSourceSpec$LogsWithGetClass")
+      logSource._2 should ===(classOf[LogsWithGetClass])
+    }
+  }
+}
diff --git 
a/actor/src/main/scala-2.13/org/apache/pekko/event/LogSourceCompat.scala 
b/actor/src/main/scala-2.13/org/apache/pekko/event/LogSourceCompat.scala
new file mode 100644
index 0000000000..0d58b06dd7
--- /dev/null
+++ b/actor/src/main/scala-2.13/org/apache/pekko/event/LogSourceCompat.scala
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pekko.event
+
+import org.apache.pekko.annotation.InternalApi
+
+/**
+ * INTERNAL API
+ *
+ * Scala 2 resolves [[LogSource.fromAnyClass]] for `getClass` results, so no 
extra implicits are needed.
+ */
+@InternalApi
+private[event] trait LogSourceCompat
diff --git 
a/actor/src/main/scala-3/org/apache/pekko/event/LogSourceCompat.scala 
b/actor/src/main/scala-3/org/apache/pekko/event/LogSourceCompat.scala
new file mode 100644
index 0000000000..0fdd6d91a0
--- /dev/null
+++ b/actor/src/main/scala-3/org/apache/pekko/event/LogSourceCompat.scala
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pekko.event
+
+import org.apache.pekko.annotation.InternalApi
+
+/**
+ * INTERNAL API
+ *
+ * Lower priority implicits for [[LogSource]]. Scala 3 does not match 
`getClass`, which returns
+ * `Class[? <: T]`, against [[LogSource.fromAnyClass]]. This is not in the 
shared sources because
+ * Scala 2 reports it as ambiguous with `fromAnyClass`.
+ */
+@InternalApi
+private[event] trait LogSourceCompat {
+  implicit def fromAnySubClass[T]: LogSource[Class[? <: T]] =
+    LogSource.fromClass.asInstanceOf[LogSource[Class[? <: T]]]
+}
diff --git a/actor/src/main/scala/org/apache/pekko/event/Logging.scala 
b/actor/src/main/scala/org/apache/pekko/event/Logging.scala
index 1c4b0f86d5..5d14018dc3 100644
--- a/actor/src/main/scala/org/apache/pekko/event/Logging.scala
+++ b/actor/src/main/scala/org/apache/pekko/event/Logging.scala
@@ -324,7 +324,7 @@ class DummyClassForStringSources
  * <li>anything else gives compile error unless implicit 
[[pekko.event.LogSource]] is in scope for it</li>
  * </ul>
  */
-object LogSource {
+object LogSource extends LogSourceCompat {
   implicit val fromString: LogSource[String] = new LogSource[String] {
     def genString(s: String) = s
     override def genString(s: String, system: ActorSystem) = s + "(" + system 
+ ")"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to