rust/tests/ui/dyn-compatibility/metasized.rs
Zachary S c3205f98dd Replace #[rustc_do_not_implement_via_object] with #[rustc_dyn_incompatible_trait], which makes the marked trait dyn-incompatible.
Removes the attribute from `MetaSized` and `PointeeSized`, with a special case in the trait solvers for `MetaSized`.

`dyn MetaSized` is a perfectly cromulent type, and seems to only have had #[rustc_do_not_implement_via_object] so the builtin object
candidate does not overlap with the builtin MetaSized impl that all `dyn` types get.
Resolves this with a special case by checking `is_sizedness_trait` where the trait solvers previously checked `implement_via_object`.

`dyn PointeeSized` alone is rejected for other reasons (since `dyn PointeeSized` is considered to have no principal trait because `PointeeSized`
is removed at an earlier stage of the compiler), but `(dyn PointeeSized + Send)` is valid and equivalent to `dyn Send`.

Add suggestions from code review

Update compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs and tests

Co-authored-by: lcnr <rust@lcnr.de>
2026-01-20 12:54:40 -06:00

25 lines
665 B
Rust

//@ run-pass
//! This test and `sized-*.rs` and `pointeesized.rs` test that dyn-compatibility correctly
//! handles sizedness traits, which are special in several parts of the compiler.
#![feature(sized_hierarchy)]
use std::marker::MetaSized;
trait Foo: std::fmt::Debug + MetaSized {}
impl<T: std::fmt::Debug + MetaSized> Foo for T {}
fn unsize_sized<T: 'static>(x: Box<T>) -> Box<dyn MetaSized> {
x
}
fn unsize_subtrait(x: Box<dyn Foo>) -> Box<dyn MetaSized> {
x
}
fn main() {
let _bx = unsize_sized(Box::new(vec![1, 2, 3]));
let bx: Box<dyn Foo> = Box::new(vec![1, 2, 3]);
let _ = format!("{bx:?}");
let _bx = unsize_subtrait(bx);
}