Open Rua opened 1 month ago
This is expected, dropping a reference doesn't drop the underline value, therefore calling drop
on it is misleading.
If you want to ignore the reference, to make inaccessible or avoid an unused lint, I suggest following the lint suggestion, and replace the drop(mutref);
by let _ = mutref;
. It has the same effect as it renders the but doesn't imply that the underline value is dropped.mutref
binding inaccessible
@rustbot labels -needs-triage -C-bug +C-discussion +A-lint
Yes, my intent was to drop the reference, for soundness reasons in unsafe code. Is binding it to _
guaranteed to drop it?
The reason the lint exist is to notify users that the drop
call does nothing, while the user might have though that it did something, otherwise there wouldn't be drop
call.
This is particularly relevant when the reference is not as obvious, but is hidden behind several lines of codes.
A prime example where it matters is when using a Mutex
and calling drop(ref_mutexguard)
instead of drop(mutexguard)
where this can lead to bug because the mutex can live longer than expected.
Yes, my intent was to drop the reference, for soundness reasons in unsafe code. Is binding it to
_
guaranteed to drop it?
Dropping a reference does nothing. A reference doesn't have a Drop
impl.
let _ = <expr>;
is guaranteed to drop immediately, but as I said, dropping a reference does nothing, but it still renders the previous binding inaccessible (for non-Copy types), if that is your intent.
let _ = <expr>;
does not move/copy out of <expr>
, so if it is a place expression (e.g. a variable) it will not be dropped, and will still be accessible later even if it does not implement Copy
.
fn main() {
let mut x = 42;
let y = &mut x;
// drop(y); // doesn't compile
let _ = y; // compiles
*y = 37;
}
One thing that does move/copy out of place expressions is a "trivial" expression-statement like <expr>;
, e.g, this doesn't compile
fn main() {
let mut x = 42;
let y = &mut x;
y;
*y = 37;
}
You can also use an inline block to force a move, e.g. this doesn't compile
fn main() {
let mut x = 42;
let y = &mut x;
let _ = { y }; // or just `{ y };`
*y = 37;
}
to make inaccessible or avoid an unused lint, I suggest following the lint suggestion, and replace the
drop(mutref);
bylet _ = mutref;
. I has the same effect as it renders themutref
binding inaccessible but doesn't imply that the underline value is dropped.
This is incorrect. let _ = variable;
has no effect other than silencing the unused variable lint. It does not make variable
inaccessible.
Yeah, sorry about that, the lint confused me between let _ = mutref;
and let _a = mutref;
.
The last one which does move the value (at least for non-Copy types, which &mut <type>
is).
Is there a way to make the variable inaccessible and not trigger this lint?
Is there a way to make the variable inaccessible and not trigger this lint?
For mutable reference there is let _a = mutref;
, let _ = { mutref };
or mutref;
just to name a few.
For immutable reference, I'm not sure, since they are Copy
-able.
For mutable reference there is
let _a = mutref;
Doesn't really work, it's still accessible through _a
.
let _ = { mutref };
ormutref;
Interesting. Maybe the lint should mention these as alternatives to make the variable inaccessible?
let _ = { mutref };
ormutref;
Interesting. Maybe the lint should mention these as alternatives to make the variable inaccessible?
I don't know. That's not really the goal of the lint, most of the time when calling drop
users want to drop the underline value, not making it inaccessible; and if the goal was to silence the unused variable lint, using let _ = ...;
is still valid.
I'm worried suggesting either one will only make the suggestion more awkward for users, in particular new users, which may not understand the implication of those (subtle) syntax differences.
I'll try to make the error message more useful.
@rustbot claim
When I call
std::mem::drop
on a mutable reference, this is supposed to consume the reference and make it unavailable to following code. And indeed it does, because any following uses trigger a "use of moved value" error.But when I do this, I get a warning from the compiler:
Meta
rustc --version --verbose
: