'temporary value dropped while borrowed' on value that is not borrowed

⚓ Rust    📅 2026-03-10    👤 surdeus    👁️ 1      

surdeus

I'm getting the error temporary value dropped while borrowed from this code

use std::hint::black_box;

// The error only occurs if the type in `Wrapper` is 'complex' (`<&() as Trait>::Type` rather than `&()`)
pub trait Trait {
	type Type;
}
impl Trait for &() {
	type Type = Self;
}

// The error only occurs if `Wrapper` uses a lifetime
struct Wrapper<'a>(<&'a () as Trait>::Type);

fn foo<T>(_: T, _: &T) {}

fn main() {
	let data = Wrapper(&());

	// The error only occurs if the temporary is the result of an expression (not a literal)
	foo(Wrapper(&black_box(())), &data);

	data;
}

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:17:15
   |
17 |     foo(Wrapper(&black_box(())), &data);
   |                  ^^^^^^^^^^^^^         - temporary value is freed at the end of this statement
   |                  |
   |                  creates a temporary value which is freed while still in use
18 |
19 |     data;
   |     ---- borrow later used here
   |
help: consider using a `let` binding to create a longer lived value
   |
17 ~     let binding = black_box(());
18 ~  foo(Wrapper(&binding), &data);

The error seems to imply that data is borrowing from the temporary value passed to foo, but I don't see why.

Is there any way to tell the compiler that data doesn't borrow from the other argument of foo? I've noticed that if I make foo not generic, and give each parameter a different lifetime, the error goes away, so maybe it's just beause the parameters share the same lifetime. If that's the case, is there any way for a function to take two of the same type, just with different lifetimes?

I know I could just follow the suggestion in the error message, but this is in the public API for a library I'm writing, and it would be nicer if users had the option of writing their inputs inline, e.g.

create_bind_group(
	Material {
		base_colour_texture: Some(&texture.create_view()),
		normal_map: Some(&normal_map.create_view()),
		..Material::default()
	},
	Layout::<Material>::new()
);

vs

let texture_view = texture.create_view();
let normal_map_view = normal_map.create_view();
create_bind_group(
	Material {
		base_colour_texture: Some(&texture_view),
		normal_map: Some(&normal_map_view),
		..Material::default()
	},
	Layout::<Material>::new()
);

3 posts - 2 participants

Read full topic

🏷️ Rust_feed