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

MSRV #443

Closed
Dirbaio opened this issue Apr 1, 2021 · 5 comments · Fixed by #447
Closed

MSRV #443

Dirbaio opened this issue Apr 1, 2021 · 5 comments · Fixed by #447
Labels
type: question A question that isn't answered by the docs

Comments

@Dirbaio
Copy link
Contributor

Dirbaio commented Apr 1, 2021

What's defmt's MSRV (Minimum Supported Rust Version)?

I've found defmt uses the following features that restrict the MSRV:

matches! macro: 1.42+
u64::MAX const: 1.43+
function-like proc macros in expression context: 1.45+

However with 1.45 it won't build, I'm not sure why. code here

error[E0425]: cannot find value `dhcp_repr` in this scope
   --> src/macros.rs:10:50
    |
10  |     (trace, $($arg:expr),*) => { defmt::trace!($($arg),*); };
    |                                                  ^^^^ not found in this scope
    | 
   ::: src/dhcp/clientv4.rs:343:17
    |
343 |                 net_trace!("DHCP send renew to {}: {:?}", endpoint, dhcp_repr);
    |                 --------------------------------------------------------------- in this macro invocation

1.46 works fine.

I thought I'd ask first, so if 1.45 is unsupported I can skip debugging it...

@Urhengulas
Copy link
Member

Let me investigate. Anyways we should document our MSRV :)

@Urhengulas Urhengulas added the type: question A question that isn't answered by the docs label Apr 1, 2021
@Urhengulas
Copy link
Member

Hi @Dirbaio,

I can observe the same behavior with this minimal example on rust 1.45.0:

macro_rules! net_log {
    (trace, $($arg:expr),*) => { defmt::trace!($($arg),*); };
    (debug, $($arg:expr),*) => { defmt::debug!($($arg),*); };
}

fn main() {
    let endpoint = 1;
    let dhcp_repr = 2;

    defmt::trace!("DHCP send renew to {}: {:?}", endpoint, dhcp_repr); // works
    net_log!(trace, "DHCP send renew to {}: {:?}", endpoint, dhcp_repr); // fails
}

But there is a funny thing: Although net_log! pretty much directly translates to defmt::trace! and also expands to the same code (see below), net_log! fails on 1.45.0, but defmt::trace! does not 🤔

Therefore I assume this is actually an issue in how macro_rules! net_log is written, but I am not proficient enough in macro magic in order to tell you why 😬


expanded code

(Generated using cargo-expand)

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
fn main() {
    let endpoint = 1;
    let dhcp_repr = 2;

    // defmt_trace!
    {
        if true && false || !true && false {
            match (&(endpoint), &(dhcp_repr)) {
                (arg0, arg1) => {
                    if let Some(mut _fmt_) = defmt::export::acquire() {
                        _fmt_ . header (& defmt :: export :: istr ({ # [link_section = ".defmt.{\"package\":\"local\",\"tag\":\"defmt_trace\",\"data\":\"DHCP send renew to {}: {:?}\",\"disambiguator\":\"6227765310601133464\"}"] # [export_name = "{\"package\":\"local\",\"tag\":\"defmt_trace\",\"data\":\"DHCP send renew to {}: {:?}\",\"disambiguator\":\"6227765310601133464\"}"] static DEFMT_LOG_STATEMENT : u8 = 0 ; & DEFMT_LOG_STATEMENT as * const u8 as usize })) ;
                        _fmt_.fmt(arg0, false);
                        _fmt_.fmt(arg1, false);
                        _fmt_.finalize();
                        defmt::export::release(_fmt_)
                    }
                }
            }
        }
    };

    // net_log!
    {
        if true && false || !true && false {
            match (&(endpoint), &(dhcp_repr)) {
                (arg0, arg1) => {
                    if let Some(mut _fmt_) = defmt::export::acquire() {
                        _fmt_ . header (& defmt :: export :: istr ({ # [link_section = ".defmt.{\"package\":\"local\",\"tag\":\"defmt_trace\",\"data\":\"DHCP send renew to {}: {:?}\",\"disambiguator\":\"12094526559404328479\"}"] # [export_name = "{\"package\":\"local\",\"tag\":\"defmt_trace\",\"data\":\"DHCP send renew to {}: {:?}\",\"disambiguator\":\"12094526559404328479\"}"] static DEFMT_LOG_STATEMENT : u8 = 0 ; & DEFMT_LOG_STATEMENT as * const u8 as usize })) ;
                        _fmt_.fmt(arg0, false);
                        _fmt_.fmt(arg1, false);
                        _fmt_.finalize();
                        defmt::export::release(_fmt_)
                    }
                }
            }
        }
    };
}

@japaric
Copy link
Member

japaric commented Apr 9, 2021

I don't think we want to add a restrictive MSRV like "1.40+" because then bumping the MSRV requires a semver bump and each time we semver bump defmt we effectively split the ecosystem.

The Embedded WG dropped their fixed MSRV and moved to 'compiles on latest stable'. We effectively have the same policy (though not documented; it's enforced by CI) and I would keep that way.

@Urhengulas
Copy link
Member

@Dirbaio: Is your question resolved by the answer from @japaric?

@Dirbaio
Copy link
Contributor Author

Dirbaio commented Apr 11, 2021

Yes, though it'd be nice to have it documented somewhere, like in the readme :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question A question that isn't answered by the docs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants