Skip to content
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

[BUG] Resolution error with proofs plugin when using certain types from other packages. #950

Open
Sintrastes opened this issue Dec 5, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@Sintrastes
Copy link

Describe the bug
When using @Given annotations with the arrow proofs compiler plugin, and using an @Given context that references certain classes in a different package from where the @Given annotations are being used, sometimes the generated code will have unresolved reference errors.

To Reproduce

Compile a project with the following two files:

// test.kt

package test
import arrow.Context
import test.mod.Functor

@Context
@Retention(AnnotationRetention.RUNTIME)
@Target(
  AnnotationTarget.CLASS,
  AnnotationTarget.FUNCTION,
  AnnotationTarget.PROPERTY,
  AnnotationTarget.VALUE_PARAMETER
)


@MustBeDocumented
annotation class Given
inline fun <A> given(@Given identity: A): A = identity

interface Hk<F,A>

object ForListK

data class ListK<A>(val list: List<A>): Hk<ForListK, A>

fun <A> Hk<ForListK, A>.fix() = this as ListK<A>

fun <A> List<A>.k() = ListK(this)

@Given
internal val listFunctor = object: Functor<ForListK> {
  override fun <A, B> Hk<ForListK, A>.fmap(f: (A) -> B): Hk<ForListK, B> {
    return ListK(fix().list.map(f))
  }
}

fun <F> fmapPlusTwo(xs: Hk<F,Int>, @Given functor: Functor<F>): Hk<F,Int> = with(functor) {
    xs.fmap { it + 2 }
}

fun main() {
  val res = fmapPlusTwo(listOf(1,2,3).k())
  println("$res")
}
// mod/functor.kt
import test.Hk

interface Functor<F> {
  fun <A, B> Hk<F, A>.fmap(f: (A) -> B): Hk<F, B>
}

After compiling a project with these two files, the generated code for the fmapPlusTwo method looks like this:

package test
@arrow.CompileTime
internal fun <F>   fmapPlusTwo(xs: Hk<F, Int>, @test.Given functor: Functor<F> = TODO("Compile time replaced"), unit: Unit = Unit): Hk<F, Int> = 
  fmapPlusTwo(xs, functor) 

with an unresolved reference error for Functor.

Expected behavior
The above examples should compile successfully.

Environment (please complete the following information):

Additional context
It's not entirely clear to me yet exactly when this issue occurs. This didn't seem to be an issue for another example where the type I imported from a different module was just a simple (i.e. not generic) type -- so perhaps the issue arises with generics.

I believe this issue could be solved by making sure to always use fully qualified names for all generated code.

@Sintrastes Sintrastes added the bug Something isn't working label Dec 5, 2021
@Sintrastes
Copy link
Author

@raulraja I'd be happy to look at this one if you have some suggestion for where I might look.

@Sintrastes
Copy link
Author

@raulraja Thanks for the suggestion.

Unfortunately, it looks like this is not as easy of a fix as I thought. This may still be part of the problem, but it actually looks like when the plugin tries to look up given instances for a generic class that is not defined in the current package, it can't actually find those instances.

I have a fork here where I've added a test to try and catch this issue -- and there I am actually getting this error before the unresolved reference error I was getting before:

error found: /tmp/Kotlin-Compilation14835146631616204679/sources/Test.kt: (29, 27): 
    There is no Proof for this type [ERROR : Semigroup] to resolve this call. Either define 
      a corresponding GivenProof or provide an evidence explicitly at this call-site.

@Sintrastes
Copy link
Author

Although, for what it's worth, whenever I try to use it.type.getJetTypeFqName(true) instead of it.type -- it looks like all of the given tests fail with a pretty hefty BackendException that I don't understand in the slightest.

@raulraja
Copy link
Member

raulraja commented Dec 9, 2021

That second error [ERROR : Semigroup] indicates an error type and probably just means that Semigroup was not resolved so maybe also missing the import or fqname for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants