Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Add an API for getting an erased type #209

Closed
mbore opened this issue May 18, 2021 · 8 comments
Closed

Add an API for getting an erased type #209

mbore opened this issue May 18, 2021 · 8 comments

Comments

@mbore
Copy link

mbore commented May 18, 2021

In Scala 2, there is a method TypeApi#erasure, which is very useful in derivation pre-checks (e.g. https://github.com/softwaremill/tapir/blob/master/core/src/main/scala/sttp/tapir/internal/OneOfMappingMacro.scala). We would love to have a similar method in dotty (e.g. defined for TypeRepr or Type[_]), in order to let the users known, that the derivation may not be possible in a certain case.

Workaround

As far as I understand, the currently available substitute for

  val t = implicitly[c.WeakTypeTag[O]].tpe.dealias
   t =:= t.erasure

is

     TypeRepr.of[T] match {
       case _: AppliedType | _: AndOrType => false
       case _ => true
     }
@smarter
Copy link
Member

smarter commented May 18, 2021

   case _: AppliedType | _: AndOrType => false
   case _ => true

That seems to exclude too much and not enough things at the same time. For example, Array[Int] will be represented as an AppliedType but its erasure is still an Array[Int], and x.type is not an AppliedType or an AndOrType, but its erasure will be whatever the erasure of its underlying type is.

Incidentally, arrays are also why we can't directly expose our internal type erasure method: internally we represent arrays after erasure as a JavaArrayType, this type isn't exposed in tasty-reflect and that's a good thing since it would add a lot of complexity and source of issues (since that type should not appear in trees pre-erasure), so if we did expose an erasure operation in tasty-reflect we'd have to make sure to replace all occurences of JavaArrayType by an AppliedType.


I don't know what your usecase is exactly, but could you emit from your macro a call to isInstanceOf[T] ? That way the compiler itself will warn if type erasure means the check will be imprecise.

@smarter
Copy link
Member

smarter commented May 18, 2021

ah I found your usecase in https://github.com/softwaremill/tapir/blob/scala3/core/src/main/scala-3/sttp/tapir/macros/TapirMacros.scala:

inline def oneOfMapping[T: ClassTag](statusCode: StatusCode, output: EndpointOutput[T]): OneOfMapping[T] = 
  tapirMacros.oneOfMappingImpl[T]('statusCode, 'output, '{classTag[T]}) }

which calls

'{ sttp.tapir.oneOfMappingClassMatcher($statusCode, $output, $ct.runtimeClass) }

which calls

    OneOfMapping(Some(statusCode), output, { (a: Any) => runtimeClass.isInstance(a) })

so it seems to me that you could drop the macro and just rely on the power of inline:

inline def oneOfMapping[T](statusCode: StatusCode, output: EndpointOutput[T]): OneOfMapping[T] =
  OneOfMapping(Some(statusCode), output, (a: Any) => a.isInstanceOf[T])

and let the compiler warn the user if the type test cannot be checked at runtime.

/cc @adamw

@smarter
Copy link
Member

smarter commented May 31, 2021

To summarize the discussion, adding this API would be non-trivial and it seems that the usecase suggested for it would be better served by judicious use of inline, so I will be closing this issue, please reopen if I missed something.

@smarter smarter closed this as completed May 31, 2021
@adamw
Copy link

adamw commented May 31, 2021

We ended up using the heuristics:

     TypeRepr.of[T] match {
       case _: AppliedType | _: AndOrType => false
       case _ => true
     }

so that we could issue a compiler error. As these are quite typical warnings (e.g. in pattern matches), they might be easily overseen.

@smarter
Copy link
Member

smarter commented May 31, 2021

As these are quite typical warnings (e.g. in pattern matches), they might be easily overseen.

That's bad since all unchecked warnings are equally problematic, they should either be silenced with @unchecked or fixed, but never left as is.

@smarter
Copy link
Member

smarter commented May 31, 2021

(I also mentioned above how that heuristic is incorrect)

@smarter
Copy link
Member

smarter commented May 31, 2021

Also, I'd be happy with making unchecked warnings errors by default, but I suspect that would require some discussions first.

@adamw
Copy link

adamw commented May 31, 2021

That's true, but practice often diverges from the preferred state :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants