Skip to content

Missing bounds check for transparent inline type parameters #10552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nicolasstucki opened this issue Nov 30, 2020 · 10 comments · Fixed by #12334
Closed

Missing bounds check for transparent inline type parameters #10552

nicolasstucki opened this issue Nov 30, 2020 · 10 comments · Fixed by #12334

Comments

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Nov 30, 2020

Minimized code

transparent inline def foo[T]: Int = 10
def bar[T]: Int = 10

def test =
  foo[List]
  bar[List]

Output

7 |  bar[List]
  |      ^^^^
  |      Missing type parameter for List

Expectation

The error should also be emitted for foo[List]

@odersky
Copy link
Contributor

odersky commented Dec 2, 2020

Maybe. Not easy to do though, as these type parameters are lost at the time we are allowed to check kinds (can't check early because of risk of cyclic references). So we might also accept this and close.

@nicolasstucki
Copy link
Contributor Author

Maybe when we inline it we can keep a dummy type Dummy$ = List in the inlined code if T is never referenced which will then fail the check in a later phase.

@odersky
Copy link
Contributor

odersky commented Dec 26, 2020

I'll close this for now. Revisit if someone wants to work on this.

@nicolasstucki
Copy link
Contributor Author

Another instance of this bug

transparent inline def foo[A <: Int]: Int = valueOf[A]
@main def run = println(foo["hi"])

It should fail but compiles.

@nicolasstucki nicolasstucki changed the title Missing kind check in inline definitions Missing bounds check for transparent inline type parameters May 4, 2021
@smarter
Copy link
Member

smarter commented May 4, 2021

Aren't these applications still available in Inlined#call when we do bounds checking?

@nicolasstucki
Copy link
Contributor Author

Indeed, the call is still there after typer

class Foo:
  transparent inline def foo[A <: Int]: Int = valueOf[A]
  def run = println(foo["hi"])
PackageDef(Ident(<empty>), List(
  TypeDef(Foo, 
    Template(DefDef(<init>, List(List()), TypeTree(), Thicket(List())), List(
      Apply(Select(New(TypeTree()), <init>), List())
    ), ValDef(_, Thicket(List()), Thicket(List())), List(
      DefDef(foo, List(List(
        TypeDef(A, TypeBoundsTree(TypeTree(), Ident(Int), Thicket(List())))
      )), Ident(Int), TypeApply(Ident(valueOf), List(Ident(A))))
    ,
      DefDef(run, List(), TypeTree(), 
        Apply(Ident(println), List(
          Inlined(
+           TypeApply(Select(This(Ident(Foo)), foo), List(
+              SingletonTypeTree(Literal("hi"))
+            ))
          , List(), TypeApply(Ident(valueOf), List(TypeTree())))
        ))
      )
    ))
  )
))

We could check them in post type before removing the call.

@nicolasstucki
Copy link
Contributor Author

Actually, this should be done in the Inliner just before/after inlining. Otherwise, we could end up losing the inlined tree due o an outer inline method dropping it.

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 5, 2021
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 5, 2021
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 5, 2021
@smarter
Copy link
Member

smarter commented May 5, 2021

Otherwise, we could end up losing the inlined tree due o an outer inline method dropping it.

If an inlined tree is dropped I assume that's because it's dead code? If so I don't think it's a big deal if we don't check bounds in it since it doesn't affect soundness.

@nicolasstucki
Copy link
Contributor Author

It is not necessarily dead code. It might be code that a macro used as part of partial evaluation. Hence it was live code during compilation.

@smarter
Copy link
Member

smarter commented May 5, 2021

I see thanks, can we come up with a test case demonstrating this for #12334 ?

nicolasstucki added a commit to dotty-staging/izumi-reflect that referenced this issue May 5, 2021
The tests do not compile due to a type bounds check

See scala/scala3#10552
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 5, 2021
nicolasstucki added a commit to dotty-staging/dotty that referenced this issue May 6, 2021
@Kordyjan Kordyjan added this to the 3.0.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants