Deref should not fail. What about Lazy?

In std::ops::Deref I read:

[…], this trait should never fail. Failure during dereferencing can be extremely confusing when Deref is invoked implicitly.

In once_cell::sync::Lazy::force, I read:

Forces the evaluation of this lazy value and returns a reference to the result. This is equivalent to the Deref impl, but is explicit.

Does that mean that the closure passed to once_cell::sync::Lazy::new should never fail either? And what does fail mean in this context? Should it never panic?

1 Like

The initialization function of once_cell's Lazy type could fail and I don't think it would be confusing in that case. IMO this usage of Deref is fine and unconfusing.

1 Like

One important property that justifies Lazy-like types to impl Deref is that its failure is idempotent. Once it succeeded, it never fail for subsequent deref. Once it failed, it keep failing. Since dereference operations can implicitly be inserted by the compiler it should not fail or succeed randomly.

1 Like

I'm tempted to send a PR to change the documentation to say things in terms of concrete concepts of the language instead:

Deref::deref() should never fail: it should not panic, nor try to communicate failure by any other means such as returning a placeholder value. Failure during dereferencing can be extremely confusing when Deref is invoked implicitly.

This still disagrees with what Lazy does, but it's much less vague and matches what I assume is the intent of the previous text. How's it sound?


That's definitely better. I think the docs should also be a little clearer about what the problems with a failing Deref impl are, but that might be a bigger change.

1 Like

So I take that I can panic if I need to.

Maybe the "confusing" thing which the docs warn about isn't reporting an error. I believe that Deref::deref should be stable as long as Self isn't explicitly modified in some way. I.e. deref's return value and panic-behavior should not change unexpectedly (e.g. due to an I/O error) but may change after explicitly changing the contents of a Box, for example.

Like I said above, maybe the key point is some sort of "stability" rather than reporting error states? But not sure.