Compiler behaves differently on type of crate

Viewed 60

I have the following rust module.

test.rs:

pub fn foo(xs: &[f32]) -> Vec<f32> {
    xs.iter()
        .flat_map(|x| xs.iter().map(|y| *x - y))
        .collect()
}

If I compile this module (as rlib) I got an error:

$ rustc -o test.s --crate-type rlib test.rs

error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
[...]

The same can be as well experimented by using godbolt (which does pretty much the same thing).


However, if I compile the same function within a binary crate. The compiler accepts this code.

For example, by using rust-playground.

(Note we are using the same compiler version here; that is, 1.63.0)


Question

Why compiler behaves differently in those two cases?

I suspect linker might kick in here, but I would like to have more technical confirmation.

1 Answers

It has nothing to do with crate types and everything to do with editions. Edition 2021 improved the borrow checker around closures.

In the Rust Playground, if you click the triple-dot menu to the right of the build profile and toolchain buttons, and select the 2018 edition, the error re-appears: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f8bb0c7ad9000ad9a9d4540351c74721

rustc likely defaults to the oldest edition of Rust (2015) for backwards compatibility. Godbolt does the same, since it just runs rustc. Rust Playground uses the latest edition.

Related