scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

When I declare a type for implicit, implicitly[ClassTag[T]] ==null #12905

Closed laglangyue closed 7 months ago

laglangyue commented 7 months ago

Reproduction steps

Scala version: 2.13

import scala.reflect.ClassTag

case class File(id: String)

class Parent[T <: AnyRef: ClassTag] {

  private implicit val manifest: Manifest[T] = {
    val classTag = implicitly[ClassTag[T]]
    if (classTag == null) {
      Manifest.classType[T](classOf[AnyRef])
    } else {
      Manifest.classType[T](classTag.runtimeClass)
    }
  }

  def hello(): Array[T] = {
    println(manifest)
    Array.empty
  }
}

class Sun extends Parent[File] {

  def test(): Array[File] = {
    hello()
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    new Sun().test()
  }
}

Problem

Using "private implicit val manifest = {}," implicitly[ClassTag[T]] = File

File

Using "private implicit val manifest: Manifest[T] = {}," implicitly[ClassTag[T]] = null, unable to obtain type File.

java.lang.Object
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [LFile; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [LFile; is in unnamed module of loader 'app')
    at Sun.test(Test.scala:27)
    at Main$.main(Test.scala:33)
    at Main.main(Test.scala)
laglangyue commented 7 months ago

When I use implicit type declaration.

import scala.reflect.ClassTag

case class File(id: String)

class Parent[T <: AnyRef: ClassTag] {

  private implicit val manifest: Manifest[T] = {
    val classTag = implicitly[ClassTag[T]]
    if (classTag == null) {
      Manifest.classType[T](classOf[AnyRef])
    } else {
      Manifest.classType[T](classTag.runtimeClass)
    }
  }

  def hello(): Array[T] = {
    println(manifest)
    Array.empty
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    println(new Parent[String].hello())
  }
}

then get

java.lang.Object
[Ljava.lang.Object;@1fbc7afb

and using val manifest: Manifest[T] = {} adn will get

java.lang.Object
[Ljava.lang.Object;@1fbc7afb
som-snytt commented 7 months ago

-Xlint says

t12905.scala:9: warning: Implicit resolves to enclosing value manifest
    val classTag = implicitly[ClassTag[T]]
                             ^
1 warning
SethTisue commented 7 months ago

also asked at https://stackoverflow.com/questions/77478732/scala-2-13-fix-type-annotation-required-for-implicit-definition-and-cant-get , and on Discord too

@laglangyue it's inconsiderate to ask the same question in lots of places on the Internet without including crosslinks. someone could waste their time helping you in one place, even though you already got helped in another

laglangyue commented 7 months ago

year,sorry,get it.I has found how to resolve it,and forgot to close the issue in the other place.

发自我的iPhone

------------------ Original ------------------ From: Seth Tisue @.> Date: Wed,Nov 15,2023 2:19 AM To: scala/bug @.> Cc: Laglangyue @.>, Mention @.> Subject: Re: [scala/bug] When I declare a type for implicit,implicitly[ClassTag[T]] ==null (Issue #12905)

also asked at https://stackoverflow.com/questions/77478732/scala-2-13-fix-type-annotation-required-for-implicit-definition-and-cant-get , and on Discord too

@laglangyue it's inconsiderate to ask the same question in lots of places on the Internet without including crosslinks. someone could waste their time helping you in one place, even though you already got helped in another

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

laglangyue commented 7 months ago

for implicit val manifest: Manifest[T] manifest is Manifest[Object], because of Type Erasure for implicit val manifest=,due to type inference, I will search for the true type from ClassTag, so I closed this issue.