#Alternatives to https://github.com/softprops/recap ? Or other solutions to `non_local_definitions`?

1 messages · Page 1 of 1 (latest)

robust laurel
#

I'm using recap https://github.com/softprops/recap to parse some regex-s to structs. In nightly, I am now getting a warning for non_local_definitions (see next message):

#[derive(Debug, Deserialize, Recap, Clone)]
#[recap(regex = r#"^(?P<from>[A-Za-z]+) to (?P<to>[A-Za-z]+) = (?P<distance>\d+)$"#)]
struct Route {
    from:     Location,
    to:       Location,
    distance: i32,
}

Basically, the macro is generating the code that the nightly compiler doesn't fully like.

I tried adding #[allow(non_local_definitions)] to the struct, but it didn't remove the warning as it is generated in the macro.

I think my options are:

  • Move from nightly to stable - but that just postpones the problem, and I'm using other nightly features
  • Submit a ticket to recap, but it seems rather abandoned and this is a nightly problem so probably won't be addressed
  • Fork recap and fix the issue in my fork, contribute back PR
  • Move away from recap to something hand-crafted for parsing regexs to structs
  • Move away to some alternative to recap which doesn't have this issue
  • Do something else - not sure what - to just swallow the non_local_definitions warnings... but that only postpones the problem.

Suggestions?

GitHub

deserialize typed structures from regex captures. Contribute to softprops/recap development by creating an account on GitHub.

#
  --> y2015\src\bin\solution_2015_09.rs:10:30
   |
10 | #[derive(Debug, Deserialize, Recap, Clone)]
   |                              ^----
   |                              |
   |                              move the `impl` block outside of this constant `RECAP_IMPL_FOR_Route`
11 | #[recap(regex = r#"^(?P<from>[A-Za-z]+) to (?P<to>[A-Za-z]+) = (?P<distance>\d+)$"#)]
12 | struct Route {
   |        ----- `Route` is not local
   |
   = note: the derive macro `Recap` defines the non-local `impl`, and may need to be changed
   = note: the derive macro `Recap` may come from an old version of the `recap_derive` crate, try updating your dependency with `cargo update -p recap_derive`
   = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
   = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint
   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
   = note: this warning originates in the derive macro `Recap` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
serene oar
#

You should submit a ticket to recap. I believe it should be easy to fix: the only problem is that they’re using lazy_static instead of the standard library’s LazyLock

#

and you can #[allow(non_local_definitions)] for now

#

to hide the warning

#

Aahh no nevermind, I see the issue

#

it is still very easy: ```diff
-let injector = Ident::new(

  • &format!("RECAP_IMPL_FOR_{}", item.ident.to_string()),
  • Span::call_site(),
    -);

let out = quote! {

  • const #injector: () = {
  • const _: () = {
    extern crate recap;
    #impl_inner
    #impl_matcher
    };
    };
#

they should probably switch to LazyLock as well

robust laurel
#

Thanks, @serene oar . The fix works. I opened a PR.