Skip to content

undocumented lifetime elision fix from 1.15 -> 1.16 ? #41105

Closed

Description

Specifically, this line of code failed to compile on 1.15.1, but successfully compiles on 1.16: https://github.com/m4b/goblin/blob/8188a8a15017cbdadfdbb807e08db968f1c634c9/src/mach/exports.rs#L94

For context, here is the important snippet:

impl<'a> ExportInfo<'a> {
    /// Parse out the export info from `bytes`, at `offset`
    pub fn parse(bytes: &'a [u8], libs: &[&'a str], flags: Flag, mut offset: usize) -> error::Result<ExportInfo<'a>> {
        use self::ExportInfo::*;
        let regular = |offset| -> error::Result<ExportInfo> {
            let address = bytes.pread::<Uleb128>(offset)?;
            Ok(Regular {
                address: address.into(),
                flags:   flags
            })
        };
        let reexport = |mut offset| -> error::Result<ExportInfo> {
            let lib_ordinal: u64 = {
                let tmp = bytes.pread::<Uleb128>(offset)?;
                offset += tmp.size();
                tmp.into()
            };
             // THIS line has lifetime issues on 1.15
            let lib_symbol_name = bytes.pread::<&str>(offset)?;
            let lib = libs[lib_ordinal as usize];
            let lib_symbol_name = if lib_symbol_name == "" { None } else { Some (lib_symbol_name)};
            Ok(Reexport {
                lib: lib,
                lib_symbol_name: lib_symbol_name,
                flags: flags
            })
        };

So, the fix (for 1.15) is adding explicit lifetime annotation to the closure return (e.g., let reexport = |mut offset| -> error::Result<ExportInfo<'a>>{..})

Consequently, it seems that this is an undocumented lifetime elision fix, or substantially less likely, 1.16 incorrectly compiles invalid lifetime code in closures.

I suspect its the former.

So, I dunno why, maybe I'm being an alarmist, but I find this somewhat serious, and fairly annoying; the only reason I upgraded to 1.16 was that I wanted cargo check for development, but upstream projects using my crate use 1.15 for CI, recommended version, etc; consequently, when 1.16 was released I noted that there were no major compiler fixes in this cycle, or major issues in compatibility notes, etc., which would cause a difference between a client compiling on 1.15 versus 1.16, so it should be safe to develop on 1.16 stable for cargo check; but alas, this is not the case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.T-coreRelevant to the core team, which will review and decide on the PR/issue.Relevant to the core team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions