Skip to content

Commit 59cb9a7

Browse files
committed
Support the compilation of Scala 2.13 scala.reflect.package
1 parent c8352c5 commit 59cb9a7

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,12 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
148148
checkInferredWellFormed(tree.tpt)
149149
val sym = tree.symbol
150150
if sym.isScala2Macro && !ctx.settings.XignoreScala2Macros.value then
151-
if !sym.owner.unforcedDecls.exists(p => !p.isScala2Macro && p.name == sym.name && p.signature == sym.signature) then
151+
if !sym.owner.unforcedDecls.exists(p => !p.isScala2Macro && p.name == sym.name && p.signature == sym.signature)
152+
// Allow scala.reflect.materializeClassTag to be able to compile scala/reflect/package.scala
153+
// At this point we cannot force the symbol of scala.reflect.package$, hence we check it by name
154+
// This should be removed on Scala 3.1
155+
&& sym.showFullName != "scala.reflect.materializeClassTag"
156+
then
152157
report.error("No Scala 3 implementation found for this Scala 2 macro.", tree.sourcePos)
153158
case _ =>
154159
processMemberDef(tree)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
package scala {
3+
object Test_materializeClassTag {
4+
def apply() = {
5+
println(scala.reflect.materializeClassTag[String])
6+
}
7+
}
8+
}
9+
10+
object Test {
11+
def main(args: Array[String]): Unit = Test_materializeClassTag()
12+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala
14+
15+
import java.lang.reflect.{ AccessibleObject => jAccessibleObject }
16+
17+
package object reflect {
18+
19+
// in the new scheme of things ClassManifests are aliased to ClassTags
20+
// this is done because we want `toArray` in collections work with ClassTags
21+
// but changing it to use the ClassTag context bound without aliasing ClassManifest
22+
// will break everyone who subclasses and overrides `toArray`
23+
// luckily for us, aliasing doesn't hamper backward compatibility, so it's ideal in this situation
24+
// I wish we could do the same for Manifests and TypeTags though
25+
26+
// note, by the way, that we don't touch ClassManifest the object
27+
// because its Byte, Short and so on factory fields are incompatible with ClassTag's
28+
29+
/** A `ClassManifest[T]` is an opaque descriptor for type `T`.
30+
* It is used by the compiler to preserve information necessary
31+
* for instantiating `Arrays` in those cases where the element type
32+
* is unknown at compile time.
33+
*
34+
* The type-relation operators make an effort to present a more accurate
35+
* picture than can be realized with erased types, but they should not be
36+
* relied upon to give correct answers. In particular they are likely to
37+
* be wrong when variance is involved or when a subtype has a different
38+
* number of type arguments than a supertype.
39+
*/
40+
@deprecated("use scala.reflect.ClassTag instead", "2.10.0")
41+
@annotation.implicitNotFound(msg = "No ClassManifest available for ${T}.")
42+
type ClassManifest[T] = scala.reflect.ClassTag[T]
43+
44+
/** The object `ClassManifest` defines factory methods for manifests.
45+
* It is intended for use by the compiler and should not be used in client code.
46+
*/
47+
@deprecated("use scala.reflect.ClassTag instead", "2.10.0")
48+
val ClassManifest = ClassManifestFactory
49+
50+
def classTag[T](implicit ctag: ClassTag[T]) = ctag
51+
52+
/** Make a java reflection object accessible, if it is not already
53+
* and it is possible to do so. If a SecurityException is thrown in the
54+
* attempt, it is caught and discarded.
55+
*/
56+
def ensureAccessible[T <: jAccessibleObject](m: T): T = {
57+
if (!m.isAccessible) {
58+
try m setAccessible true
59+
catch { case _: SecurityException => } // does nothing
60+
}
61+
m
62+
}
63+
64+
// anchor for the class tag materialization macro emitted during tag materialization in Implicits.scala
65+
// implementation is hardwired into `scala.reflect.reify.Taggers`
66+
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
67+
// todo. once we have implicit macros for tag generation, we can remove this anchor
68+
private[scala] def materializeClassTag[T](): ClassTag[T] = macro ???
69+
}
70+
71+
/** An exception that indicates an error during Scala reflection */
72+
case class ScalaReflectionException(msg: String) extends Exception(msg)

0 commit comments

Comments
 (0)