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

Lifetimes seem broken #428

Closed
turion opened this issue Feb 10, 2022 · 2 comments · Fixed by #483
Closed

Lifetimes seem broken #428

turion opened this issue Feb 10, 2022 · 2 comments · Fixed by #483
Labels

Comments

@turion
Copy link
Contributor

turion commented Feb 10, 2022

Prompted by #425 (comment) I tried to add tests for lifetimes, but I couldn't do it because I got a compile error:

    Checking rustler_test v0.1.0 (/home/turion/Nextcloud/e/informatisch/rust/rustler/rustler_tests/native/rustler_test)
error[E0261]: use of undeclared lifetime name `'a`
   --> rustler_tests/native/rustler_test/src/test_codegen.rs:145:10
    |
145 | #[derive(NifStruct)]
    |          -^^^^^^^^
    |          |
    |          undeclared lifetime
    |          lifetime `'a` is missing in item created through this procedural macro
    |
    = note: this error originates in the derive macro `NifStruct` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0261`.

Whole code:

diff --git rustler_tests/lib/rustler_test.ex rustler_tests/lib/rustler_test.ex
index ec351e2..57e87d7 100644
--- rustler_tests/lib/rustler_test.ex
+++ rustler_tests/lib/rustler_test.ex
@@ -71,6 +71,7 @@ defmodule RustlerTest do
   def tuplestruct_echo(_), do: err()
   def newtype_record_echo(_), do: err()
   def tuplestruct_record_echo(_), do: err()
+  def string_slice_lifetime_echo(), do: err()
   def reserved_keywords_type_echo(_), do: err()
 
   def dirty_io(), do: err()
diff --git rustler_tests/native/rustler_test/src/lib.rs rustler_tests/native/rustler_test/src/lib.rs
index 402637f..808a5ac 100644
--- rustler_tests/native/rustler_test/src/lib.rs
+++ rustler_tests/native/rustler_test/src/lib.rs
@@ -67,6 +67,7 @@ rustler::init!(
         test_codegen::tuplestruct_echo,
         test_codegen::newtype_record_echo,
         test_codegen::tuplestruct_record_echo,
+        test_codegen::string_slice_lifetime,
         test_dirty::dirty_cpu,
         test_dirty::dirty_io,
         test_range::sum_range,
diff --git rustler_tests/native/rustler_test/src/test_codegen.rs rustler_tests/native/rustler_test/src/test_codegen.rs
index 748934e..b0dda3a 100644
--- rustler_tests/native/rustler_test/src/test_codegen.rs
+++ rustler_tests/native/rustler_test/src/test_codegen.rs
@@ -142,6 +142,17 @@ pub fn tuplestruct_record_echo(tuplestruct: TupleStructRecord) -> TupleStructRec
     tuplestruct
 }
 
+#[derive(NifStruct)]
+#[module = "StringSliceLifetime"]
+struct StringSliceLifetime<'a> {
+    message: &'a str,
+}
+
+#[rustler::nif]
+pub fn string_slice_lifetime() -> StringSliceLifetime<'static> {
+    StringSliceLifetime { message: "hi" }
+}
+
 pub mod reserved_keywords {
     use rustler::{NifMap, NifRecord, NifStruct, NifTuple, NifUntaggedEnum};
 
diff --git rustler_tests/test/codegen_test.exs rustler_tests/test/codegen_test.exs
index 2fe5684..855594c 100644
--- rustler_tests/test/codegen_test.exs
+++ rustler_tests/test/codegen_test.exs
@@ -21,6 +21,10 @@ defmodule TupleStructRecord do
   defrecord :tuplestruct, a: 1, b: 2, c: 3
 end
 
+defmodule StringSliceLifetime do
+  defstruct :message
+end
+
 defmodule RustlerTest.CodegenTest do
   use ExUnit.Case, async: true
 
@@ -231,6 +235,11 @@ defmodule RustlerTest.CodegenTest do
                  end
   end
 
+  test "string_slice_lifetime" do
+    value = %StringSliceLifetime{message: "hello"}
+    assert value == string_slice_lifetime_echo()
+  end
+
   test "reserved keywords" do
     assert %{override: 1} == RustlerTest.reserved_keywords_type_echo(%{override: 1})
@evnu evnu added the bug label Feb 10, 2022
@evnu
Copy link
Member

evnu commented Feb 10, 2022

The lifetime is not declared for rustler::Encoder, see the generated code:

    impl<'b> ::rustler::Encoder for Bla<'a> {
        fn encode<'a>(&self, env: ::rustler::Env<'a>) -> ::rustler::Term<'a> {
            use RUSTLER_ATOMS_Bla::*;
            let mut map = ::rustler::types::map::map_new(env);
            map = map
                .map_put(atom_my_str().encode(env), self.my_str.encode(env))
                .unwrap();
            map
        }
    }

(created with cargo expand --lib).

Interestingly, the example works for Decoder, because of the overlapping lifetime names (we use 'a in the generated code for Decoder). So, there are multiple issues here:

  1. We do not declare the lifetimes in generated code
  2. The lifetime 'a overlaps with a lifetime 'a for the Decoder

@turion turion mentioned this issue Feb 10, 2022
@turion
Copy link
Contributor Author

turion commented Feb 10, 2022

The lifetime 'a overlaps with a lifetime 'a for the Decoder

I think this might be intentional, but I'm not sure yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants