Skip to content

try_as_dyn does not work with builtin impls #162134

Open

Description

@Janrupf

Lifting this from a discussion on Zulip.

core::any::try_as_dyn doesn't work (always returns None) when trying to access builtin impls in any way:

trait SyncAble {}
impl<T> SyncAble for T where T: Sync /* <- builtin */ {}

println!("{}", core::any::try_as_dyn::<u32, dyn SyncAble>(&0).is_some());

Thats quite annoying because checking whether T: Sync holds would potentially allow for optimizations (offloading computations). The same applies to all other builtin impl's. This can be quite confusing, especially because its not consistent for a single trait either.

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 1, 2026
  2. maxdexh commented on Sep 1, 2026

    @maxdexh
    Member

    Note that the SyncAble impl isn't builtin, but the impl Sync for u32 is. Builtin impls get ignored, even if you obscure them through a blanket impl like here. This is consistent with Copy since the Copy impl is not builtin.

    simpler example to show this:

    let _: &dyn Send = try_as_dyn(&1).unwrap(); // doesn't work
  3. added
    F-try_as_dyn`#![feature(try_as_dyn)]`
    C-bugCategory: This is a bug.
    A-dyn-traitArea: trait objects, vtable layout
    T-langRelevant to the language team
    on Sep 1, 2026
  4. BoxyUwU commented on Sep 2, 2026

    @BoxyUwU
    Member
  5. theemathas commented on Sep 2, 2026

    @theemathas
    Contributor

    The reason try_as_dyn doesn't work with builtin impls was: I discovered that the builtin impl that makes dyn Trait implement Trait can be lifetime-dependent (#150161 (comment)). Oli decided to fix this by blanket-banning all builtin impls.

    This ban is probably broader than it needs to be, but it's not clear if there's a more principled fix, other than maybe allowing individual builtin impls one by one.

    Could you explain what you think is inconsistent with the current treatment of builtin impls?

  6. added
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    and removed
    T-langRelevant to the language team
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 2, 2026
  7. Janrupf commented on Sep 2, 2026

    @Janrupf
    Author

    Its not inconsistent regarding builtin impls in general. But its inconsistent for a certain traits: Sometimes a Copy is not builtin, sometimes it is for example. This requires the user to understand when something is possibly a builtin impl. My expectation would be that it at least always works for a certain trait or doesn't.

    I believe the correct fix would be to not ignore builtin impls in general, but ignore the non-'static ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dyn-traitArea: trait objects, vtable layoutC-bugCategory: This is a bug.F-try_as_dyn`#![feature(try_as_dyn)]`T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions