core: Rewrite docs for try_as_dyn - #162312
Open
jnkel wants to merge 1 commit into
Open
Conversation
Collaborator
|
r? @JohnTitor rustbot has assigned @JohnTitor. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
jnkel
force-pushed
the
try_as_dyn-docs
branch
from
September 5, 2026 06:23
5c087ba to
8626105
Compare
jnkel
force-pushed
the
try_as_dyn-docs
branch
from
September 5, 2026 06:24
8626105 to
793a9ea
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Update the documentation for
try_as_dynto resolve confusion some people had about the feature, provide better examples, and promise less.In particular, this PR updates the documentation to never promise success, allowing for spurious failures for even "simple" cases. This reflects the general consensus in https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/try_as_dyn.20potential.20problematic.20implications/near/621331808, since the precise rules of the implementation can be quite subtle and difficult to explain to users. Instead, document the function as being best-effort and able to produce false negatives, with non-exhaustive examples of situations where it produces false negatives in practice. We can always make the guarantees stricter in the future.
Also replaces the "animal-cat-dog" style example with more realistic use cases of
try_as_dynfor performance and debugging.cc @oli-obk
Rendered
Returns
Some(&U)ifTcan be coerced to the dyn trait typeU. Otherwise, it returnsNone.Examples of false negatives
Some examples of situations where
try_as_dyn::<T, dyn Trait>returnsNonein practice evenwhen
TimplementsTrait:T's impl forTraitis lifetime-dependentT's impl forTraitis a builtin impl (e.g.dyn DebugimplementsDebug)T's impl forTraithas a trait bound which requires transitively reasoning aboutlifetime-dependent or builtin impls
This list is not exhaustive. There is some detailed documentation about these limitations at
https://doc.rust-lang.org/unstable-book/library-features/try-as-dyn.html But the gist is
summarized below:
Lifetime-dependent impls
try_as_dyndoes not have access to lifetime information, thus it cannot differentiate between'staticand other lifetimes and cannot reason about outlives bounds on impls. Thus it cannotreason about impls that have
'staticlifetimes or outlives bounds of any kind. ///The following impls are lifetime-dependent and produce false negatives when used with
try_as_dyn:Impls that mention a generic parameter more than once are lifetime-depndent and produce false
negatives, even if they don't expressly mention any lifetimes:
The following impl is lifetime-independent, because even though it mentions lifetimes,
implementation of the trait is not conditional over the lifetimes:
Impls without generic parameters at all are also lifetime-independent, as long as they contain
no
'staticlifetimes.Builtin impls
Builtin impls (like
impl Debug for dyn Debug, or automatic implementations ofSendandSync) have various obscure rules and often are not fully generic. To simplify reasoning aboutwhat is allowed and what not, all builtin impls are rejected and will neither directly nor
indirectly contribute to a
Someresult.Compile-time failures
Determining whether
Tcan be coerced to the dyn trait typeUrequires compiler trait resolution.In some cases, that resolution can exceed the recursion limit,
and compilation will fail instead of this function returning
None.The input type
Tmust outlive the lifetime'aon thedyn Trait + 'a.This is basically the same rule that forbids
let x: &dyn Trait + 'static = &&some_local_variable;So if you see borrow check errors around
try_as_dyn, think about whether a normal unsizingcoercion would be possible at all if you were using concrete types or had bounds on the input type.
Examples
Using
try_as_dynto use bytewise comparison instead of PartialEq for certain types, similar tothe standard library's optimization for slices:
Using
try_as_dynfor debugging: