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

Panic on codegen "Parse HIR" phase when defining private type #2170

Closed
pixelshot91 opened this issue Jun 30, 2024 · 7 comments · Fixed by #2180
Closed

Panic on codegen "Parse HIR" phase when defining private type #2170

pixelshot91 opened this issue Jun 30, 2024 · 7 comments · Fixed by #2180
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc bug Something isn't working

Comments

@pixelshot91
Copy link
Contributor

pixelshot91 commented Jun 30, 2024

Describe the bug

The codegen panics when I execute the steps described below.
What I find surprising is that:

  1. Neither the struct nor the 2 traits are pub.
  2. The file common.rs is not imported by pub mod but by mod
  3. The file rust/src/api/simple.rs is unchanged from the default greet function, and does not references in any way my struct or my traits

frb_codegen shouldn't even see my file common.rs , no ?

Tentatives

  1. If I add
#[frb(ignore)]

to every item in common.rs, codegen still fails

  1. If I add #[frb(ignore)] above mod common; codegen succeed, but Rust compilation fails with
error[E0658]: non-inline modules in proc macro input are unstable

Working versions

  1. If I remove this line, codegen succeed
impl MyTrait2 for MyStruct {}
  1. If I add this comment in rust/src/lib.rs, codegen succeed
/// flutter_rust_bridge:ignore
mod common;

Any help is appreciated, I thanks again for your work 👍

Steps to reproduce

From the repo created by flutter_rust_bridge_codegen create, I add a file rust/src/common.rs

trait MyTrait {
    fn request(&self);
}

trait MyTrait2 {}

struct MyStruct {
    client: Box<dyn MyTrait>,
}

impl MyTrait2 for MyStruct {}

and add this file to the crate:

pub mod api;
mod frb_generated;

mod common;

Logs

Details

[2024-06-30T20:55:39.360Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/main.rs:24] cli=Cli { verbose: false, command: Generate(GenerateCommandArgs { watch: false, primary: GenerateCommandArgsPrimary { config_file: None, rust_input: None, dart_output: None, c_output: None, duplicated_c_output: None, rust_root: None, rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, no_dart_enums_style: false, no_add_mod_to_lib: false, llvm_path: None, llvm_compiler_opts: None, dart_root: None, no_build_runner: false, extra_headers: None, no_web: false, no_deps_check: false, default_external_library_loader_web_prefix: None, no_dart3: false, full_dep: false, local: false, enable_lifetime: false, type_64bit_int: false, stop_on_error: false, dump: None, dump_all: false } }) }
[2024-06-30T20:55:39.360Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/config/config_parser.rs:51] Found config file flutter_rust_bridge.yaml
[2024-06-30T20:55:39.360Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/mod.rs:23] config=Config { base_dir: Some(""), rust_input: Some("crate::api"), dart_output: Some("lib/src/rust"), c_output: None, duplicated_c_output: None, rust_root: Some("rust/"), rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, dart_enums_style: None, add_mod_to_lib: None, llvm_path: None, llvm_compiler_opts: None, dart_root: None, build_runner: None, extra_headers: None, web: None, deps_check: None, dart3: None, full_dep: None, local: None, default_external_library_loader_web_prefix: None, dart_type_rename: None, enable_lifetime: None, type_64bit_int: None, stop_on_error: None, dump: None, dump_all: None } meta_config=MetaConfig { watch: false }
[2024-06-30T20:55:39.360Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/config/internal_config_parser/mod.rs:33] InternalConfig.parse base_dir="/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug"
[2024-06-30T20:55:39.452Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/mod.rs:26] internal_config=InternalConfig { controller: ControllerInternalConfig { watch: false, watching_paths: ["/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src"], exclude_paths: ["/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.rs", "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.io.rs", "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.web.rs"], max_count: None }, preparer: PreparerInternalConfig { dart_root: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug", deps_check: true, needs_ffigen: false }, parser: ParserInternalConfig { hir: ParserHirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, rust_crate_dir: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust", third_party_crate_names: [] }, mir: ParserMirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, force_codec_mode_pack: Some(CodecModePack { dart2rust: Pde, rust2dart: Pde }), default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, stop_on_error: false, enable_lifetime: false, type_64bit_int: false } }, generator: GeneratorInternalConfig { api_dart: GeneratorApiDartInternalConfig { dart_enums_style: true, dart3: true, dart_decl_base_output_path: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust", dart_impl_output_path: TargetOrCommonMap { common: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.dart", io: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.io.dart", web: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.web.dart" }, dart_entrypoint_class_name: "RustLib", dart_preamble: "", dart_type_rename: {} }, wire: GeneratorWireInternalConfig { dart: GeneratorWireDartInternalConfig { has_ffigen: false, web_enabled: true, llvm_path: ["/opt/homebrew/opt/llvm", "/usr/local/opt/llvm", "/usr/lib/llvm-9", "/usr/lib/llvm-10", "/usr/lib/llvm-11", "/usr/lib/llvm-12", "/usr/lib/llvm-13", "/usr/lib/llvm-14", "/usr/lib/", "/usr/lib64/", "C:/Program Files/llvm", "C:/msys64/mingw64"], llvm_compiler_opts: "", dart_root: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug", extra_headers: "", dart_impl_output_path: TargetOrCommonMap { common: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.dart", io: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.io.dart", web: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/lib/src/rust/frb_generated.web.dart" }, dart_output_class_name_pack: DartOutputClassNamePack { entrypoint_class_name: "RustLib", api_class_name: "RustLibApi", api_impl_class_name: "RustLibApiImpl", api_impl_platform_class_name: "RustLibApiImplPlatform", wire_class_name: "RustLibWire", wasm_module_name: "RustLibWasmModule" }, default_external_library_loader: GeneratorWireDartDefaultExternalLibraryLoaderInternalConfig { stem: "rust_lib_booky_minimal_frb_unwrap_bug", io_directory: "rust/target/release/", web_prefix: "pkg/" }, c_symbol_prefix: "frbgen_booky_minimal_frb_unwrap_bug_" }, rust: GeneratorWireRustInternalConfig { rust_crate_dir: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust", web_enabled: true, rust_output_path: TargetOrCommonMap { common: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.rs", io: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.io.rs", web: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.web.rs" }, c_symbol_prefix: "frbgen_booky_minimal_frb_unwrap_bug_", has_ffigen: false, default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, rust_preamble: "" }, c: GeneratorWireCInternalConfig { enable: false, rust_crate_dir: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust", rust_output_path: TargetOrCommonMap { common: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.rs", io: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.io.rs", web: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.web.rs" }, c_output_path: None, c_symbol_prefix: "frbgen_booky_minimal_frb_unwrap_bug_" } } }, polisher: PolisherInternalConfig { duplicated_c_output_path: [], dart_format_line_length: 80, add_mod_to_lib: true, build_runner: true, web_enabled: true, dart_root: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug", rust_crate_dir: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust", rust_output_path: TargetOrCommonMap { common: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.rs", io: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.io.rs", web: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/src/frb_generated.web.rs" }, c_output_path: None, enable_auto_upgrade: true }, dumper: DumperInternalConfig { dump_contents: [], dump_directory: "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust/target/frb_dump" } }
[2024-06-30T20:55:39.452Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/utils/dart_repository/dart_repo.rs:22] Guessing toolchain the runner is run into
[2024-06-30T20:55:39.452Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/command_runner.rs:129] execute command: bin=sh args="-c \"flutter\" \"--version\"" current_dir=None cmd="sh" "-c" "\"flutter\" \"--version\""
[2024-06-30T20:55:39.717Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/command_runner.rs:140] command="sh" "-c" "\"flutter\" \"--version\"" stdout=Flutter 3.22.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 761747bfc5 (4 weeks ago) • 2024-06-05 22:15:13 +0200
Engine • revision edd8546116
Tools • Dart 3.4.3 • DevTools 2.34.3
 stderr=
[2024-06-30T20:55:39.717Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/cargo_expand/mod.rs:26] run_cargo_expand manifest_dir= rust_crate_dir="/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust"
[2024-06-30T20:55:39.717Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/cargo_expand/real.rs:60] Running cargo expand in '"/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust"'
[2024-06-30T20:55:39.717Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/command_runner.rs:129] execute command: bin=cargo args="expand --lib --theme=none --ugly" current_dir=Some("/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust") cmd=cd "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly"
[2024-06-30T20:55:39.843Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/commands/command_runner.rs:140] command=cd "/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly" stdout=#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use flutter_rust_bridge::frb;

pub mod api {

    pub mod simple {
        #[doc = "frb_encoded(235b6672622873796e63295d)"]
        pub fn gredfdset(name: String) -> String {
            {
                let res =
                    ::alloc::fmt::format(format_args!("Hello, {0}!", name));
                res
            }
        }
        #[doc = "frb_encoded(235b66726228696e6974295d)"]
        pub fn init_app() { flutter_rust_bridge::setup_default_user_utils(); }
        trait MyTrait {
            fn request(&self);
        }
        trait MyTrait2 {}
        struct MyStruct {
            client: Box<dyn MyTrait>,
        }
        impl MyTrait2 for MyStruct {}
    }
}
mod frb_generated {
    #![allow(non_camel_case_types, unused, non_snake_case,
    clippy::needless_return, clippy::redundant_closure_call,
    clippy::redundant_closure, clippy::useless_conversion, clippy::unit_arg,
    clippy::unused_unit, clippy::double_parens, clippy::let_and_return,
    clippy::too_many_arguments, clippy::match_single_binding,
    clippy::clone_on_copy, clippy::let_unit_value, clippy::deref_addrof,
    clippy::explicit_auto_deref, clippy::borrow_deref_ref,
    clippy::needless_borrow)]
    use flutter_rust_bridge::for_generated::byteorder::{
        NativeEndian, ReadBytesExt, WriteBytesExt,
    };
    use flutter_rust_bridge::for_generated::{
        transform_result_dco, Lifetimeable, Lockable,
    };
    use flutter_rust_bridge::{Handler, IntoIntoDart};
    #[doc(hidden)]
    pub(crate) struct FrbWrapper<T>(T);
    impl<T: Clone> Clone for FrbWrapper<T> {
        fn clone(&self) -> Self { FrbWrapper(self.0.clone()) }
    }
    impl<T: PartialEq> PartialEq for FrbWrapper<T> {
        fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) }
    }
    impl<T: Eq> Eq for FrbWrapper<T> {}
    impl<T: std::hash::Hash> std::hash::Hash for FrbWrapper<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.0.hash(state)
        }
    }
    impl<T> From<T> for FrbWrapper<T> {
        fn from(t: T) -> Self { FrbWrapper(t) }
    }
    use std::collections::HashMap;
    use std::marker::PhantomData;
    use std::sync::Arc;
    pub struct MoiArc<T: ?Sized + MoiArcValue> {
        object_id: Option<ObjectId>,
        value: Option<Arc<T>>,
        _phantom: PhantomData<T>,
    }
    #[automatically_derived]
    impl<T: ::core::fmt::Debug + ?Sized + MoiArcValue> ::core::fmt::Debug for
        MoiArc<T> {
        #[inline]
        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
            ::core::fmt::Formatter::debug_struct_field3_finish(f, "MoiArc",
                "object_id", &self.object_id, "value", &self.value,
                "_phantom", &&self._phantom)
        }
    }
    impl<T: ?Sized + MoiArcValue> Drop for MoiArc<T> {
        fn drop(&mut self) {
            if let Some(object_id) = self.object_id {
                    Self::decrement_strong_count(object_id);
                }
        }
    }
    impl<T: ?Sized + MoiArcValue> AsRef<T> for MoiArc<T> {
        fn as_ref(&self) -> &T { self.value.as_ref().unwrap().as_ref() }
    }
    impl<T: ?Sized + MoiArcValue>
        ::flutter_rust_bridge::for_generated::BaseArc<T> for MoiArc<T> {
        fn new(value: T) -> Self where T: Sized {
            let mut pool = T::get_pool().write().unwrap();
            let object_id = pool.id_generator.next_id();
            let value = Arc::new(value);
            let old_value =
                pool.map.insert(object_id,
                    MoiArcPoolValue { ref_count: 1, value: value.clone() });
            if !old_value.is_none() {
                    ::core::panicking::panic("assertion failed: old_value.is_none()")
                };
            Self {
                object_id: Some(object_id),
                value: Some(value),
                _phantom: PhantomData,
            }
        }
        fn try_unwrap(mut self) -> Result<T, Self> where T: Sized {
            let pool = &mut T::get_pool().write().unwrap();
            if pool.map.get(&self.object_id.unwrap()).unwrap().ref_count == 1
                    {
                    Self::decrement_strong_count_raw(self.object_id.unwrap(),
                        pool);
                    self.object_id.take().unwrap();
                    Ok(Arc::into_inner(self.value.take().unwrap()).unwrap())
                } else { Err(self) }
        }
        fn into_inner(self) -> Option<T> where T: Sized {
            self.try_unwrap().ok()
        }
        fn into_raw(mut self) -> usize { self.object_id.take().unwrap() }
    }
    impl<T: ?Sized + MoiArcValue> Clone for MoiArc<T> {
        fn clone(&self) -> Self {
            Self::increment_strong_count(self.object_id.unwrap());
            Self {
                object_id: self.object_id,
                value: self.value.clone(),
                _phantom: PhantomData,
            }
        }
    }
    impl<T: ?Sized + MoiArcValue> MoiArc<T> {
        pub(crate) fn from_raw(raw: usize) -> Self where T: Sized {
            let map = &T::get_pool().read().unwrap().map;
            Self {
                object_id: Some(raw),
                value: Some(map.get(&raw).unwrap().value.clone()),
                _phantom: PhantomData,
            }
        }
        pub fn increment_strong_count(raw: usize) {
            let map = &mut T::get_pool().write().unwrap().map;
            map.get_mut(&raw).unwrap().ref_count += 1;
        }
        pub fn decrement_strong_count(raw: usize) {
            let mut pool = T::get_pool().write().unwrap();
            let object = Self::decrement_strong_count_raw(raw, &mut pool);
            drop(pool);
            drop(object);
        }
        fn decrement_strong_count_raw(raw: usize,
            pool: &mut MoiArcPoolInner<T>) -> Option<MoiArcPoolValue<T>> {
            let value = pool.map.get_mut(&raw).unwrap();
            value.ref_count -= 1;
            if value.ref_count == 0 { pool.map.remove(&raw) } else { None }
        }
    }
    pub trait MoiArcValue: 'static {
        fn get_pool()
        -> &'static MoiArcPool<Self>;
    }
    type ObjectId = usize;
    pub type MoiArcPool<T> = std::sync::RwLock<MoiArcPoolInner<T>>;
    pub struct MoiArcPoolInner<T: ?Sized> {
        map: HashMap<ObjectId, MoiArcPoolValue<T>>,
        id_generator: IdGenerator,
    }
    impl<T: ?Sized> Default for MoiArcPoolInner<T> {
        fn default() -> Self {
            Self { map: HashMap::new(), id_generator: Default::default() }
        }
    }
    struct IdGenerator {
        next_id: ObjectId,
    }
    impl Default for IdGenerator {
        fn default() -> Self { Self { next_id: Self::MIN_ID } }
    }
    impl IdGenerator {
        const MIN_ID: ObjectId = 1;
        const MAX_ID: ObjectId = 2147483600;
        fn next_id(&mut self) -> ObjectId {
            let ans = self.next_id;
            self.next_id =
                if self.next_id >= Self::MAX_ID {
                        Self::MIN_ID
                    } else { self.next_id + 1 };
            ans
        }
    }
    impl<T: ?Sized> MoiArcPoolInner<T> {}
    struct MoiArcPoolValue<T: ?Sized> {
        ref_count: i32,
        value: Arc<T>,
    }
    use ::flutter_rust_bridge::for_generated::decode_rust_opaque_nom;
    fn decode_rust_opaque_moi<T: MoiArcValue + Send + Sync>(ptr: usize)
        -> RustOpaqueMoi<T> {
        RustOpaqueMoi::from_arc(MoiArc::<T>::from_raw(ptr))
    }
    use ::flutter_rust_bridge::for_generated::StdArc;
    use ::flutter_rust_bridge::RustOpaqueNom;
    /// Please refer to `RustOpaque` for doc.
    pub type RustOpaqueMoi<T> =
        ::flutter_rust_bridge::for_generated::RustOpaqueBase<T, MoiArc<T>>;
    /// A wrapper to support [arbitrary Rust types](https://cjycode.com/flutter_rust_bridge/guides/types/arbitrary).
    pub type RustOpaque<T> = RustOpaqueMoi<T>;
    use ::flutter_rust_bridge::RustAutoOpaqueNom;
    /// Please refer to `RustAutoOpaque` for doc.
    pub type RustAutoOpaqueMoi<T> =
        ::flutter_rust_bridge::for_generated::RustAutoOpaqueBase<T,
        MoiArc<::flutter_rust_bridge::for_generated::RustAutoOpaqueInner<T>>>;
    /// Usually this is unneeded, and just write down arbitrary types.
    /// However, when you need arbitrary types at places that are not supported yet,
    /// use `RustOpaqueOpaque<YourArbitraryType>`.
    pub type RustAutoOpaque<T> = RustAutoOpaqueMoi<T>;
    pub trait CstDecode<T> {
        fn cst_decode(self)
        -> T;
    }
    impl<T, S> CstDecode<Option<T>> for *mut S where *mut S: CstDecode<T> {
        fn cst_decode(self) -> Option<T> {
            (!self.is_null()).then(|| self.cst_decode())
        }
    }
    pub trait SseDecode {
        fn sse_decode(deserializer:
            &mut ::flutter_rust_bridge::for_generated::SseDeserializer)
        -> Self;
    }
    pub trait SseEncode {
        fn sse_encode(self,
        serializer: &mut ::flutter_rust_bridge::for_generated::SseSerializer);
    }
    fn transform_result_sse<T, E>(raw: Result<T, E>)
        ->
            Result<::flutter_rust_bridge::for_generated::Rust2DartMessageSse,
            ::flutter_rust_bridge::for_generated::Rust2DartMessageSse> where
        T: SseEncode, E: SseEncode {
        use ::flutter_rust_bridge::for_generated::{Rust2DartAction, SseCodec};
        match raw {
            Ok(raw) =>
                Ok(SseCodec::encode(Rust2DartAction::Success,
                        |serializer| { raw.sse_encode(serializer) })),
            Err(raw) =>
                Err(SseCodec::encode(Rust2DartAction::Error,
                        |serializer| { raw.sse_encode(serializer) })),
        }
    }
    pub struct StreamSink<T,
        Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec =
        ::flutter_rust_bridge::for_generated::SseCodec> {
        base: ::flutter_rust_bridge::for_generated::StreamSinkBase<T,
        Rust2DartCodec>,
    }
    #[automatically_derived]
    impl<T: ::core::clone::Clone, Rust2DartCodec: ::core::clone::Clone +
        ::flutter_rust_bridge::for_generated::BaseCodec> ::core::clone::Clone
        for StreamSink<T, Rust2DartCodec> {
        #[inline]
        fn clone(&self) -> StreamSink<T, Rust2DartCodec> {
            StreamSink { base: ::core::clone::Clone::clone(&self.base) }
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        StreamSink<T, Rust2DartCodec> {
        pub fn deserialize(raw: String) -> Self {
            Self {
                base: ::flutter_rust_bridge::for_generated::StreamSinkBase::deserialize(raw),
            }
        }
    }
    impl<T> StreamSink<T, ::flutter_rust_bridge::for_generated::DcoCodec> {
        pub fn add<T2>(&self, value: T)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            T: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Success,
                value)
        }
        pub fn add_error<TR, T2>(&self, value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            TR: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Error,
                value)
        }
        fn add_raw<TR,
            T2>(&self,
            action: ::flutter_rust_bridge::for_generated::Rust2DartAction,
            value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            TR: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.base.add_raw(::flutter_rust_bridge::for_generated::DcoCodec::encode(action,
                    value.into_into_dart()))
        }
    }
    impl<T> StreamSink<T, ::flutter_rust_bridge::for_generated::SseCodec>
        where T: SseEncode {
        pub fn add(&self, value: T)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Success,
                value)
        }
        pub fn add_error<TR: SseEncode>(&self, value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Error,
                value)
        }
        pub fn add_raw<TR: SseEncode>(&self,
            action: ::flutter_rust_bridge::for_generated::Rust2DartAction,
            value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.base.add_raw(::flutter_rust_bridge::for_generated::SseCodec::encode(action,
                    |serializer| value.sse_encode(serializer)))
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        ::flutter_rust_bridge::IntoIntoDart<StreamSink<T, Rust2DartCodec>> for
        StreamSink<T, Rust2DartCodec> {
        fn into_into_dart(self) -> StreamSink<T, Rust2DartCodec> {
            ::core::panicking::panic("internal error: entered unreachable code")
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        ::flutter_rust_bridge::IntoDart for StreamSink<T, Rust2DartCodec> {
        fn into_dart(self) -> ::flutter_rust_bridge::for_generated::DartAbi {
            ::core::panicking::panic("internal error: entered unreachable code")
        }
    }
    pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0";
    pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 =
        -890726528;
    #[allow(missing_copy_implementations)]
    #[allow(non_camel_case_types)]
    #[allow(dead_code)]
    pub struct FLUTTER_RUST_BRIDGE_HANDLER {
        __private_field: (),
    }
    #[doc(hidden)]
    pub static FLUTTER_RUST_BRIDGE_HANDLER: FLUTTER_RUST_BRIDGE_HANDLER =
        FLUTTER_RUST_BRIDGE_HANDLER { __private_field: () };
    impl ::lazy_static::__Deref for FLUTTER_RUST_BRIDGE_HANDLER {
        type Target =
            ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool>;
        fn deref(&self)
            ->
                &::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
            #[inline(always)]
            fn __static_ref_initialize()
                ->
                    ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
                {
                    match (&FLUTTER_RUST_BRIDGE_CODEGEN_VERSION,
                            &flutter_rust_bridge::for_generated::FLUTTER_RUST_BRIDGE_RUNTIME_VERSION)
                        {
                        (left_val, right_val) => {
                            if !(*left_val == *right_val) {
                                    let kind = ::core::panicking::AssertKind::Eq;
                                    ::core::panicking::assert_failed(kind, &*left_val,
                                        &*right_val,
                                        ::core::option::Option::Some(format_args!("Please ensure flutter_rust_bridge\'s codegen ({0}) and runtime ({1}) versions are the same",
                                                FLUTTER_RUST_BRIDGE_CODEGEN_VERSION,
                                                flutter_rust_bridge::for_generated::FLUTTER_RUST_BRIDGE_RUNTIME_VERSION)));
                                }
                        }
                    };
                    ::flutter_rust_bridge::DefaultHandler::new_simple(Default::default())
                }
            }
            #[inline(always)]
            fn __stability()
                ->
                    &'static ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
                static LAZY:
                    ::lazy_static::lazy::Lazy<::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool>>
                    =
                    ::lazy_static::lazy::Lazy::INIT;
                LAZY.get(__static_ref_initialize)
            }
            __stability()
        }
    }
    impl ::lazy_static::LazyStatic for FLUTTER_RUST_BRIDGE_HANDLER {
        fn initialize(lazy: &Self) { let _ = &**lazy; }
    }
    fn wire__crate__api__simple__gredfdset_impl(ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32)
        -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::<flutter_rust_bridge::for_generated::SseCodec,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "gredfdset",
                port: None,
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    let api_name = <String>::sse_decode(&mut deserializer);
                    deserializer.end();
                    transform_result_sse::<_,
                            ()>((move ||
                                    {
                                        let output_ok =
                                            Result::<_,
                                                        ()>::Ok(crate::api::simple::gredfdset(api_name))?;
                                        Ok(output_ok)
                                    })())
                })
    }
    fn wire__crate__api__simple__init_app_impl(port_:
            flutter_rust_bridge::for_generated::MessagePort,
        ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32) {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,
            _,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "init_app",
                port: Some(port_),
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    deserializer.end();
                    move |context|
                        {
                            transform_result_sse::<_,
                                    ()>((move ||
                                            {
                                                let output_ok =
                                                    Result::<_, ()>::Ok({ crate::api::simple::init_app(); })?;
                                                Ok(output_ok)
                                            })())
                        }
                })
    }
    impl SseDecode for String {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            let mut inner = <Vec<u8>>::sse_decode(deserializer);
            return String::from_utf8(inner).unwrap();
        }
    }
    impl SseDecode for Vec<u8> {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            let mut len_ = <i32>::sse_decode(deserializer);
            let mut ans_ = ::alloc::vec::Vec::new();
            for idx_ in 0..len_ { ans_.push(<u8>::sse_decode(deserializer)); }
            return ans_;
        }
    }
    impl SseDecode for u8 {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_u8().unwrap()
        }
    }
    impl SseDecode for () {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {}
    }
    impl SseDecode for i32 {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_i32::<NativeEndian>().unwrap()
        }
    }
    impl SseDecode for bool {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_u8().unwrap() != 0
        }
    }
    fn pde_ffi_dispatcher_primary_impl(func_id: i32,
        port: flutter_rust_bridge::for_generated::MessagePort,
        ptr:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len: i32, data_len: i32) {
        match func_id {
            2 =>
                wire__crate__api__simple__init_app_impl(port, ptr,
                    rust_vec_len, data_len),
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
    fn pde_ffi_dispatcher_sync_impl(func_id: i32,
        ptr:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len: i32, data_len: i32)
        -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
        match func_id {
            1 =>
                wire__crate__api__simple__gredfdset_impl(ptr, rust_vec_len,
                    data_len),
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
    impl SseEncode for String {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            <Vec<u8>>::sse_encode(self.into_bytes(), serializer);
        }
    }
    impl SseEncode for Vec<u8> {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            <i32>::sse_encode(self.len() as _, serializer);
            for item in self { <u8>::sse_encode(item, serializer); }
        }
    }
    impl SseEncode for u8 {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_u8(self).unwrap();
        }
    }
    impl SseEncode for () {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {}
    }
    impl SseEncode for i32 {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_i32::<NativeEndian>(self).unwrap();
        }
    }
    impl SseEncode for bool {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_u8(self as _).unwrap();
        }
    }
    #[cfg(not(target_family = "wasm"))]
    #[path = "frb_generated.io.rs"]
    mod io {
        use super::*;
        use flutter_rust_bridge::for_generated::byteorder::{
            NativeEndian, ReadBytesExt, WriteBytesExt,
        };
        use flutter_rust_bridge::for_generated::{
            transform_result_dco, Lifetimeable, Lockable,
        };
        use flutter_rust_bridge::{Handler, IntoIntoDart};
        pub trait NewWithNullPtr {
            fn new_with_null_ptr()
            -> Self;
        }
        impl<T> NewWithNullPtr for *mut T {
            fn new_with_null_ptr() -> Self { std::ptr::null_mut() }
        }
        #[no_mangle]
        pub extern "C" fn frb_get_rust_content_hash() -> i32 {
            FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH
        }
        #[no_mangle]
        pub extern "C" fn frb_pde_ffi_dispatcher_primary(func_id: i32,
            port_: i64, ptr_: *mut u8, rust_vec_len_: i32, data_len_: i32) {
            pde_ffi_dispatcher_primary_impl(func_id, port_, ptr_,
                rust_vec_len_, data_len_)
        }
        #[no_mangle]
        pub extern "C" fn frb_pde_ffi_dispatcher_sync(func_id: i32,
            ptr_: *mut u8, rust_vec_len_: i32, data_len_: i32)
            -> ::flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
            pde_ffi_dispatcher_sync_impl(func_id, ptr_, rust_vec_len_,
                data_len_)
        }
        #[no_mangle]
        pub extern "C" fn dart_fn_deliver_output(call_id: i32, ptr_: *mut u8,
            rust_vec_len_: i32, data_len_: i32) {
            let message =
                unsafe {
                    ::flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                        rust_vec_len_, data_len_)
                };
            FLUTTER_RUST_BRIDGE_HANDLER.dart_fn_handle_output(call_id,
                message)
        }
    }
    #[cfg(not(target_family = "wasm"))]
    pub use io::*;
}
/// flutter_rust_bridge:ignore
mod common {
    trait MyTrait {
        fn request(&self);
    }
    trait MyTrait2 {}
    struct MyStruct {
        client: Box<dyn MyTrait>,
    }
    impl MyTrait2 for MyStruct {}
}
 stderr=    Checking rust_lib_booky_minimal_frb_unwrap_bug v0.1.0 (/home/julien/Perso/LeBonCoin/chain_automatisation/booky_minimal_frb_unwrap_bug/rust)
