1
Fork 0

Rollup merge of #134367 - WaffleLapkin:trait_upcasting_as_a_treat, r=compiler-errors

Stabilize `feature(trait_upcasting)`

This feature was "done" for a while now, I think it's finally time to stabilize it! Stabilization report: https://github.com/rust-lang/rust/pull/134367#issuecomment-2545839841.
cc reference PR: https://github.com/rust-lang/reference/pull/1622.

Closes #65991 (tracking issue), closes #89460 (the lint is no longer future incompat).

r? compiler-errors
This commit is contained in:
Matthias Krüger 2025-02-07 18:26:25 +01:00 committed by GitHub
commit cbd44d7998
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
94 changed files with 140 additions and 479 deletions

View file

@ -400,6 +400,9 @@ declare_features! (
/// Allows `#[track_caller]` to be used which provides /// Allows `#[track_caller]` to be used which provides
/// accurate caller location reporting during panic (RFC 2091). /// accurate caller location reporting during panic (RFC 2091).
(accepted, track_caller, "1.46.0", Some(47809)), (accepted, track_caller, "1.46.0", Some(47809)),
/// Allows dyn upcasting trait objects via supertraits.
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(accepted, trait_upcasting, "CURRENT_RUSTC_VERSION", Some(65991)),
/// Allows #[repr(transparent)] on univariant enums (RFC 2645). /// Allows #[repr(transparent)] on univariant enums (RFC 2645).
(accepted, transparent_enums, "1.42.0", Some(60405)), (accepted, transparent_enums, "1.42.0", Some(60405)),
/// Allows indexing tuples. /// Allows indexing tuples.

View file

@ -634,9 +634,6 @@ declare_features! (
(unstable, thread_local, "1.0.0", Some(29594)), (unstable, thread_local, "1.0.0", Some(29594)),
/// Allows defining `trait X = A + B;` alias items. /// Allows defining `trait X = A + B;` alias items.
(unstable, trait_alias, "1.24.0", Some(41517)), (unstable, trait_alias, "1.24.0", Some(41517)),
/// Allows dyn upcasting trait objects via supertraits.
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
(unstable, trait_upcasting, "1.56.0", Some(65991)),
/// Allows for transmuting between arrays with sizes that contain generic consts. /// Allows for transmuting between arrays with sizes that contain generic consts.
(unstable, transmute_generic_consts, "1.70.0", Some(109929)), (unstable, transmute_generic_consts, "1.70.0", Some(109929)),
/// Allows #[repr(transparent)] on unions (RFC 2645). /// Allows #[repr(transparent)] on unions (RFC 2645).

View file

@ -605,7 +605,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
)]; )];
let mut has_unsized_tuple_coercion = false; let mut has_unsized_tuple_coercion = false;
let mut has_trait_upcasting_coercion = None;
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@ -690,13 +689,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// these here and emit a feature error if coercion doesn't fail // these here and emit a feature error if coercion doesn't fail
// due to another reason. // due to another reason.
match impl_source { match impl_source {
traits::ImplSource::Builtin(
BuiltinImplSource::TraitUpcasting { .. },
_,
) => {
has_trait_upcasting_coercion =
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
}
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => { traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
has_unsized_tuple_coercion = true; has_unsized_tuple_coercion = true;
} }
@ -707,21 +699,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
} }
} }
if let Some((sub, sup)) = has_trait_upcasting_coercion
&& !self.tcx().features().trait_upcasting()
{
// Renders better when we erase regions, since they're not really the point here.
let (sub, sup) = self.tcx.erase_regions((sub, sup));
let mut err = feature_err(
&self.tcx.sess,
sym::trait_upcasting,
self.cause.span,
format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"),
);
err.note(format!("required when coercing `{source}` into `{target}`"));
err.emit();
}
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() { if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() {
feature_err( feature_err(
&self.tcx.sess, &self.tcx.sess,

View file

@ -1,6 +1,5 @@
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, LangItem};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::{declare_lint, declare_lint_pass}; use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym; use rustc_span::sym;
use rustc_trait_selection::traits::supertraits; use rustc_trait_selection::traits::supertraits;
@ -9,11 +8,12 @@ use crate::lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel};
use crate::{LateContext, LateLintPass, LintContext}; use crate::{LateContext, LateLintPass, LintContext};
declare_lint! { declare_lint! {
/// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the /// The `deref_into_dyn_supertrait` lint is emitted whenever there is a `Deref` implementation
/// `Deref` implementation with a `dyn SuperTrait` type as `Output`. /// for `dyn SubTrait` with a `dyn SuperTrait` type as the `Output` type.
/// ///
/// These implementations will become shadowed when the `trait_upcasting` feature is stabilized. /// These implementations are "shadowed" by trait upcasting (stabilized since
/// The `deref` functions will no longer be called implicitly, so there might be behavior change. /// CURRENT_RUSTC_VERSION). The `deref` functions is no longer called implicitly, which might
/// change behavior compared to previous rustc versions.
/// ///
/// ### Example /// ### Example
/// ///
@ -43,15 +43,14 @@ declare_lint! {
/// ///
/// ### Explanation /// ### Explanation
/// ///
/// The dyn upcasting coercion feature adds new coercion rules, taking priority /// The trait upcasting coercion added a new coercion rule, taking priority over certain other
/// over certain other coercion rules, which will cause some behavior change. /// coercion rules, which causes some behavior change compared to older `rustc` versions.
///
/// `deref` can be still called explicitly, it just isn't called as part of a deref coercion
/// (since trait upcasting coercion takes priority).
pub DEREF_INTO_DYN_SUPERTRAIT, pub DEREF_INTO_DYN_SUPERTRAIT,
Warn, Allow,
"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future", "`Deref` implementation with a supertrait trait object for output is shadowed by trait upcasting",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
};
} }
declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]); declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);

View file

@ -21,6 +21,7 @@
// tidy-alphabetical-start // tidy-alphabetical-start
#![allow(internal_features)] #![allow(internal_features)]
#![cfg_attr(bootstrap, feature(trait_upcasting))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(array_windows)] #![feature(array_windows)]
@ -32,7 +33,6 @@
#![feature(let_chains)] #![feature(let_chains)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(rustdoc_internals)] #![feature(rustdoc_internals)]
#![feature(trait_upcasting)]
#![warn(unreachable_pub)] #![warn(unreachable_pub)]
// tidy-alphabetical-end // tidy-alphabetical-end

View file

@ -29,6 +29,7 @@
#![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::potential_query_instability)] #![allow(rustc::potential_query_instability)]
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(trait_upcasting))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(allocator_api)] #![feature(allocator_api)]
@ -56,7 +57,6 @@
#![feature(ptr_alignment_type)] #![feature(ptr_alignment_type)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(rustdoc_internals)] #![feature(rustdoc_internals)]
#![feature(trait_upcasting)]
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(try_trait_v2)] #![feature(try_trait_v2)]

View file

@ -12,9 +12,7 @@ use hir::LangItem;
use hir::def_id::DefId; use hir::def_id::DefId;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::{ use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
Obligation, ObligationCause, PolyTraitObligation, PredicateObligations, SelectionError,
};
use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode}; use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
@ -23,8 +21,6 @@ use tracing::{debug, instrument, trace};
use super::SelectionCandidate::*; use super::SelectionCandidate::*;
use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack}; use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
use crate::traits;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::util; use crate::traits::util;
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@ -904,54 +900,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}) })
} }
/// Temporary migration for #89190
fn need_migrate_deref_output_trait_object(
&mut self,
ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
cause: &ObligationCause<'tcx>,
) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
// Don't drop any candidates in intercrate mode, as it's incomplete.
// (Not that it matters, since `Unsize` is not a stable trait.)
//
// FIXME(@lcnr): This should probably only trigger during analysis,
// disabling candidates during codegen is also questionable.
if let TypingMode::Coherence = self.infcx.typing_mode() {
return None;
}
let tcx = self.tcx();
if tcx.features().trait_upcasting() {
return None;
}
// <ty as Deref>
let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
let obligation =
traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref));
if !self.infcx.predicate_may_hold(&obligation) {
return None;
}
self.infcx.probe(|_| {
let ty = traits::normalize_projection_ty(
self,
param_env,
ty::AliasTy::new_from_args(tcx, tcx.lang_items().deref_target()?, trait_ref.args),
cause.clone(),
0,
// We're *intentionally* throwing these away,
// since we don't actually use them.
&mut PredicateObligations::new(),
)
.as_type()
.unwrap();
if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
})
}
/// Searches for unsizing that might apply to `obligation`. /// Searches for unsizing that might apply to `obligation`.
fn assemble_candidates_for_unsizing( fn assemble_candidates_for_unsizing(
&mut self, &mut self,
@ -1019,15 +967,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let principal_a = a_data.principal().unwrap(); let principal_a = a_data.principal().unwrap();
let target_trait_did = principal_def_id_b.unwrap(); let target_trait_did = principal_def_id_b.unwrap();
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source); let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
source,
obligation.param_env,
&obligation.cause,
) {
if deref_trait_ref.def_id() == target_trait_did {
return;
}
}
for (idx, upcast_trait_ref) in for (idx, upcast_trait_ref) in
util::supertraits(self.tcx(), source_trait_ref).enumerate() util::supertraits(self.tcx(), source_trait_ref).enumerate()

View file

@ -179,9 +179,7 @@ pub enum BuiltinImplSource {
Object(usize), Object(usize),
/// A built-in implementation of `Upcast` for trait objects to other trait objects. /// A built-in implementation of `Upcast` for trait objects to other trait objects.
/// ///
/// This can be removed when `feature(dyn_upcasting)` is stabilized, since we only /// The index is only used for winnowing.
/// use it to detect when upcasting traits in hir typeck. The index is only used
/// for winnowing.
TraitUpcasting(usize), TraitUpcasting(usize),
/// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`. /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
/// ///

View file

@ -81,7 +81,6 @@
#![feature(strict_provenance_atomic_ptr)] #![feature(strict_provenance_atomic_ptr)]
#![feature(strict_provenance_lints)] #![feature(strict_provenance_lints)]
#![feature(test)] #![feature(test)]
#![feature(trait_upcasting)]
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(trusted_random_access)] #![feature(trusted_random_access)]
#![feature(try_blocks)] #![feature(try_blocks)]

View file

@ -1,26 +0,0 @@
# `trait_upcasting`
The tracking issue for this feature is: [#65991]
[#65991]: https://github.com/rust-lang/rust/issues/65991
------------------------
The `trait_upcasting` feature adds support for trait upcasting coercion. This allows a
trait object of type `dyn Bar` to be cast to a trait object of type `dyn Foo`
so long as `Bar: Foo`.
```rust,edition2018
#![feature(trait_upcasting)]
trait Foo {}
trait Bar: Foo {}
impl Foo for i32 {}
impl<T: Foo + ?Sized> Bar for T {}
let bar: &dyn Bar = &123;
let foo: &dyn Foo = bar;
```

View file

@ -1,3 +1,4 @@
#![cfg_attr(bootstrap, feature(trait_upcasting))]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(cell_update)] #![feature(cell_update)]
#![feature(float_gamma)] #![feature(float_gamma)]
@ -9,7 +10,6 @@
#![feature(yeet_expr)] #![feature(yeet_expr)]
#![feature(nonzero_ops)] #![feature(nonzero_ops)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(trait_upcasting)]
#![feature(strict_overflow_ops)] #![feature(strict_overflow_ops)]
#![feature(pointer_is_aligned_to)] #![feature(pointer_is_aligned_to)]
#![feature(unqualified_local_imports)] #![feature(unqualified_local_imports)]

View file

@ -1,9 +1,6 @@
// Validation stops this too early. // Validation stops this too early.
//@compile-flags: -Zmiri-disable-validation //@compile-flags: -Zmiri-disable-validation
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
#[allow(dead_code)] #[allow(dead_code)]
fn a(&self) -> i32 { fn a(&self) -> i32 {

View file

@ -1,7 +1,6 @@
//@revisions: stack tree //@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows //@[tree]compile-flags: -Zmiri-tree-borrows
#![allow(incomplete_features)] // for trait upcasting #![feature(allocator_api)]
#![feature(allocator_api, trait_upcasting)]
use std::alloc::{AllocError, Allocator, Layout}; use std::alloc::{AllocError, Allocator, Layout};
use std::cell::Cell; use std::cell::Cell;

View file

@ -1,6 +1,3 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
use std::fmt; use std::fmt;
fn main() { fn main() {

View file

@ -2,7 +2,6 @@
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 //@ compile-flags: -C no-prepopulate-passes -Copt-level=0
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(trait_upcasting)]
pub trait Base { pub trait Base {
fn base(&self); fn base(&self);

View file

@ -1,6 +1,6 @@
//@ known-bug: #131886 //@ known-bug: #131886
//@ compile-flags: -Zvalidate-mir --crate-type=lib //@ compile-flags: -Zvalidate-mir --crate-type=lib
#![feature(trait_upcasting, type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
type Tait = impl Sized; type Tait = impl Sized;

View file

@ -1,5 +1,4 @@
//@ build-pass //@ build-pass
#![feature(trait_upcasting)]
pub trait A {} pub trait A {}
pub trait B {} pub trait B {}

View file

@ -1,5 +1,5 @@
#![feature(dyn_star, trait_upcasting)] #![expect(incomplete_features)]
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes #![feature(dyn_star)]
trait A: B {} trait A: B {}
trait B {} trait B {}

View file

@ -1,12 +1,3 @@
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/no-unsize-coerce-dyn-trait.rs:1:12
|
LL | #![feature(dyn_star, trait_upcasting)]
| ^^^^^^^^
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/no-unsize-coerce-dyn-trait.rs:11:26 --> $DIR/no-unsize-coerce-dyn-trait.rs:11:26
| |
@ -18,6 +9,6 @@ LL | let y: Box<dyn* B> = x;
= note: expected struct `Box<dyn* B>` = note: expected struct `Box<dyn* B>`
found struct `Box<dyn* A>` found struct `Box<dyn* A>`
error: aborting due to 1 previous error; 1 warning emitted error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.

View file

@ -1,6 +1,6 @@
//@ known-bug: #104800 //@ known-bug: #104800
#![feature(dyn_star, trait_upcasting)] #![feature(dyn_star)]
trait Foo: Bar { trait Foo: Bar {
fn hello(&self); fn hello(&self);

View file

@ -1,7 +1,7 @@
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/upcast.rs:3:12 --> $DIR/upcast.rs:3:12
| |
LL | #![feature(dyn_star, trait_upcasting)] LL | #![feature(dyn_star)]
| ^^^^^^^^ | ^^^^^^^^
| |
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information = note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information

View file

@ -1,13 +0,0 @@
trait Foo {}
trait Bar: Foo {}
impl Foo for () {}
impl Bar for () {}
fn main() {
let bar: &dyn Bar = &();
let foo: &dyn Foo = bar;
//~^ ERROR trait upcasting coercion is experimental [E0658]
}

View file

@ -1,14 +0,0 @@
error[E0658]: cannot cast `dyn Bar` to `dyn Foo`, trait upcasting coercion is experimental
--> $DIR/feature-gate-trait_upcasting.rs:11:25
|
LL | let foo: &dyn Foo = bar;
| ^^^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: required when coercing `&dyn Bar` into `&dyn Foo`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
--> $DIR/unsized_coercion5.rs:17:32 --> $DIR/unsized_coercion5.rs:15:32
| |
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>; LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
| ^ doesn't have a size known at compile-time | ^ doesn't have a size known at compile-time

View file

@ -5,8 +5,6 @@
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
//@[next] check-pass //@[next] check-pass
#![feature(trait_upcasting)]
trait Trait {} trait Trait {}
impl Trait for u32 {} impl Trait for u32 {}

View file

@ -1,4 +1,3 @@
#![feature(trait_upcasting)]
// Check that super-traits are callable. // Check that super-traits are callable.
//@ revisions: cfi kcfi //@ revisions: cfi kcfi

View file

@ -1,6 +1,5 @@
//@ compile-flags: -Znext-solver //@ compile-flags: -Znext-solver
//@ check-pass //@ check-pass
#![feature(trait_upcasting)]
trait A {} trait A {}
trait B: A {} trait B: A {}

View file

@ -1,6 +1,5 @@
//@ check-pass //@ check-pass
//@ compile-flags: -Znext-solver //@ compile-flags: -Znext-solver
#![feature(trait_upcasting)]
pub trait A {} pub trait A {}
pub trait B: A {} pub trait B: A {}

View file

@ -1,6 +1,5 @@
//@ compile-flags: -Znext-solver //@ compile-flags: -Znext-solver
//@ check-pass //@ check-pass
#![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {} trait Foo: Bar<i32> + Bar<u32> {}

View file

@ -3,8 +3,6 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
#![feature(trait_upcasting)]
trait Target {} trait Target {}
trait Source: Send + Target {} trait Source: Send + Target {}

View file

@ -1,4 +1,3 @@
#![feature(trait_upcasting)]
#![feature(trait_alias)] #![feature(trait_alias)]
// Although we *elaborate* `T: Alias` to `i32: B`, we should // Although we *elaborate* `T: Alias` to `i32: B`, we should

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/alias-where-clause-isnt-supertrait.rs:27:5 --> $DIR/alias-where-clause-isnt-supertrait.rs:26:5
| |
LL | fn test(x: &dyn C) -> &dyn B { LL | fn test(x: &dyn C) -> &dyn B {
| ------ expected `&dyn B` because of return type | ------ expected `&dyn B` because of return type

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { fn a(&self) -> i32 {
10 10

View file

@ -1,5 +1,4 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {} trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {}
trait Bar<T: Default + ToString> { trait Bar<T: Default + ToString> {

View file

@ -1,35 +0,0 @@
#![deny(deref_into_dyn_supertrait)]
use std::ops::Deref;
trait Bar<T> {}
impl<T, U> Bar<U> for T {}
trait Foo: Bar<i32> {
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a);
}
impl Foo for () {
fn as_dyn_bar_u32<'a>(&self) -> &(dyn Bar<u32> + 'a) {
self
}
}
impl<'a> Deref for dyn Foo + 'a {
//~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion
//~| WARN this will change its meaning in a future release!
type Target = dyn Bar<u32> + 'a;
fn deref(&self) -> &Self::Target {
self.as_dyn_bar_u32()
}
}
fn take_dyn<T>(x: &dyn Bar<T>) -> T {
todo!()
}
fn main() {
let x: &dyn Foo = &();
let y = take_dyn(x);
let z: u32 = y;
}

View file

@ -1,19 +0,0 @@
error: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/deref-upcast-behavioral-change.rs:17:1
|
LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
...
LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo`
|
= warning: this will change its meaning in a future release!
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
note: the lint level is defined here
--> $DIR/deref-upcast-behavioral-change.rs:1:9
|
LL | #![deny(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -0,0 +1,17 @@
//@ check-pass
#![warn(deref_into_dyn_supertrait)]
use std::ops::Deref;
trait Bar<T> {}
trait Foo: Bar<i32> {}
impl<'a> Deref for dyn Foo + 'a {
//~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion
type Target = dyn Bar<u32> + 'a;
fn deref(&self) -> &Self::Target {
todo!()
}
}
fn main() {}

View file

@ -0,0 +1,17 @@
warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/deref-upcast-shadowing-lint.rs:8:1
|
LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
LL |
LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo`
|
note: the lint level is defined here
--> $DIR/deref-upcast-shadowing-lint.rs:2:9
|
LL | #![warn(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: 1 warning emitted

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { fn a(&self) -> i32 {
10 10

View file

@ -4,8 +4,6 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
#![feature(trait_upcasting)]
trait A: B { trait A: B {
type Assoc; type Assoc;
} }

View file

@ -6,8 +6,6 @@
// Check that we are able to instantiate a binder during trait upcasting, // Check that we are able to instantiate a binder during trait upcasting,
// and that it doesn't cause any issues with codegen either. // and that it doesn't cause any issues with codegen either.
#![feature(trait_upcasting)]
trait Supertrait<'a, 'b> {} trait Supertrait<'a, 'b> {}
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}

View file

@ -5,7 +5,7 @@
// We previously wrongly instantiated binders during trait upcasting, // We previously wrongly instantiated binders during trait upcasting,
// allowing the super trait to be more generic than the sub trait. // allowing the super trait to be more generic than the sub trait.
// This was unsound. // This was unsound.
#![feature(trait_upcasting)]
trait Supertrait<'a, 'b> { trait Supertrait<'a, 'b> {
fn cast(&self, x: &'a str) -> &'b str; fn cast(&self, x: &'a str) -> &'b str;
} }

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/illegal-upcast-from-impl.rs:17:66 --> $DIR/illegal-upcast-from-impl.rs:15:66
| |
LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x } LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
| ----------------------- ^ expected trait `Super`, found trait `Sub` | ----------------------- ^ expected trait `Super`, found trait `Sub`

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/illegal-upcast-from-impl.rs:17:66 --> $DIR/illegal-upcast-from-impl.rs:15:66
| |
LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x } LL | fn illegal(x: &dyn Sub<Assoc = ()>) -> &dyn Super<Assoc = i32> { x }
| ----------------------- ^ expected trait `Super`, found trait `Sub` | ----------------------- ^ expected trait `Super`, found trait `Sub`

View file

@ -2,8 +2,6 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
#![feature(trait_upcasting)]
trait Super { trait Super {
type Assoc; type Assoc;
} }

View file

@ -9,8 +9,6 @@
//@[next] rustc-env:RUST_BACKTRACE=0 //@[next] rustc-env:RUST_BACKTRACE=0
//@ check-pass //@ check-pass
#![feature(trait_upcasting)]
trait Super { trait Super {
type Assoc; type Assoc;
} }

View file

@ -1,6 +1,3 @@
#![deny(deref_into_dyn_supertrait)]
#![feature(trait_upcasting)] // remove this and the test compiles
use std::ops::Deref; use std::ops::Deref;
trait Bar<T> {} trait Bar<T> {}
@ -32,5 +29,5 @@ fn main() {
let x: &dyn Foo = &(); let x: &dyn Foo = &();
let y = take_dyn(x); let y = take_dyn(x);
let z: u32 = y; let z: u32 = y;
//~^ ERROR mismatched types //~^ error: mismatched types
} }

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/inference-behavior-change-deref.rs:34:18 --> $DIR/inference-behavior-change-deref.rs:31:18
| |
LL | let z: u32 = y; LL | let z: u32 = y;
| --- ^ expected `u32`, found `i32` | --- ^ expected `u32`, found `i32`

View file

@ -1,5 +1,3 @@
#![feature(trait_upcasting)]
trait Foo { trait Foo {
fn a(&self) -> i32 { fn a(&self) -> i32 {
10 10

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:53:35 --> $DIR/invalid-upcast.rs:51:35
| |
LL | let _: &dyn std::fmt::Debug = baz; LL | let _: &dyn std::fmt::Debug = baz;
| -------------------- ^^^ expected trait `Debug`, found trait `Baz` | -------------------- ^^^ expected trait `Debug`, found trait `Baz`
@ -10,7 +10,7 @@ LL | let _: &dyn std::fmt::Debug = baz;
found reference `&dyn Baz` found reference `&dyn Baz`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:55:24 --> $DIR/invalid-upcast.rs:53:24
| |
LL | let _: &dyn Send = baz; LL | let _: &dyn Send = baz;
| --------- ^^^ expected trait `Send`, found trait `Baz` | --------- ^^^ expected trait `Send`, found trait `Baz`
@ -21,7 +21,7 @@ LL | let _: &dyn Send = baz;
found reference `&dyn Baz` found reference `&dyn Baz`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:57:24 --> $DIR/invalid-upcast.rs:55:24
| |
LL | let _: &dyn Sync = baz; LL | let _: &dyn Sync = baz;
| --------- ^^^ expected trait `Sync`, found trait `Baz` | --------- ^^^ expected trait `Sync`, found trait `Baz`
@ -32,7 +32,7 @@ LL | let _: &dyn Sync = baz;
found reference `&dyn Baz` found reference `&dyn Baz`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:60:25 --> $DIR/invalid-upcast.rs:58:25
| |
LL | let bar: &dyn Bar = baz; LL | let bar: &dyn Bar = baz;
| -------- ^^^ expected trait `Bar`, found trait `Baz` | -------- ^^^ expected trait `Bar`, found trait `Baz`
@ -43,7 +43,7 @@ LL | let bar: &dyn Bar = baz;
found reference `&dyn Baz` found reference `&dyn Baz`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:62:35 --> $DIR/invalid-upcast.rs:60:35
| |
LL | let _: &dyn std::fmt::Debug = bar; LL | let _: &dyn std::fmt::Debug = bar;
| -------------------- ^^^ expected trait `Debug`, found trait `Bar` | -------------------- ^^^ expected trait `Debug`, found trait `Bar`
@ -54,7 +54,7 @@ LL | let _: &dyn std::fmt::Debug = bar;
found reference `&dyn Bar` found reference `&dyn Bar`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:64:24 --> $DIR/invalid-upcast.rs:62:24
| |
LL | let _: &dyn Send = bar; LL | let _: &dyn Send = bar;
| --------- ^^^ expected trait `Send`, found trait `Bar` | --------- ^^^ expected trait `Send`, found trait `Bar`
@ -65,7 +65,7 @@ LL | let _: &dyn Send = bar;
found reference `&dyn Bar` found reference `&dyn Bar`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:66:24 --> $DIR/invalid-upcast.rs:64:24
| |
LL | let _: &dyn Sync = bar; LL | let _: &dyn Sync = bar;
| --------- ^^^ expected trait `Sync`, found trait `Bar` | --------- ^^^ expected trait `Sync`, found trait `Bar`
@ -76,7 +76,7 @@ LL | let _: &dyn Sync = bar;
found reference `&dyn Bar` found reference `&dyn Bar`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:69:25 --> $DIR/invalid-upcast.rs:67:25
| |
LL | let foo: &dyn Foo = baz; LL | let foo: &dyn Foo = baz;
| -------- ^^^ expected trait `Foo`, found trait `Baz` | -------- ^^^ expected trait `Foo`, found trait `Baz`
@ -87,7 +87,7 @@ LL | let foo: &dyn Foo = baz;
found reference `&dyn Baz` found reference `&dyn Baz`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:71:35 --> $DIR/invalid-upcast.rs:69:35
| |
LL | let _: &dyn std::fmt::Debug = foo; LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo` | -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@ -98,7 +98,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo` found reference `&dyn Foo`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:73:24 --> $DIR/invalid-upcast.rs:71:24
| |
LL | let _: &dyn Send = foo; LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo` | --------- ^^^ expected trait `Send`, found trait `Foo`
@ -109,7 +109,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo` found reference `&dyn Foo`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:75:24 --> $DIR/invalid-upcast.rs:73:24
| |
LL | let _: &dyn Sync = foo; LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo` | --------- ^^^ expected trait `Sync`, found trait `Foo`
@ -120,7 +120,7 @@ LL | let _: &dyn Sync = foo;
found reference `&dyn Foo` found reference `&dyn Foo`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:78:25 --> $DIR/invalid-upcast.rs:76:25
| |
LL | let foo: &dyn Foo = bar; LL | let foo: &dyn Foo = bar;
| -------- ^^^ expected trait `Foo`, found trait `Bar` | -------- ^^^ expected trait `Foo`, found trait `Bar`
@ -131,7 +131,7 @@ LL | let foo: &dyn Foo = bar;
found reference `&dyn Bar` found reference `&dyn Bar`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:80:35 --> $DIR/invalid-upcast.rs:78:35
| |
LL | let _: &dyn std::fmt::Debug = foo; LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo` | -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@ -142,7 +142,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo` found reference `&dyn Foo`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:82:24 --> $DIR/invalid-upcast.rs:80:24
| |
LL | let _: &dyn Send = foo; LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo` | --------- ^^^ expected trait `Send`, found trait `Foo`
@ -153,7 +153,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo` found reference `&dyn Foo`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/invalid-upcast.rs:84:24 --> $DIR/invalid-upcast.rs:82:24
| |
LL | let _: &dyn Sync = foo; LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo` | --------- ^^^ expected trait `Sync`, found trait `Foo`

View file

@ -1,5 +1,4 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
struct Test { struct Test {
func: Box<dyn FnMut() + 'static>, func: Box<dyn FnMut() + 'static>,

View file

@ -1,14 +0,0 @@
error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
--> $DIR/issue-11515.rs:11:38
|
LL | let test = Box::new(Test { func: closure });
| ^^^^^^^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,14 +0,0 @@
error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
--> $DIR/issue-11515.rs:11:38
|
LL | let test = Box::new(Test { func: closure });
| ^^^^^^^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,3 +1,4 @@
//@ check-pass
//@ revisions: current next //@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
@ -8,5 +9,5 @@ struct Test {
fn main() { fn main() {
let closure: Box<dyn Fn() + 'static> = Box::new(|| ()); let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
let test = Box::new(Test { func: closure }); //~ ERROR trait upcasting coercion is experimental [E0658] let test = Box::new(Test { func: closure });
} }

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { fn a(&self) -> i32 {
10 10

View file

@ -1,5 +1,5 @@
warning: methods `z` and `y` are never used warning: methods `z` and `y` are never used
--> $DIR/lifetime.rs:10:8 --> $DIR/lifetime.rs:8:8
| |
LL | trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { LL | trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
| --- methods in this trait | --- methods in this trait
@ -13,7 +13,7 @@ LL | fn y(&self) -> i32 {
= note: `#[warn(dead_code)]` on by default = note: `#[warn(dead_code)]` on by default
warning: method `w` is never used warning: method `w` is never used
--> $DIR/lifetime.rs:24:8 --> $DIR/lifetime.rs:22:8
| |
LL | trait Bar: Foo { LL | trait Bar: Foo {
| --- method in this trait | --- method in this trait

View file

@ -1,4 +1,5 @@
#![deny(deref_into_dyn_supertrait)] //@ check-pass
#![warn(deref_into_dyn_supertrait)]
use std::ops::Deref; use std::ops::Deref;
@ -6,8 +7,7 @@ trait Bar<'a> {}
trait Foo<'a>: Bar<'a> {} trait Foo<'a>: Bar<'a> {}
impl<'a> Deref for dyn Foo<'a> { impl<'a> Deref for dyn Foo<'a> {
//~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion
//~| WARN this will change its meaning in a future release!
type Target = dyn Bar<'a>; type Target = dyn Bar<'a>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {

View file

@ -1,19 +1,17 @@
error: this `Deref` implementation is covered by an implicit supertrait coercion warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/migrate-lint-deny-regions.rs:8:1 --> $DIR/migrate-lint-deny-regions.rs:9:1
| |
LL | impl<'a> Deref for dyn Foo<'a> { LL | impl<'a> Deref for dyn Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>`
... LL |
LL | type Target = dyn Bar<'a>; LL | type Target = dyn Bar<'a>;
| -------------------------- target type is a supertrait of `dyn Foo<'_>` | -------------------------- target type is a supertrait of `dyn Foo<'_>`
| |
= warning: this will change its meaning in a future release!
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
note: the lint level is defined here note: the lint level is defined here
--> $DIR/migrate-lint-deny-regions.rs:1:9 --> $DIR/migrate-lint-deny-regions.rs:2:9
| |
LL | #![deny(deref_into_dyn_supertrait)] LL | #![warn(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error warning: 1 warning emitted

View file

@ -1,25 +0,0 @@
#![deny(deref_into_dyn_supertrait)]
use std::ops::Deref;
// issue 89190
trait A {}
trait B: A {}
impl<'a> Deref for dyn 'a + B {
//~^ ERROR this `Deref` implementation is covered by an implicit supertrait coercion
//~| WARN this will change its meaning in a future release!
type Target = dyn A;
fn deref(&self) -> &Self::Target {
todo!()
}
}
fn take_a(_: &dyn A) {}
fn whoops(b: &dyn B) {
take_a(b)
}
fn main() {}

View file

@ -1,19 +0,0 @@
error: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/migrate-lint-deny.rs:9:1
|
LL | impl<'a> Deref for dyn 'a + B {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn B` implements `Deref<Target = dyn A>` which conflicts with supertrait `A`
...
LL | type Target = dyn A;
| -------------------- target type is a supertrait of `dyn B`
|
= warning: this will change its meaning in a future release!
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
note: the lint level is defined here
--> $DIR/migrate-lint-deny.rs:1:9
|
LL | #![deny(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -1,4 +1,5 @@
//@ check-pass //@ check-pass
#![warn(deref_into_dyn_supertrait)]
use std::ops::Deref; use std::ops::Deref;
@ -9,8 +10,7 @@ trait Foo: Bar<i32> {
} }
impl<'a> Deref for dyn Foo + 'a { impl<'a> Deref for dyn Foo + 'a {
//~^ WARN this `Deref` implementation is covered by an implicit supertrait coercion //~^ warn: this `Deref` implementation is covered by an implicit supertrait coercion
//~| WARN this will change its meaning in a future release!
type Target = dyn Bar<u32> + 'a; type Target = dyn Bar<u32> + 'a;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {

View file

@ -1,15 +1,17 @@
warning: this `Deref` implementation is covered by an implicit supertrait coercion warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/migrate-lint-different-substs.rs:11:1 --> $DIR/migrate-lint-different-substs.rs:12:1
| |
LL | impl<'a> Deref for dyn Foo + 'a { LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
... LL |
LL | type Target = dyn Bar<u32> + 'a; LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo` | -------------------------------- target type is a supertrait of `dyn Foo`
| |
= warning: this will change its meaning in a future release! note: the lint level is defined here
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> --> $DIR/migrate-lint-different-substs.rs:2:9
= note: `#[warn(deref_into_dyn_supertrait)]` on by default |
LL | #![warn(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: 1 warning emitted warning: 1 warning emitted

View file

@ -1,7 +1,5 @@
//@ build-pass //@ build-pass
#![feature(trait_upcasting)]
trait Supertrait<T> { trait Supertrait<T> {
fn method(&self) {} fn method(&self) {}
} }

View file

@ -1,5 +1,4 @@
//@ check-fail //@ check-fail
#![feature(trait_upcasting)]
trait Bar<T> { trait Bar<T> {
fn bar(&self, _: T) {} fn bar(&self, _: T) {}

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/multiple-occurrence-ambiguousity.rs:20:26 --> $DIR/multiple-occurrence-ambiguousity.rs:19:26
| |
LL | let t: &dyn Bar<_> = s; LL | let t: &dyn Bar<_> = s;
| ----------- ^ expected trait `Bar`, found trait `Foo` | ----------- ^ expected trait `Bar`, found trait `Foo`

View file

@ -1,10 +1,8 @@
// Test for <https://github.com/rust-lang/rust/issues/135316>.
//
//@ run-pass //@ run-pass
//@ check-run-results //@ check-run-results
// Test for <https://github.com/rust-lang/rust/issues/135316>.
#![feature(trait_upcasting)]
trait Supertrait<T> { trait Supertrait<T> {
fn _print_numbers(&self, mem: &[usize; 100]) { fn _print_numbers(&self, mem: &[usize; 100]) {
println!("{mem:?}"); println!("{mem:?}");

View file

@ -1,5 +1,4 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(trait_upcasting)]
// Test for <https://github.com/rust-lang/rust/issues/135315>. // Test for <https://github.com/rust-lang/rust/issues/135315>.

View file

@ -5,7 +5,7 @@ error: vtable entries: [
Method(<() as Supertrait<()>>::_print_numbers), Method(<() as Supertrait<()>>::_print_numbers),
Method(<() as Middle<()>>::say_hello), Method(<() as Middle<()>>::say_hello),
] ]
--> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:30:1 --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:29:1
| |
LL | impl Trait for () {} LL | impl Trait for () {}
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ error: vtable entries: [
Method(<dyn Middle<()> as Supertrait<()>>::_print_numbers - shim(reify)), Method(<dyn Middle<()> as Supertrait<()>>::_print_numbers - shim(reify)),
Method(<dyn Middle<()> as Middle<()>>::say_hello - shim(reify)), Method(<dyn Middle<()> as Middle<()>>::say_hello - shim(reify)),
] ]
--> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:34:1 --> $DIR/multiple-supertraits-modulo-normalization-vtable.rs:33:1
| |
LL | type Virtual = dyn Middle<()>; LL | type Virtual = dyn Middle<()>;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^

View file

@ -1,10 +1,8 @@
// Test for <https://github.com/rust-lang/rust/issues/135315>.
//
//@ run-pass //@ run-pass
//@ check-run-results //@ check-run-results
#![feature(trait_upcasting)]
// Test for <https://github.com/rust-lang/rust/issues/135315>.
trait Supertrait<T> { trait Supertrait<T> {
fn _print_numbers(&self, mem: &[usize; 100]) { fn _print_numbers(&self, mem: &[usize; 100]) {
println!("{mem:?}"); println!("{mem:?}");

View file

@ -4,8 +4,6 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
#![feature(trait_upcasting)]
trait Mirror { trait Mirror {
type Assoc; type Assoc;
} }

View file

@ -6,8 +6,6 @@
// Ensure we don't have ambiguity when upcasting to two supertraits // Ensure we don't have ambiguity when upcasting to two supertraits
// that are identical modulo normalization. // that are identical modulo normalization.
#![feature(trait_upcasting)]
trait Supertrait<T> { trait Supertrait<T> {
fn method(&self) {} fn method(&self) {}
} }

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait A { trait A {
fn foo_a(&self); //~ WARN method `foo_a` is never used fn foo_a(&self); //~ WARN method `foo_a` is never used
} }

View file

@ -1,5 +1,5 @@
warning: method `foo_a` is never used warning: method `foo_a` is never used
--> $DIR/replace-vptr.rs:6:8 --> $DIR/replace-vptr.rs:4:8
| |
LL | trait A { LL | trait A {
| - method in this trait | - method in this trait
@ -9,7 +9,7 @@ LL | fn foo_a(&self);
= note: `#[warn(dead_code)]` on by default = note: `#[warn(dead_code)]` on by default
warning: method `foo_c` is never used warning: method `foo_c` is never used
--> $DIR/replace-vptr.rs:14:8 --> $DIR/replace-vptr.rs:12:8
| |
LL | trait C: A + B { LL | trait C: A + B {
| - method in this trait | - method in this trait

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;

View file

@ -1,5 +1,3 @@
#![feature(trait_upcasting)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync { trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 { fn a(&self) -> i32 {
10 10

View file

@ -1,12 +1,12 @@
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
--> $DIR/subtrait-method.rs:55:9 --> $DIR/subtrait-method.rs:53:9
| |
LL | bar.c(); LL | bar.c();
| ^ | ^
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:27:1 --> $DIR/subtrait-method.rs:25:1
| |
LL | trait Baz: Bar { LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -16,14 +16,14 @@ LL | bar.a();
| ~ | ~
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:59:9 --> $DIR/subtrait-method.rs:57:9
| |
LL | foo.b(); LL | foo.b();
| ^ | ^
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it note: `Bar` defines an item `b`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:17:1 --> $DIR/subtrait-method.rs:15:1
| |
LL | trait Bar: Foo { LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -33,14 +33,14 @@ LL | foo.a();
| ~ | ~
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:61:9 --> $DIR/subtrait-method.rs:59:9
| |
LL | foo.c(); LL | foo.c();
| ^ | ^
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:27:1 --> $DIR/subtrait-method.rs:25:1
| |
LL | trait Baz: Bar { LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -50,14 +50,14 @@ LL | foo.a();
| ~ | ~
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:65:9 --> $DIR/subtrait-method.rs:63:9
| |
LL | foo.b(); LL | foo.b();
| ^ | ^
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it note: `Bar` defines an item `b`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:17:1 --> $DIR/subtrait-method.rs:15:1
| |
LL | trait Bar: Foo { LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -67,14 +67,14 @@ LL | foo.a();
| ~ | ~
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:67:9 --> $DIR/subtrait-method.rs:65:9
| |
LL | foo.c(); LL | foo.c();
| ^ | ^
| |
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it note: `Baz` defines an item `c`, perhaps you need to implement it
--> $DIR/subtrait-method.rs:27:1 --> $DIR/subtrait-method.rs:25:1
| |
LL | trait Baz: Bar { LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^

View file

@ -1,7 +1,5 @@
//@ run-pass //@ run-pass
#![feature(trait_upcasting)]
trait Super<U> { trait Super<U> {
fn call(&self) fn call(&self)
where where

View file

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:20:13 --> $DIR/type-checking-test-1.rs:18:13
| |
LL | let _ = x as &dyn Bar<_>; // Ambiguous LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object

View file

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:20:13 --> $DIR/type-checking-test-1.rs:18:13
| |
LL | let _ = x as &dyn Bar<_>; // Ambiguous LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object

View file

@ -2,8 +2,6 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
#![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {} trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> { trait Bar<T> {
fn bar(&self) -> Option<T> { fn bar(&self) -> Option<T> {

View file

@ -1,5 +1,3 @@
#![feature(trait_upcasting)]
trait Foo<T>: Bar<i32> + Bar<T> {} trait Foo<T>: Bar<i32> + Bar<T> {}
trait Bar<T> { trait Bar<T> {
fn bar(&self) -> Option<T> { fn bar(&self) -> Option<T> {

View file

@ -1,11 +1,11 @@
error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>` error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
--> $DIR/type-checking-test-2.rs:19:13 --> $DIR/type-checking-test-2.rs:17:13
| |
LL | let _ = x as &dyn Bar<u32>; // Error LL | let _ = x as &dyn Bar<u32>; // Error
| ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>` error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
--> $DIR/type-checking-test-2.rs:24:13 --> $DIR/type-checking-test-2.rs:22:13
| |
LL | let a = x as &dyn Bar<_>; // Ambiguous LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object

View file

@ -1,5 +1,3 @@
#![feature(trait_upcasting)]
trait Foo<'a>: Bar<'a> {} trait Foo<'a>: Bar<'a> {}
trait Bar<'a> {} trait Bar<'a> {}

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:11:13 --> $DIR/type-checking-test-3.rs:9:13
| |
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'a>; // Error
| ^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` | ^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-3.rs:16:18 --> $DIR/type-checking-test-3.rs:14:18
| |
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here

View file

@ -1,5 +1,3 @@
#![feature(trait_upcasting)]
trait Foo<'a>: Bar<'a, 'a> {} trait Foo<'a>: Bar<'a, 'a> {}
trait Bar<'a, 'b> { trait Bar<'a, 'b> {
fn get_b(&self) -> Option<&'a u32> { fn get_b(&self) -> Option<&'a u32> {

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:19:13 --> $DIR/type-checking-test-4.rs:17:13
| |
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:24:18 --> $DIR/type-checking-test-4.rs:22:18
| |
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:30:5 --> $DIR/type-checking-test-4.rs:28:5
| |
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -24,7 +24,7 @@ LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:35:5 --> $DIR/type-checking-test-4.rs:33:5
| |
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:40:5 --> $DIR/type-checking-test-4.rs:38:5
| |
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:48:5 --> $DIR/type-checking-test-4.rs:46:5
| |
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here

View file

@ -1,4 +1,4 @@
#![feature(trait_upcasting, type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
//@ check-pass //@ check-pass

View file

@ -3,7 +3,7 @@
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@check-pass //@check-pass
#![feature(trait_upcasting, type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
trait Super { trait Super {
type Assoc; type Assoc;

View file

@ -1,14 +0,0 @@
error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
--> $DIR/upcast-through-struct-tail.rs:11:5
|
LL | x
| ^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,14 +0,0 @@
error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
--> $DIR/upcast-through-struct-tail.rs:11:5
|
LL | x
| ^
|
= note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
= help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,3 +1,4 @@
//@ check-pass
//@ revisions: current next //@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
@ -9,7 +10,6 @@ trait B {}
fn test<'a>(x: Box<Wrapper<dyn A + 'a>>) -> Box<Wrapper<dyn B + 'a>> { fn test<'a>(x: Box<Wrapper<dyn A + 'a>>) -> Box<Wrapper<dyn B + 'a>> {
x x
//~^ ERROR cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
} }
fn main() {} fn main() {}

View file

@ -2,8 +2,6 @@
// //
// issue: <https://github.com/rust-lang/rust/issues/131813> // issue: <https://github.com/rust-lang/rust/issues/131813>
#![feature(trait_upcasting)]
trait Pollable { trait Pollable {
#[allow(unused)] #[allow(unused)]
fn poll(&self) {} fn poll(&self) {}

View file

@ -1,4 +1,3 @@
#![feature(trait_upcasting)]
//@ check-fail //@ check-fail
// //
// issue: <https://github.com/rust-lang/rust/pull/120222> // issue: <https://github.com/rust-lang/rust/pull/120222>

View file

@ -1,5 +1,5 @@
error[E0606]: casting `*const dyn Trait<u8, u8>` as `*const dyn Trait<u8, u16>` is invalid error[E0606]: casting `*const dyn Trait<u8, u8>` as `*const dyn Trait<u8, u16>` is invalid
--> $DIR/upcast_soundness_bug.rs:59:13 --> $DIR/upcast_soundness_bug.rs:58:13
| |
LL | let p = p as *const dyn Trait<u8, u16>; // <- this is bad! LL | let p = p as *const dyn Trait<u8, u16>; // <- this is bad!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^