Skip to content

Instantly share code, notes, and snippets.

@peter-kehl
Last active April 30, 2024 07:36
Show Gist options
  • Save peter-kehl/315225a4ad86c6ec2a069a19be89676b to your computer and use it in GitHub Desktop.
Save peter-kehl/315225a4ad86c6ec2a069a19be89676b to your computer and use it in GitHub Desktop.
Rust lambdas returning a reference, stored in a function pointer
fn _f() {
use alloc::string::String;
let lambda: fn(&str) -> &str = |x| x;
let lambda = |x| -> &str { x };
// No:
#[cfg(unused)]
let lambda = |x: &str| x;
#[cfg(unused)]
let lambda = |x: &str| -> &str { x };
struct S {
s: alloc::string::String,
i: usize,
}
// No:
#[cfg(unused)]
let lambda = |s| -> &str { s.s };
#[cfg(unused)]
let s = S {
s: "abc".to_string(),
i: 1,
};
#[cfg(unused)]
lambda(&s);
let get: fn(&S) -> &alloc::string::String = |s: &S| &s.s;
let get: fn(&S) -> &alloc::string::String = |s| &s.s;
let get: fn(&_) -> &alloc::string::String = |s: &S| &s.s;
let get: fn(&S) -> &_ = |s| &s.s; // OK
#[cfg(unused)]
let get: fn(&S) -> _ = |s| &s.s; // NOT ok
#[cfg(unused)]
let get: fn(&S) -> _ = |s| -> &String { &s.s }; // NOT ok
let get: fn(&S) -> &_ = |s| -> &String { &s.s }; // OK
let get: fn(&S) -> Result<&_, ()> = |s| Ok(&s.s); // OK
#[cfg(unused)]
let get: fn(&S) -> Result<&_, _> = |s| Ok(&s.s); // NOT ok
#[cfg(unused)]
let get: fn(&S) -> _ = |s| Ok(&s.s); // NOT ok
impl S {
fn f(&self) {
let get: fn(&Self) -> &String = |s: &S| &s.s;
let get: fn(&Self) -> &String = |s| &s.s;
// Macro-friendly: if inferred, then we don't have to specify the return type - not even on the right side:
let get: for<'a> fn(&'a Self) -> &'a _ = |s| &s.s;
let get: for<'a> fn(&'a Self) -> &'a _ = |s| &s.s[..];
let get: for<'a> fn(&'a Self) -> &'a _ = |s| -> &String { &s.s };
let get: for<'a> fn(&'a Self) -> &'a _ = |s| -> &str { &s.s[..] };
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment