Skip to content

Commit

Permalink
Unrolled build for rust-lang#136522
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#136522 - compiler-errors:dyn_compatible_for_dispatch, r=oli-obk

Remove `feature(dyn_compatible_for_dispatch)` from the compiler

This PR proposes the removal of `feature(dyn_compatible_for_dispatch)` from the compiler.

* As far as I can tell from the tracking issue, there's very little demand for this feature. I think that if this feature becomes useful in the future, then a fresh implementation from a fresh set of eyes, with renewed understanding of how this feature fits into the picture of Rust as it exists **today** would be great to have; however, in the absence of this demand, I don't see a particularly good reason to keep this implementation around.

* The RFC didn't receive very much discussion outside of the lang team, and while the discussion it received seemed to suggest that this feature was aiming to simplify the language and improve expressibility, I don't think this feature has really demonstrated either of those goals in practice. Furthermore, nobody seems to have owned this feature for quite some time or express desire to push for its stabilization.

* Relatedly, I find some of the RFC discussion like "when we make things impossible it's often presumptuous"[^1] and "I tend to want to take a 'we are all adults here' attitude toward unsafe code"[^2] to be particularly uncompelling. Of course this is no criticism to the authors of those comments since they're pretty old comments now, but type soundness is (IMO) the primary goal of the types team. This feature doesn't really do much other than further complicating the story of where we must validate object safety for soundness, along making dyn-incompatible trait object types *almost* seem useful, but very much remain UB to create and misleading to users who don't know better.

* Dyn compatibility's story has gotten more complicated since the feature was proposed in 2017, and now it needs to interact with things like associated consts, GATs, RPITITs, trait upcasting, `dyn*`, etc. While some of this is exercised in the codebase today, I'm not confident all of the corners of this feature have been hammered out. Reducing the "surface area" for what can go wrong in the compiler, especially around a side of the language (`dyn Trait`) that has been known to be particularly unsound in the past, seems good enough motivation to get rid of this for now.

[^1]: rust-lang/rfcs#2027 (comment)
[^2]: rust-lang/rfcs#2027 (comment)

cc `@rust-lang/types` `@rust-lang/lang`

Tracking:

- rust-lang#43561

r? types
  • Loading branch information
rust-timer authored Feb 25, 2025
2 parents 7d8c6e7 + f3d31f7 commit 27d0df5
Show file tree
Hide file tree
Showing 58 changed files with 511 additions and 886 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ declare_features! (
Some("renamed to `doc_notable_trait`")),
/// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
(removed, dropck_parametricity, "1.38.0", Some(28498), None),
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
///
/// Renamed from `object_safe_for_dispatch`.
///
/// [^1]: Formerly known as "object safe".
(removed, dyn_compatible_for_dispatch, "1.83.0", Some(43561),
Some("removed, not used heavily and represented additional complexity in dyn compatibility")),
/// Uses generic effect parameters for ~const bounds
(removed, effects, "1.84.0", Some(102090),
Some("removed, redundant with `#![feature(const_trait_impl)]`")),
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,6 @@ declare_features! (
(unstable, doc_notable_trait, "1.52.0", Some(45040)),
/// Allows using the `may_dangle` attribute (RFC 1327).
(unstable, dropck_eyepatch, "1.10.0", Some(34761)),
/// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1].
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
///
/// Renamed from `object_safe_for_dispatch`.
///
/// [^1]: Formerly known as "object safe".
(unstable, dyn_compatible_for_dispatch, "1.83.0", Some(43561)),
/// Allows using the `#[fundamental]` attribute.
(unstable, fundamental, "1.0.0", Some(29635)),
/// Allows using `#[link_name="llvm.*"]`.
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_analysis/src/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,7 @@ fn check_object_overlap<'tcx>(

for component_def_id in component_def_ids {
if !tcx.is_dyn_compatible(component_def_id) {
// Without the 'dyn_compatible_for_dispatch' feature this is an error
// which will be reported by wfcheck. Ignore it here.
// This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
// With the feature enabled, the trait is not implemented automatically,
// so this is valid.
// This is a WF error tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`.
} else {
let mut supertrait_def_ids = elaborate::supertrait_def_ids(tcx, component_def_id);
if supertrait_def_ids
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,10 @@ fn receiver_for_self_ty<'tcx>(
/// a pointer.
///
/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in
/// a new check that `Trait` is dyn-compatible, creating a cycle (until dyn_compatible_for_dispatch
/// is stabilized, see tracking issue <https://github.com/rust-lang/rust/issues/43561>).
/// Instead, we fudge a little by introducing a new type parameter `U` such that
/// a new check that `Trait` is dyn-compatible, creating a cycle.
/// Instead, we emulate a placeholder by introducing a new type parameter `U` such that
/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`.
///
/// Written as a chalk-style query:
/// ```ignore (not-rust)
/// forall (U: Trait + ?Sized) {
Expand Down Expand Up @@ -572,8 +572,6 @@ fn receiver_is_dispatchable<'tcx>(

// the type `U` in the query
// use a bogus type parameter to mimic a forall(U) query using u32::MAX for now.
// FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can
// replace this with `dyn Trait`
let unsized_self_ty: Ty<'tcx> =
Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,13 +859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

if let Some(principal) = data.principal() {
if !self.infcx.tcx.features().dyn_compatible_for_dispatch() {
principal.with_self_ty(self.tcx(), self_ty)
} else if self.tcx().is_dyn_compatible(principal.def_id()) {
principal.with_self_ty(self.tcx(), self_ty)
} else {
return;
}
principal.with_self_ty(self.tcx(), self_ty)
} else {
// Only auto trait bounds exist.
return;
Expand Down
21 changes: 8 additions & 13 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,19 +904,14 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
// FIXME(#27579) RFC also considers adding trait
// obligations that don't refer to Self and
// checking those

let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch();

if !defer_to_coercion {
if let Some(principal) = data.principal_def_id() {
self.out.push(traits::Obligation::with_depth(
tcx,
self.cause(ObligationCauseCode::WellFormed(None)),
self.recursion_depth,
self.param_env,
ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
));
}
if let Some(principal) = data.principal_def_id() {
self.out.push(traits::Obligation::with_depth(
tcx,
self.cause(ObligationCauseCode::WellFormed(None)),
self.recursion_depth,
self.param_env,
ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
));
}
}

Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3827,7 +3827,6 @@ ui/suggestions/issue-103646.rs
ui/suggestions/issue-104086-suggest-let.rs
ui/suggestions/issue-104287.rs
ui/suggestions/issue-104327.rs
ui/suggestions/issue-104328.rs
ui/suggestions/issue-104961.rs
ui/suggestions/issue-105226.rs
ui/suggestions/issue-105494.rs
Expand Down
18 changes: 0 additions & 18 deletions tests/ui/coherence/coherence-unsafe-trait-object-impl.rs

This file was deleted.

22 changes: 0 additions & 22 deletions tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr

This file was deleted.

4 changes: 1 addition & 3 deletions tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//@ check-pass

// Regression test for #128176. Previously we would call `type_of` on the `1` anon const
// before the anon const had been lowered and had the `type_of` fed with a result.

#![feature(generic_const_exprs)]
#![feature(dyn_compatible_for_dispatch)]
#![allow(incomplete_features)]

trait X {
Expand All @@ -13,6 +10,7 @@ trait X {

const _: () = {
fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
//~^ ERROR the trait `X` is not dyn compatible
};

fn main() {}
19 changes: 19 additions & 0 deletions tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0038]: the trait `X` is not dyn compatible
--> $DIR/cg-in-dyn-issue-128176.rs:12:24
|
LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^ `X` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/cg-in-dyn-issue-128176.rs:8:10
|
LL | trait X {
| - this trait is not dyn compatible...
LL | type Y<const N: i16>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0038`.

This file was deleted.

6 changes: 1 addition & 5 deletions tests/ui/dyn-compatibility/associated-consts.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
// Check that we correctly prevent users from making trait objects
// from traits with associated consts.
//
//@ revisions: curr dyn_compatible_for_dispatch

#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]

trait Bar {
const X: usize;
}

fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//[curr]~^ ERROR E0038
//~^ ERROR E0038
t
//~^ ERROR E0038
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:20:5
--> $DIR/associated-consts.rs:8:31
|
LL | t
| ^ `Bar` is not dyn compatible
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/generics.rs:10:8
--> $DIR/associated-consts.rs:5:11
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
= note: required for the cast from `&T` to `&dyn Bar`
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait

error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:27:5
--> $DIR/associated-consts.rs:10:5
|
LL | t as &dyn Bar
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/generics.rs:10:8
--> $DIR/associated-consts.rs:5:11
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
= note: required for the cast from `&T` to `&dyn Bar`

error: aborting due to 2 previous errors
Expand Down
15 changes: 5 additions & 10 deletions tests/ui/dyn-compatibility/generics.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Check that we correctly prevent users from making trait objects
// from traits with generic methods, unless `where Self : Sized` is
// present.
//@ revisions: curr dyn_compatible_for_dispatch

#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))]


trait Bar {
Expand All @@ -16,18 +13,16 @@ trait Quux {
}

fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//[curr]~^ ERROR E0038
//~^ ERROR E0038
t
//[dyn_compatible_for_dispatch]~^ ERROR E0038
//[curr]~^^ ERROR E0038
//~^ ERROR E0038
}

fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
//[curr]~^ ERROR E0038
//~^ ERROR E0038
t as &dyn Bar
//[dyn_compatible_for_dispatch]~^ ERROR E0038
//[curr]~^^ ERROR E0038
//[curr]~| ERROR E0038
//~^ ERROR E0038
//~| ERROR E0038
}

fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
Expand Down
Loading

0 comments on commit 27d0df5

Please sign in to comment.