Comments (6)
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
:
(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
:
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.
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.
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.
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.
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.
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)
- weedle 4.0.0 breaks uniffi_udl v0.25.3 HOT 4
- What are the advantages of using an external crate for hash instead of the one from the std HOT 4
- Allow UniFFI exported types (e.g. `Object`) from EXTERNAL crates to be used in a crate's e.g. `Record` HOT 6
- Python bindings missing threading import HOT 3
- Long docstrings result in build assertion failure. HOT 3
- Python doesn't generate return type of async functions HOT 6
- Ability to share data across FFI without a copy HOT 1
- Vec capacity can unnecessarily cause Rust panics when creating a `RustBuffer`.
- Kotlin global reference table overflow HOT 2
- Equality check on records when arrays are involved in Kotlin HOT 8
- `uniffi::custom_newtype!(Newtype, u16)` gives `Lift<UniFfiTag>` is not implemented for `Newtype` HOT 11
- Example: How to run the trait function defined in rust instead the implementation in caller? HOT 2
- First callback interface produces "expected value, found struct variant `Self::Other`" error HOT 3
- Tests broken in kotlin project using uniffi HOT 7
- Call requires API level 33 (current min is 29): android.system.SystemCleaner#cleaner
- Android: `java.lang.ClassNotFoundException: Didn't find class "*UniffiRustFutureContinuationCallback"` HOT 2
- Unable to conditionally enable uniffi::constructor macro HOT 28
- Can you pass functions as arguments to uniffi? HOT 4
- Python: empty struct Record produces empty class
- anyhow on uniffi 0.26.1 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from uniffi-rs.