warning: unused import: `flutter_rust_bridge::frb`
 --> src/lib.rs:1:5
  |
1 | use flutter_rust_bridge::frb;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s


[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/hir/flat/parser/syn_item/item_struct_or_enum.rs:36] parse_syn_item_struct_or_enum item_ident=Ident { sym: MyStruct, span: bytes(588..596) }
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=dyn MyTrait ans=Delegate(DynTrait(MirTypeDelegateDynTrait { trait_def_name: NamespacedName { namespace: Namespace { joined_path: "crate::api::simple" }, name: "MyTrait" }, data: None }))
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=Box < dyn MyTrait > ans=Boxed(MirTypeBoxed { exist_in_real_api: true, inner: Delegate(DynTrait(MirTypeDelegateDynTrait { trait_def_name: NamespacedName { namespace: Namespace { joined_path: "crate::api::simple" }, name: "MyTrait" }, data: None })) })
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=MyStruct ans=StructRef(MirTypeStructRef { ident: MirStructIdent(NamespacedName { namespace: Namespace { joined_path: "crate::api::simple" }, name: "MyStruct" }), is_exception: false })
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:134] parse_function function name: "request"
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=request inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=MyTrait ans=TraitDef(MirTypeTraitDef { name: NamespacedName { namespace: Namespace { joined_path: "crate::api::simple" }, name: "MyTrait" } })
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:134] parse_function function name: "gredfdset"
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=gredfdset inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:134] parse_function function name: "init_app"
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=init_app inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
[2024-06-30T20:55:39.848Z DEBUG /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=MyStruct ans=StructRef(MirTypeStructRef { ident: MirStructIdent(NamespacedName { namespace: Namespace { joined_path: "crate::api::simple" }, name: "MyStruct" }), is_exception: false })
[2024-06-30T20:55:39.848Z ERROR /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/utils/logs.rs:55] panicked at /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/trait_object.rs:48:38:
called `Option::unwrap()` on a `None` value
thread 'main' panicked at /home/julien/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.0.0/src/library/codegen/parser/mir/parser/ty/trait_object.rs:48:38:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Expected behavior

frb_codegen should never panic.
Some restriction may apply on the type and traits that I expose to Dart, but Rust code that stay private should not have any impact on codegen

Generated binding code

No response

OS

Debian GNU/Linux 12 (bookworm)

Version of flutter_rust_bridge_codegen

v2.0.0

Flutter info

Details

```shell [✓] Flutter (Channel stable, 3.22.2, on Debian GNU/Linux 12 (bookworm) 6.1.0-18-amd64, locale en) • Flutter version 3.22.2 on channel stable at /home/julien/fvm/versions/stable • Upstream repository https://github.com/flutter/flutter.git • Framework revision 761747bfc5 (4 weeks ago), 2024-06-05 22:15:13 +0200 • Engine revision edd8546116 • Dart version 3.4.3 • DevTools version 2.34.3

[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /home/julien/Android/Sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: /home/julien/.local/share/JetBrains/Toolbox/apps/android-studio-2/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.9-11255266)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Linux toolchain - develop for Linux desktop
• Debian clang version 16.0.6 (19)
• cmake version 3.25.1
• ninja version 1.11.1
• pkg-config version 1.8.1

[✓] Android Studio (version 2023.3)
• Android Studio at /home/julien/.local/share/JetBrains/Toolbox/apps/android-studio-2
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.9-11255266)

[✓] Android Studio (version 2023.1)
• Android Studio at /home/julien/.local/share/JetBrains/Toolbox/apps/android-studio
• Flutter plugin version 78.2.1
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)

[✓] Android Studio (version 2022.3)
• Android Studio at /home/julien/android-studios/android-studio-2022.3.1.19
• Flutter plugin version 75.1.2
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] IntelliJ IDEA Community Edition (version 2019.2)
• IntelliJ at /home/julien/idea
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.87.0)
• VS Code at /usr/share/code
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (1 available)
• Linux (desktop) • linux • linux-x64 • Debian GNU/Linux 12 (bookworm) 6.1.0-18-amd64

[✓] Network resources
• All expected network resources are available.

! Doctor found issues in 2 categories.

</p>
</details> 

### Version of `clang++`

16.0.6 (19)

### Additional context

rustc 1.79.0 (129f3b996 2024-06-10)
@pixelshot91 pixelshot91 added the bug Something isn't working label Jun 30, 2024
@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 1, 2024

Firstly, yes it should never panic. (e.g. it can return a Result::Err, and later that err is ignored). Feel free to PR for this by e.g. converting a panic into a Result::Err! Alternatively, I will work on it in the next batch.

Secondly, as for why it sees it: I have not implemented full-featured module parsing logic, since the rule of "what module is visible" is not very trivial. But feel free to PR for this as well. The non-api folder is scanned because there can be definitions in non-api folders and is used in api folders, so in this phase we just parse it.

Thirdly, the current workaround, as you pointed out, is to /// flutter_rust_bridge:ignore that mod.

@fzyzcjy fzyzcjy added the awaiting Waiting for responses, PR, further discussions, upstream release, etc label Jul 1, 2024
@AlexV525
Copy link
Contributor

AlexV525 commented Jul 1, 2024

Running into the same issue, how do I determine which mod I should write?

 flutter_rust_bridge_codegen generate                                                                                                                                                               
[2024-07-01T02:23:49.548Z INFO frb_codegen\src\library\codegen\parser\mir\parser\ty\enum_or_struct.rs:73] Skip parsing enum_or_struct `NamespacedName { namespace: Namespace { joined_path: "crate::bls::bls12381::big" }, name: "BIG" }` because of error (e=Cannot parse array length

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: <unknown>
  16: <unknown>
  17: <unknown>
  18: <unknown>
  19: <unknown>
  20: <unknown>
  21: <unknown>
  22: <unknown>
  23: <unknown>
  24: <unknown>
  25: <unknown>
  26: BaseThreadInitThunk
  27: RtlUserThreadStart)
[2024-07-01T02:23:49.550Z INFO frb_codegen\src\library\codegen\parser\mir\parser\ty\enum_or_struct.rs:73] Skip parsing enum_or_struct `NamespacedName { namespace: Namespace { joined_path: "crate::bls::bls12381::dbig" }, name: "DBIG" }` because of error (e=Cannot parse array length                                                                                                                 

Stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: <unknown>
  16: <unknown>
  17: <unknown>
  18: <unknown>
  19: <unknown>
  20: <unknown>
  21: <unknown>
  22: <unknown>
  23: <unknown>
  24: <unknown>
  25: <unknown>
  26: BaseThreadInitThunk
  27: RtlUserThreadStart)
[1.2s] Parse ⢀                                                                                                                                                                                       
  └── [1.2s] Cargo expand & syn parse                                                                                                                                                                
  └── [0.0s] Parse HIR                                                                                                                                                                               
  └── [0.0s] Parse MIR ⠂                                                                                                                                                                             
[2024-07-01T02:23:49.552Z ERROR frb_codegen\src\library\utils\logs.rs:55] panicked at frb_codegen\src\library\codegen\parser\mir\parser\ty\trait_object.rs:48:38:
called `Option::unwrap()` on a `None` value
thread 'main' panicked at frb_codegen\src\library\codegen\parser\mir\parser\ty\trait_object.rs:48:38:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0:     0x7ff74f6751da - <unknown>
   1:     0x7ff74f6931cb - <unknown>
   2:     0x7ff74f66fec1 - <unknown>
   3:     0x7ff74f674f5a - <unknown>
   4:     0x7ff74f677dea - <unknown>
   5:     0x7ff74f677a58 - <unknown>
   6:     0x7ff74f57d3a7 - <unknown>
   7:     0x7ff74f678629 - <unknown>
   8:     0x7ff74f678332 - <unknown>
   9:     0x7ff74f675e99 - <unknown>
  10:     0x7ff74f678090 - <unknown>
  11:     0x7ff75005e887 - <unknown>
  12:     0x7ff75005e942 - <unknown>
  13:     0x7ff74f8251c3 - <unknown>
  14:     0x7ff74f81d42f - <unknown>
  15:     0x7ff74f82401e - <unknown>
  16:     0x7ff74f822d19 - <unknown>
  17:     0x7ff74f72cad8 - <unknown>
  18:     0x7ff74f88d9d5 - <unknown>
  19:     0x7ff74f82224f - <unknown>
  20:     0x7ff74f5c24db - <unknown>
  21:     0x7ff74f81e16a - <unknown>
  22:     0x7ff74f82401e - <unknown>
  23:     0x7ff74f7bd9b3 - <unknown>
  24:     0x7ff74f733d93 - <unknown>
  25:     0x7ff74f8aa796 - <unknown>
  26:     0x7ff74f82709d - <unknown>
  27:     0x7ff74f5ed0ca - <unknown>
  28:     0x7ff74f5f0711 - <unknown>
  29:     0x7ff74f566149 - <unknown>
  30:     0x7ff74f5eeb8c - <unknown>
  31:     0x7ff74f50c78e - <unknown>
  32:     0x7ff74f50b8c6 - <unknown>
  33:     0x7ff74f510eda - <unknown>
  34:     0x7ff74f667428 - <unknown>
  35:     0x7ff74f50cd8c - <unknown>
  36:     0x7ff750059e9c - <unknown>
  37:     0x7ffaeb3d257d - BaseThreadInitThunk
  38:     0x7ffaebe4af28 - RtlUserThreadStart

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 1, 2024

how do I determine which mod I should write?

Currently, the workaround maybe just bisect the modules (ignore half mods, see whether it works, etc)... But after it is fixed, there is no need to do so (since it will not error).

Feel free to PR for this (possibly simple change)! Alternatively I will work on it in the next batch.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 1, 2024

Given the error is related to trait_object in codegen, I would also guess it is related to code like dyn WhateverTrait.

@AlexV525
Copy link
Contributor

AlexV525 commented Jul 2, 2024

Bisected the minimal struct that can reproduce this issue:

use std::fmt;
use std::fmt::Debug;

/// Trait that logs at level INFO every update received (if any).
pub trait Progress: Send + Sync + 'static {
    /// Send a new progress update. The progress value should be in the range 0.0 - 100.0, and the message value is an
    /// optional text message that can be displayed to the user.
    fn update(&self, progress: f32, message: Option<String>);
}

pub struct ProgressHolder {
    pub progress: Box<dyn Progress>,
}
impl Debug for ProgressHolder {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ProgressHolder").finish_non_exhaustive()
    }
}

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 2, 2024

Looks like dyn TraitName causes the problem

Copy link
Contributor

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants