Auto merge of #118133 - Urgau:stabilize_trait_upcasting, r=WaffleLapkin

Stabilize RFC3324 dyn upcasting coercion

This PR stabilize the `trait_upcasting` feature, aka https://github.com/rust-lang/rfcs/pull/3324.

The FCP was completed here: https://github.com/rust-lang/rust/issues/65991#issuecomment-1817552398.

~~And also remove the `deref_into_dyn_supertrait` lint which is now handled by dyn upcasting coercion.~~

Heavily inspired by https://github.com/rust-lang/rust/pull/101718
Fixes https://github.com/rust-lang/rust/issues/65991
This commit is contained in:
bors 2023-11-22 16:15:34 +00:00
commit 6d2b84b3ed
69 changed files with 107 additions and 357 deletions

View File

@ -338,6 +338,9 @@ declare_features! (
/// Allows `#[track_caller]` to be used which provides
/// accurate caller location reporting during panic (RFC 2091).
(accepted, track_caller, "1.46.0", Some(47809), None),
/// 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), None),
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
(accepted, transparent_enums, "1.42.0", Some(60405), None),
/// Allows indexing tuples.

View File

@ -562,9 +562,6 @@ declare_features! (
(unstable, thread_local, "1.0.0", Some(29594), None),
/// Allows defining `trait X = A + B;` alias items.
(unstable, trait_alias, "1.24.0", Some(41517), None),
/// 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), None),
/// Allows for transmuting between arrays with sizes that contain generic consts.
(unstable, transmute_generic_consts, "1.70.0", Some(109929), None),
/// Allows #[repr(transparent)] on unions (RFC 2645).

View File

@ -626,7 +626,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
)];
let mut has_unsized_tuple_coercion = false;
let mut has_trait_upcasting_coercion = None;
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@ -694,13 +693,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// these here and emit a feature error if coercion doesn't fail
// due to another reason.
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, _) => {
has_unsized_tuple_coercion = true;
}
@ -711,21 +703,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.parse_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 {
feature_err(
&self.tcx.sess.parse_sess,

View File

@ -490,8 +490,9 @@ lint_requested_level = requested on the command line with `{$level} {$lint_name}
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
.label = target type is set here
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion
.help = consider removing this implementation or replacing it with a method instead
.label = target type is a supertrait of `{$t}`
lint_suspicious_double_ref_clone =
using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type

View File

@ -5,7 +5,6 @@ use crate::{
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_span::sym;
use rustc_trait_selection::traits::supertraits;
@ -13,9 +12,6 @@ declare_lint! {
/// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the
/// `Deref` implementation with a `dyn SuperTrait` type as `Output`.
///
/// These implementations will become shadowed when the `trait_upcasting` feature is stabilized.
/// The `deref` functions will no longer be called implicitly, so there might be behavior change.
///
/// ### Example
///
/// ```rust,compile_fail
@ -44,15 +40,10 @@ declare_lint! {
///
/// ### Explanation
///
/// The dyn upcasting coercion feature adds new coercion rules, taking priority
/// over certain other coercion rules, which will cause some behavior change.
/// The implicit dyn upcasting coercion take priority over those `Deref` impls.
pub DEREF_INTO_DYN_SUPERTRAIT,
Warn,
"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
};
"`Deref` implementation usage with a supertrait trait object for output are shadow by implicit coercion",
}
declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);
@ -90,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
cx.emit_spanned_lint(
DEREF_INTO_DYN_SUPERTRAIT,
tcx.def_span(item.owner_id.def_id),
SupertraitAsDerefTarget { t, target_principal, label },
SupertraitAsDerefTarget { t, label },
);
}
}

View File

@ -10,9 +10,7 @@ use rustc_errors::{
};
use rustc_hir::def_id::DefId;
use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::{
inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
};
use rustc_middle::ty::{inhabitedness::InhabitedPredicate, Clause, Ty, TyCtxt};
use rustc_session::parse::ParseSess;
use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
@ -556,9 +554,9 @@ pub enum BuiltinSpecialModuleNameUsed {
// deref_into_dyn_supertrait.rs
#[derive(LintDiagnostic)]
#[diag(lint_supertrait_as_deref_target)]
#[help]
pub struct SupertraitAsDerefTarget<'a> {
pub t: Ty<'a>,
pub target_principal: PolyExistentialTraitRef<'a>,
#[subdiagnostic]
pub label: Option<SupertraitAsDerefTargetLabel>,
}

View File

@ -49,7 +49,7 @@
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(control_flow_enum)]
#![feature(trait_upcasting)]
#![cfg_attr(bootstrap, feature(trait_upcasting))]
#![feature(trusted_step)]
#![feature(try_blocks)]
#![feature(try_reserve_kind)]

View File

@ -9,13 +9,10 @@
use hir::def_id::DefId;
use hir::LangItem;
use rustc_hir as hir;
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use crate::traits;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::util;
use super::BuiltinImplConditions;
@ -690,45 +687,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>> {
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_type(
self,
param_env,
ty::AliasTy::new(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 vec![],
)
.ty()
.unwrap();
if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
})
}
/// Searches for unsizing that might apply to `obligation`.
fn assemble_candidates_for_unsizing(
&mut self,
@ -786,15 +744,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let principal_a = a_data.principal().unwrap();
let target_trait_did = principal_def_id_b.unwrap();
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
util::supertraits(self.tcx(), source_trait_ref).enumerate()

View File

@ -111,7 +111,7 @@
#![feature(slice_flatten)]
#![feature(error_generic_member_access)]
#![feature(error_in_core)]
#![feature(trait_upcasting)]
#![cfg_attr(bootstrap, feature(trait_upcasting))]
#![feature(utf8_chunks)]
#![feature(is_ascii_octdigit)]
#![feature(get_many_mut)]

View File

@ -1,27 +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)]
#![allow(incomplete_features)]
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

@ -11,7 +11,7 @@
#![feature(round_ties_even)]
#![feature(let_chains)]
#![feature(lint_reasons)]
#![feature(trait_upcasting)]
#![cfg_attr(bootstrap, feature(trait_upcasting))]
// Configure clippy and other lints
#![allow(
clippy::collapsible_else_if,

View File

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

View File

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

View File

@ -1,6 +1,3 @@
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
fn main() {
basic();
diamond();

View File

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

View File

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

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
--> $DIR/no-unsize-coerce-dyn-trait.rs:1: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

View File

@ -1,6 +1,6 @@
// known-bug: #104800
#![feature(dyn_star, trait_upcasting)]
#![feature(dyn_star)]
trait Foo: Bar {
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
--> $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

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,13 +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: required when coercing `&dyn Bar` into `&dyn Foo`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

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

View File

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

View File

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

View File

@ -1,7 +1,5 @@
// compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> {}

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/upcast-wrong-substs.rs:11:30
--> $DIR/upcast-wrong-substs.rs:9:30
|
LL | let y: &dyn Bar<usize> = x;
| --------------- ^ expected trait `Bar`, found trait `Foo`

View File

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

View File

@ -1,5 +1,5 @@
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 {
| ------ expected `&dyn B` because of return type

View File

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

View File

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

View File

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

View File

@ -0,0 +1,14 @@
warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/deref-lint-regions.rs:8:1
|
LL | impl<'a> Deref for dyn Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | type Target = dyn Bar<'a>;
| -------------------------- target type is a supertrait of `dyn Foo<'_>`
|
= help: consider removing this implementation or replacing it with a method instead
= note: `#[warn(deref_into_dyn_supertrait)]` on by default
warning: 1 warning emitted

View File

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

View File

@ -0,0 +1,14 @@
warning: this `Deref` implementation is covered by an implicit supertrait coercion
--> $DIR/deref-lint.rs:9:1
|
LL | impl<'a> Deref for dyn 'a + B {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | type Target = dyn A;
| -------------------- target type is a supertrait of `dyn B`
|
= help: consider removing this implementation or replacing it with a method instead
= note: `#[warn(deref_into_dyn_supertrait)]` on by default
warning: 1 warning emitted

View File

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

View File

@ -3,8 +3,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)]
trait A: B {
type Assoc;
}

View File

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

View File

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

View File

@ -1,8 +1,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)]
trait Super {
type Assoc;
}

View File

@ -1,5 +1,4 @@
#![deny(deref_into_dyn_supertrait)]
#![feature(trait_upcasting)] // remove this and the test compiles
use std::ops::Deref;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +0,0 @@
error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
--> $DIR/issue-11515.rs:10: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: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,13 +0,0 @@
error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental
--> $DIR/issue-11515.rs:10: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: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,3 +1,4 @@
// check-pass
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
@ -7,5 +8,5 @@ struct Test {
fn main() {
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
#![feature(trait_upcasting)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
10

View File

@ -1,19 +0,0 @@
error: `dyn Foo<'_>` implements `Deref` with supertrait `Bar<'_>` as target
--> $DIR/migrate-lint-deny-regions.rs:8:1
|
LL | impl<'a> Deref for dyn Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | type Target = dyn Bar<'a>;
| -------------------------- target type is set here
|
= 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-regions.rs:1:9
|
LL | #![deny(deref_into_dyn_supertrait)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -1,19 +0,0 @@
error: `dyn B` implements `Deref` with supertrait `A` as target
--> $DIR/migrate-lint-deny.rs:9:1
|
LL | impl<'a> Deref for dyn 'a + B {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | type Target = dyn A;
| -------------------- target type is set here
|
= 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 previous error

View File

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

View File

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

View File

@ -3,8 +3,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)]
trait Mirror {
type Assoc;
}

View File

@ -1,7 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
trait A {
fn foo_a(&self);
}

View File

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

View File

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

View File

@ -1,64 +1,64 @@
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();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:27:1
--> $DIR/subtrait-method.rs:25:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:57:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:15:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:59:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:17:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
--> $DIR/subtrait-method.rs:61:9
|
LL | foo.c();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:27:1
--> $DIR/subtrait-method.rs:25:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
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();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:17:1
--> $DIR/subtrait-method.rs:15:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
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();
| ^ help: there is a method with a similar name: `a`
|
= 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
--> $DIR/subtrait-method.rs:27:1
--> $DIR/subtrait-method.rs:25:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^

View File

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:19:13
--> $DIR/type-checking-test-1.rs:17:13
|
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

View File

@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
--> $DIR/type-checking-test-1.rs:19:13
--> $DIR/type-checking-test-1.rs:17:13
|
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

View File

@ -1,8 +1,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(trait_upcasting)]
trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> {
fn bar(&self) -> Option<T> {

View File

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

View File

@ -1,11 +1,11 @@
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
| ^^^^^^^^^^^^^^^^^^ 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<_>`
--> $DIR/type-checking-test-2.rs:24:13
--> $DIR/type-checking-test-2.rs:22:13
|
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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:15:13
--> $DIR/type-checking-test-4.rs:13:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:20:13
--> $DIR/type-checking-test-4.rs:18:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- 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`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:26:5
--> $DIR/type-checking-test-4.rs:24:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -24,7 +24,7 @@ LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:31:5
--> $DIR/type-checking-test-4.rs:29:5
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:36:5
--> $DIR/type-checking-test-4.rs:34:5
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/type-checking-test-4.rs:44:5
--> $DIR/type-checking-test-4.rs:42:5
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here

View File

@ -1,13 +0,0 @@
error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
--> $DIR/upcast-through-struct-tail.rs:10: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: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,13 +0,0 @@
error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
--> $DIR/upcast-through-struct-tail.rs:10: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: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

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