Skip to content

Relax T: Sized bound on try_as_dyn / try_as_dyn_mut#156104

Open
aobatact wants to merge 1 commit intorust-lang:mainfrom
aobatact:try-as-dyn-unsized
Open

Relax T: Sized bound on try_as_dyn / try_as_dyn_mut#156104
aobatact wants to merge 1 commit intorust-lang:mainfrom
aobatact:try-as-dyn-unsized

Conversation

@aobatact
Copy link
Copy Markdown

@aobatact aobatact commented May 3, 2026

trait_info_of already returns None for unsized types, so allowing T: ?Sized is sound and lets callers in generic contexts use these functions without a separate Sized bound. For unsized T, the function always returns None.

Tracking issue: #144361

Motivation

Currently, it is not possible to use try_as_dyn as "specialization-like" dispatch in
blanket impls with ?Sized type.

// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 3, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 3, 2026

r? @adwinwhite

rustbot has assigned @adwinwhite.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 22 candidates

@rustbot

This comment has been minimized.

`trait_info_of` already returns `None` for unsized types, so allowing
`T: ?Sized` is sound and lets callers in generic contexts use these
functions without a separate `Sized` bound. For unsized `T`, the
function always returns `None`.
@aobatact aobatact force-pushed the try-as-dyn-unsized branch from 7acc268 to ecf527f Compare May 3, 2026 14:00
@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented May 4, 2026

cc @oli-obk

Copy link
Copy Markdown
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors r+ rollup

Makes sense

View changes since this review

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 4, 2026

📌 Commit ecf527f has been approved by oli-obk

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 4, 2026
@oli-obk oli-obk assigned oli-obk and unassigned adwinwhite May 4, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request May 4, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
rust-bors Bot pushed a commit that referenced this pull request May 4, 2026
Rollup of 6 pull requests

Successful merges:

 - #155543 (docs(unstable-book): Document const generics features)
 - #156043 (c-variadic: gate `va_arg` on `c_variadic_experimental_arch`)
 - #156082 (Move tests associated types)
 - #156092 (Clean up `TyCtxt::needs_crate_hash` usage and rename it to `needs_hir_hash`.)
 - #156104 (Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`)
 - #156128 (.mailmap: prefer matching just based on commit emails)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 4, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 4, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
rust-bors Bot pushed a commit that referenced this pull request May 4, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #155848 ([doc]: Revert `core::io::ErrorKind` doc changes)
 - #155855 (Remove unnecessary `get_unchecked`)
 - #156062 (Added command-line argument support for `wasm32-wali-linux-musl`)
 - #155543 (docs(unstable-book): Document const generics features)
 - #156043 (c-variadic: gate `va_arg` on `c_variadic_experimental_arch`)
 - #156082 (Move tests associated types)
 - #156092 (Clean up `TyCtxt::needs_crate_hash` usage and rename it to `needs_hir_hash`.)
 - #156104 (Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`)
 - #156128 (.mailmap: prefer matching just based on commit emails)
 - #156135 (Remove most uses of def_id_to_node_id)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 4, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
rust-bors Bot pushed a commit that referenced this pull request May 4, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #155848 ([doc]: Revert `core::io::ErrorKind` doc changes)
 - #155855 (Remove unnecessary `get_unchecked`)
 - #155543 (docs(unstable-book): Document const generics features)
 - #155962 (`rustc`: `target_features`: allow for `cfg`-only stable `target_features`)
 - #156043 (c-variadic: gate `va_arg` on `c_variadic_experimental_arch`)
 - #156082 (Move tests associated types)
 - #156092 (Clean up `TyCtxt::needs_crate_hash` usage and rename it to `needs_hir_hash`.)
 - #156104 (Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`)
 - #156128 (.mailmap: prefer matching just based on commit emails)
 - #156135 (Remove most uses of def_id_to_node_id)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 4, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
rust-bors Bot pushed a commit that referenced this pull request May 4, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #155848 ([doc]: Revert `core::io::ErrorKind` doc changes)
 - #155855 (Remove unnecessary `get_unchecked`)
 - #155543 (docs(unstable-book): Document const generics features)
 - #155962 (`rustc`: `target_features`: allow for `cfg`-only stable `target_features`)
 - #156043 (c-variadic: gate `va_arg` on `c_variadic_experimental_arch`)
 - #156082 (Move tests associated types)
 - #156092 (Clean up `TyCtxt::needs_crate_hash` usage and rename it to `needs_hir_hash`.)
 - #156103 (Fix E0040 suggestion for explicit `Drop::drop` UFCS calls)
 - #156104 (Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`)
 - #156128 (.mailmap: prefer matching just based on commit emails)
 - #156135 (Remove most uses of def_id_to_node_id)
 - #156152 (Update books)
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request May 5, 2026
…-obk

Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`

`trait_info_of` already returns `None` for unsized types, so allowing `T: ?Sized` is sound and lets callers in generic contexts use these functions without a separate `Sized` bound. For unsized `T`, the function always returns `None`.

Tracking issue: rust-lang#144361

## Motivation

Currently, it is not possible to use `try_as_dyn` as "specialization-like" dispatch in
blanket impls with `?Sized` type.

```rust
// Cannot add ?Sized now.
impl<T: 'static /* + ?Sized */, S: Serializer + 'static> Serialize<S> for T {
    fn serialize(&self, serializer: &mut S) -> Result<S::Ok, S::Error> {
        if let Some(spec) = try_as_dyn::<_, dyn SpecializedSer<S>>(self) {
            spec.specialized_serialize(serializer)
        } else {
            // fall back to compile-time reflection via TypeId
            ...
        }
    }
}
```
rust-bors Bot pushed a commit that referenced this pull request May 5, 2026
Rollup of 16 pull requests

Successful merges:

 - #155848 ([doc]: Revert `core::io::ErrorKind` doc changes)
 - #155855 (Remove unnecessary `get_unchecked`)
 - #155543 (docs(unstable-book): Document const generics features)
 - #155962 (`rustc`: `target_features`: allow for `cfg`-only stable `target_features`)
 - #156043 (c-variadic: gate `va_arg` on `c_variadic_experimental_arch`)
 - #156082 (Move tests associated types)
 - #156087 (Improve `&pin` reference-pattern suggestions)
 - #156092 (Clean up `TyCtxt::needs_crate_hash` usage and rename it to `needs_hir_hash`.)
 - #156103 (Fix E0040 suggestion for explicit `Drop::drop` UFCS calls)
 - #156104 (Relax `T: Sized` bound on `try_as_dyn` / `try_as_dyn_mut`)
 - #156122 (Add a `doc_cfg` regression test to ensure foreign types impls are working as expected)
 - #156128 (.mailmap: prefer matching just based on commit emails)
 - #156135 (Remove most uses of def_id_to_node_id)
 - #156152 (Update books)
 - #156154 (tests: mark import UI tests as check-pass)
 - #156162 (Update `browser-ui-test` version to `0.23.5`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants