Giter Site home page Giter Site logo

Comments (6)

Lonami avatar Lonami commented on June 8, 2024 1

Thanks a lot for taking the time to look into this. I've created a new project from a Compose template, and after configuring the Rust plugins and uniffi and setting up the NDK version, setup the code necessary to trigger the issue.

I've published the failing code at https://github.com/Lonami/VerifyError-Repro.

Please let me know if you need any more details to import or run the project, or if I can help in any other way. After importing the project, assuming both the NDK and uniffi are configured and installed in the system correctly, it should be possible to open MainActivity.kt in Android Studio and select the Split or Design view (to the right) to trigger the VerifyError during the @Preview of DefaultPreview:

image

(The squiggly line under Instant.now() is Call requires API level 26 (current min is 21): java.time.Instant#now, which can be safely ignored for this demo.)

The code generated by uniffi-bindgen is placed at app/build/generated/source/uniffi/debug/java/uniffi/verifyerror:

image

The code generation is done by app/build.gradle (at the bottom of the file, android.applicationVariants.all { ...) and invokes the following command:

commandLine 'uniffi-bindgen', 'generate', '../native/src/verifyerror.udl', '--language', 'kotlin', '--no-format', '--out-dir', "${buildDir}/generated/source/uniffi/${variant.name}/java"

from uniffi-rs.

Lonami avatar Lonami commented on June 8, 2024

If I comment out all offending FfiConverter until the preview stops complaining (and replace their uses in method definitions with a TODO()), the @Preview starts working again. I don't think the implementation itself (read, allocationSize and write) have any part on this. It might be the way the sub-classing is defined (as in FfiConverterTypeTextFormat : FfiConverterRustBuffer<TextFormat>). But I really have no idea why it could possibly fail with VerifyError… Maybe it's the way the interface is defined?

interface FfiConverterRustBuffer<KotlinType> : FfiConverter<KotlinType, RustBuffer.ByValue>

But this really seems like a bug in the compiler, perhaps being unable these generics.

What is most strange to me is that the application runs fine when not inside a @Preview.

from uniffi-rs.

badboy avatar badboy commented on June 8, 2024

It's definitely not easily reproducable in just plain Kotlin.
Could you put a full failing example into a repository so I can run and test it? Might be easier than me trying to piece together the parts to get it to build. I'm happy to take a look then.

from uniffi-rs.

badboy avatar badboy commented on June 8, 2024

I spent a bit of time on it this morning. I am able to reproduce it using the provided code.
I'm fairly sure now this is some miscompilation in whatever does the preview rendering.
I don't think the uniffi code is inherently wrong. But I also don't know where the buggy behavior is hiding.

Unfortunately I can't spent much more time on this right now.

from uniffi-rs.

Lonami avatar Lonami commented on June 8, 2024

Thanks, yeah, it's probably safe to close this issue as the bug is unlikely to be uniffi's fault (technically, I'm sure the code could be generated in a different way to not trigger this problem, but that's a workaround and not the right solution).

from uniffi-rs.

Lonami avatar Lonami commented on June 8, 2024

The repository I mentioned earlier was deleted but here's the main contents of the files:

MainActivity.kt

package com.example.verifyerror

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.verifyerror.ui.theme.VerifyErrorReproTheme
import uniffi.verifyerror.Message
import java.time.Instant

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            VerifyErrorReproTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Greeting("Android")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    val msg = remember {
        Message(
            id = 1,
            sender = "Alice",
            text = "Testing",
            date = Instant.now(),
            editDate = null,
            formatting = listOf(),
        )
    }

    Text(text = msg.text)
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.VerifyErrorRepro"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.VerifyErrorRepro">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

build.gradle

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id "org.mozilla.rust-android-gradle.rust-android"
}

android {
    namespace 'com.example.verifyerror'
    compileSdk 32

    defaultConfig {
        applicationId "com.example.verifyerror"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion '1.1.1'
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }
    ndkVersion '25.1.8937393'
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
    implementation "androidx.compose.ui:ui:$compose_ui_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
    implementation 'androidx.compose.material:material:1.1.1'
    implementation "net.java.dev.jna:jna:5.12.0@aar"
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
}

cargo {
    module = "../native"
    libname = "uniffi_verifyerror"
    targets = ["arm64"]
    profile = 'release'
}

tasks.whenTaskAdded { task ->
    if ((task.name == 'javaPreCompileDebug' || task.name == 'javaPreCompileRelease')) {
        task.dependsOn 'cargoBuild'
    }
}

android.applicationVariants.all { variant ->
    def t = tasks.register("generate${variant.name.capitalize()}UniFFIBindings", Exec) {
        workingDir "${project.projectDir}"
        commandLine 'uniffi-bindgen', 'generate', '../native/src/verifyerror.udl', '--language', 'kotlin', '--no-format', '--out-dir', "${buildDir}/generated/source/uniffi/${variant.name}/java"
    }
    variant.javaCompileProvider.get().dependsOn(t)
    def sourceSet = variant.sourceSets.find { it.name == variant.name }
    sourceSet.java.srcDir new File(buildDir, "generated/source/uniffi/${variant.name}/java")
}

Maybe this can be closed as stale.

from uniffi-rs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.