diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 7e1f35627e3..27643e715e6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -176,7 +176,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .in_definition_order() // We only care about associated types. .filter(|item| item.kind == ty::AssocKind::Type) - // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. + // No RPITITs -- they're not dyn-compatible for now. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, // we do not need to constrain the associated type. diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index b99148f3368..980d20f9d3b 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -712,10 +712,7 @@ impl<'tcx> Instance<'tcx> { .. }) ); - // We also need to generate a shim if this is an AFIT. - let needs_rpitit_shim = - tcx.return_position_impl_trait_in_trait_shim_data(def).is_some(); - if needs_track_caller_shim || needs_rpitit_shim { + if needs_track_caller_shim { if tcx.is_closure_like(def) { debug!( " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a508487c796..fc439416a1a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -149,7 +149,6 @@ mod opaque_types; mod parameterized; mod predicate; mod region; -mod return_position_impl_trait_in_trait; mod rvalue_scopes; mod structural_impls; #[allow(hidden_glob_reexports)] diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs deleted file mode 100644 index 568e504b940..00000000000 --- a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs +++ /dev/null @@ -1,95 +0,0 @@ -use rustc_hir::def_id::DefId; - -use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt}; - -impl<'tcx> TyCtxt<'tcx> { - /// Given a `def_id` of a trait or impl method, compute whether that method needs to - /// have an RPITIT shim applied to it for it to be dyn compatible. If so, return the - /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT. - /// - /// NOTE that these args are not, in general, the same as than the RPITIT's args. They - /// are a subset of those args, since they do not include the late-bound lifetimes of - /// the RPITIT. Depending on the context, these will need to be dealt with in different - /// ways -- in codegen, it's okay to fill them with ReErased. - pub fn return_position_impl_trait_in_trait_shim_data( - self, - def_id: DefId, - ) -> Option<(DefId, ty::EarlyBinder<'tcx, ty::GenericArgsRef<'tcx>>)> { - let assoc_item = self.opt_associated_item(def_id)?; - - let (trait_item_def_id, opt_impl_def_id) = match assoc_item.container { - ty::AssocItemContainer::Impl => { - (assoc_item.trait_item_def_id?, Some(self.parent(def_id))) - } - ty::AssocItemContainer::Trait => (def_id, None), - }; - - let sig = self.fn_sig(trait_item_def_id); - - // Check if the trait returns an RPITIT. - let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = - *sig.skip_binder().skip_binder().output().kind() - else { - return None; - }; - if !self.is_impl_trait_in_trait(def_id) { - return None; - } - - let args = if let Some(impl_def_id) = opt_impl_def_id { - // Rebase the args from the RPITIT onto the impl trait ref, so we can later - // substitute them with the method args of the *impl* method, since that's - // the instance we're building a vtable shim for. - ty::GenericArgs::identity_for_item(self, trait_item_def_id).rebase_onto( - self, - self.parent(trait_item_def_id), - self.impl_trait_ref(impl_def_id) - .expect("expected impl trait ref from parent of impl item") - .instantiate_identity() - .args, - ) - } else { - // This is when we have a default trait implementation. - ty::GenericArgs::identity_for_item(self, trait_item_def_id) - }; - - Some((def_id, ty::EarlyBinder::bind(args))) - } - - /// Given a `DefId` of an RPITIT and its args, return the existential predicates - /// that corresponds to the RPITIT's bounds with the self type erased. - pub fn item_bounds_to_existential_predicates( - self, - def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> &'tcx ty::List> { - let mut bounds: Vec<_> = self - .item_self_bounds(def_id) - .iter_instantiated(self, args) - .filter_map(|clause| { - clause - .kind() - .map_bound(|clause| match clause { - ty::ClauseKind::Trait(trait_pred) => Some(ty::ExistentialPredicate::Trait( - ty::ExistentialTraitRef::erase_self_ty(self, trait_pred.trait_ref), - )), - ty::ClauseKind::Projection(projection_pred) => { - Some(ty::ExistentialPredicate::Projection( - ty::ExistentialProjection::erase_self_ty(self, projection_pred), - )) - } - ty::ClauseKind::TypeOutlives(_) => { - // Type outlives bounds don't really turn into anything, - // since we must use an intersection region for the `dyn*`'s - // region anyways. - None - } - _ => unreachable!("unexpected clause in item bounds: {clause:?}"), - }) - .transpose() - }) - .collect(); - bounds.sort_by(|a, b| a.skip_binder().stable_cmp(self, &b.skip_binder())); - self.mk_poly_existential_predicates(&bounds) - } -} diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 34074a84e28..c9771467e49 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -8,7 +8,6 @@ use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::*; use rustc_middle::query::Providers; -use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, }; @@ -718,12 +717,6 @@ fn build_call_shim<'tcx>( let def_id = instance.def_id(); - let rpitit_shim = if let ty::InstanceKind::ReifyShim(..) = instance { - tcx.return_position_impl_trait_in_trait_shim_data(def_id) - } else { - None - }; - let sig = tcx.fn_sig(def_id); let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); @@ -779,30 +772,7 @@ fn build_call_shim<'tcx>( let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo::outermost(span); - let mut destination = Place::return_place(); - if let Some((rpitit_def_id, fn_args)) = rpitit_shim { - let rpitit_args = - fn_args.instantiate_identity().extend_to(tcx, rpitit_def_id, |param, _| { - match param.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Type { .. } - | ty::GenericParamDefKind::Const { .. } => { - unreachable!("rpitit should have no addition ty/ct") - } - } - }); - let dyn_star_ty = Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), - tcx.lifetimes.re_erased, - ty::DynStar, - ); - destination = local_decls.push(local_decls[RETURN_PLACE].clone()).into(); - local_decls[RETURN_PLACE].ty = dyn_star_ty; - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - *inputs_and_output.last_mut().unwrap() = dyn_star_ty; - sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); - } + let destination = Place::return_place(); let rcvr_place = || { assert!(rcvr_adjustment.is_some()); @@ -921,23 +891,7 @@ fn build_call_shim<'tcx>( ); } // BB #1/#2 - return - // NOTE: If this is an RPITIT in dyn, we also want to coerce - // the return type of the function into a `dyn*`. - let stmts = if rpitit_shim.is_some() { - vec![Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - Place::return_place(), - Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::DynStar, CoercionSource::Implicit), - Operand::Move(destination), - sig.output(), - ), - ))), - }] - } else { - vec![] - }; + let stmts = vec![]; block(&mut blocks, stmts, TerminatorKind::Return, false); if let Some(Adjustment::RefMut) = rcvr_adjustment { // BB #3 - drop if closure panics diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 3fceada2510..78a45243983 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -9,7 +9,6 @@ use std::ops::ControlFlow; use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -807,31 +806,8 @@ fn contains_illegal_impl_trait_in_trait<'tcx>( let ty = tcx.liberate_late_bound_regions(fn_def_id, ty); if tcx.asyncness(fn_def_id).is_async() { - // FIXME(async_fn_in_dyn_trait): Think of a better way to unify these code paths - // to issue an appropriate feature suggestion when users try to use AFIDT. - // Obviously we must only do this once AFIDT is finished enough to actually be usable. - if tcx.features().async_fn_in_dyn_trait() { - let ty::Alias(ty::Projection, proj) = *ty.kind() else { - bug!("expected async fn in trait to return an RPITIT"); - }; - assert!(tcx.is_impl_trait_in_trait(proj.def_id)); - - // FIXME(async_fn_in_dyn_trait): We should check that this bound is legal too, - // and stop relying on `async fn` in the definition. - for bound in tcx.item_bounds(proj.def_id).instantiate(tcx, proj.args) { - if let Some(violation) = bound - .visit_with(&mut IllegalRpititVisitor { tcx, allowed: Some(proj) }) - .break_value() - { - return Some(violation); - } - } - - None - } else { - // Rendering the error as a separate `async-specific` message is better. - Some(MethodViolationCode::AsyncFn) - } + // Rendering the error as a separate `async-specific` message is better. + Some(MethodViolationCode::AsyncFn) } else { ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value() } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 2c60be63bd5..6057b66c483 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; -use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin}; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -18,8 +18,6 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::sym; -use rustc_type_ir::elaborate; -use thin_vec::thin_vec; use tracing::{debug, instrument}; use super::{ @@ -63,9 +61,6 @@ enum ProjectionCandidate<'tcx> { /// Bounds specified on an object type Object(ty::PolyProjectionPredicate<'tcx>), - /// Built-in bound for a dyn async fn in trait - ObjectRpitit, - /// From an "impl" (or a "pseudo-impl" returned by select) Select(Selection<'tcx>), } @@ -832,16 +827,6 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( env_predicates, false, ); - - // `dyn Trait` automagically project their AFITs to `dyn* Future`. - if tcx.is_impl_trait_in_trait(obligation.predicate.def_id) - && let Some(out_trait_def_id) = data.principal_def_id() - && let rpitit_trait_def_id = tcx.parent(obligation.predicate.def_id) - && elaborate::supertrait_def_ids(tcx, out_trait_def_id) - .any(|trait_def_id| trait_def_id == rpitit_trait_def_id) - { - candidate_set.push_candidate(ProjectionCandidate::ObjectRpitit); - } } #[instrument( @@ -1273,8 +1258,6 @@ fn confirm_candidate<'cx, 'tcx>( ProjectionCandidate::Select(impl_source) => { confirm_select_candidate(selcx, obligation, impl_source) } - - ProjectionCandidate::ObjectRpitit => confirm_object_rpitit_candidate(selcx, obligation), }; // When checking for cycle during evaluation, we compare predicates with @@ -2070,45 +2053,6 @@ fn confirm_impl_candidate<'cx, 'tcx>( } } -fn confirm_object_rpitit_candidate<'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTermObligation<'tcx>, -) -> Progress<'tcx> { - let tcx = selcx.tcx(); - let mut obligations = thin_vec![]; - - // Compute an intersection lifetime for all the input components of this GAT. - let intersection = - selcx.infcx.next_region_var(RegionVariableOrigin::MiscVariable(obligation.cause.span)); - for component in obligation.predicate.args { - match component.unpack() { - ty::GenericArgKind::Lifetime(lt) => { - obligations.push(obligation.with(tcx, ty::OutlivesPredicate(lt, intersection))); - } - ty::GenericArgKind::Type(ty) => { - obligations.push(obligation.with(tcx, ty::OutlivesPredicate(ty, intersection))); - } - ty::GenericArgKind::Const(_ct) => { - // Consts have no outlives... - } - } - } - - Progress { - term: Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates( - obligation.predicate.def_id, - obligation.predicate.args, - ), - intersection, - ty::DynStar, - ) - .into(), - obligations, - } -} - // Get obligations corresponding to the predicates from the where-clause of the // associated type itself. fn assoc_ty_own_obligations<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4cd6781ab89..4404324d5cd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -616,12 +616,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for assoc_type in assoc_types { let defs: &ty::Generics = tcx.generics_of(assoc_type); - // When `async_fn_in_dyn_trait` is enabled, we don't need to check the - // RPITIT for compatibility, since it's not provided by the user. - if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) { - continue; - } - if !defs.own_params.is_empty() { tcx.dcx().span_delayed_bug( obligation.cause.span, diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a726ebae6fe..48d5a4a0fcb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -55,31 +55,6 @@ fn fn_sig_for_fn_abi<'tcx>( sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } - // Modify `fn() -> impl Future` to `fn() -> dyn* Future`. - if let ty::InstanceKind::ReifyShim(def_id, _) = instance.def - && let Some((rpitit_def_id, fn_args)) = - tcx.return_position_impl_trait_in_trait_shim_data(def_id) - { - let fn_args = fn_args.instantiate(tcx, args); - let rpitit_args = - fn_args.extend_to(tcx, rpitit_def_id, |param, _| match param.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Type { .. } - | ty::GenericParamDefKind::Const { .. } => { - unreachable!("rpitit should have no addition ty/ct") - } - }); - let dyn_star_ty = Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), - tcx.lifetimes.re_erased, - ty::DynStar, - ); - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - *inputs_and_output.last_mut().unwrap() = dyn_star_ty; - sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); - } - sig } ty::Closure(def_id, args) => { diff --git a/tests/crashes/136286.rs b/tests/crashes/136286.rs deleted file mode 100644 index f0ea14bd167..00000000000 --- a/tests/crashes/136286.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #136286 -//@ compile-flags: --edition=2024 - -#![feature(async_fn_in_dyn_trait)] -trait A { - async fn b(self: A); -} diff --git a/tests/crashes/137706.rs b/tests/crashes/137706.rs deleted file mode 100644 index 0b46f9c237a..00000000000 --- a/tests/crashes/137706.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #137706 -//@ needs-rustc-debug-assertions -trait A { - fn b() -> impl IntoIterator; -} - -impl A<()> for dyn A {} diff --git a/tests/crashes/137895.rs b/tests/crashes/137895.rs deleted file mode 100644 index bb624d2e9fa..00000000000 --- a/tests/crashes/137895.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #137895 -trait A { - fn b() -> impl ?Sized + 'a; -} - -impl A for dyn A {} diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.rs b/tests/ui/async-await/dyn/mut-is-pointer-like.rs index 93e8281164c..a82567e372e 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.rs +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.rs @@ -1,11 +1,9 @@ //@ aux-build:block-on.rs //@ edition: 2021 -//@ run-pass -//@ check-run-results +//@ known-bug: #133119 #![allow(refining_impl_trait)] #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete extern crate block_on; diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr index 7c72ce43cf0..bf20473924b 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mut-is-pointer-like.rs:7:12 + --> $DIR/mut-is-pointer-like.rs:6:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,5 +7,65 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:35:16 + | +LL | let x: Pin<&mut dyn AsyncTrait> = f; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:35:56 + | +LL | let x: Pin<&mut dyn AsyncTrait> = f; + | ^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = note: required for the cast from `Pin<&mut {async block@$DIR/mut-is-pointer-like.rs:32:32: 32:37}>` to `Pin<&mut dyn AsyncTrait>` + +error[E0277]: the trait bound `dyn AsyncTrait: AsyncTrait` is not satisfied + --> $DIR/mut-is-pointer-like.rs:36:11 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^ the trait `AsyncTrait` is not implemented for `dyn AsyncTrait` + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:36:9 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/works.rs b/tests/ui/async-await/dyn/works.rs index 0732a3ee2f2..f406a7b593f 100644 --- a/tests/ui/async-await/dyn/works.rs +++ b/tests/ui/async-await/dyn/works.rs @@ -1,11 +1,9 @@ //@ aux-build:block-on.rs //@ edition: 2021 -//@ run-pass -//@ check-run-results +//@ known-bug: #133119 #![allow(refining_impl_trait)] #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete extern crate block_on; diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr index 2c7db7c32f5..47abeab5aac 100644 --- a/tests/ui/async-await/dyn/works.stderr +++ b/tests/ui/async-await/dyn/works.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/works.rs:7:12 + --> $DIR/works.rs:6:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,5 +7,75 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:27:34 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + = note: required for the cast from `&&'static str` to `&dyn AsyncTrait` +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:27:16 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:28:11 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:28:9 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/wrong-size.rs b/tests/ui/async-await/dyn/wrong-size.rs index ac15dd26067..f5fce3648ac 100644 --- a/tests/ui/async-await/dyn/wrong-size.rs +++ b/tests/ui/async-await/dyn/wrong-size.rs @@ -1,7 +1,7 @@ //@ edition: 2021 +//@ known-bug: #133119 #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete use std::future::Future; @@ -19,5 +19,5 @@ impl AsyncTrait for &'static str { fn main() { let x: &dyn AsyncTrait = &"hello, world!"; - //~^ ERROR `impl Future` needs to have the same ABI as a pointer + // FIXME ~^ ERROR `impl Future` needs to have the same ABI as a pointer } diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr index 0202b5f2409..b4684f4fc17 100644 --- a/tests/ui/async-await/dyn/wrong-size.stderr +++ b/tests/ui/async-await/dyn/wrong-size.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-size.rs:3:12 + --> $DIR/wrong-size.rs:4:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,15 +7,41 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: `impl Future` needs to have the same ABI as a pointer +error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/wrong-size.rs:21:30 | LL | let x: &dyn AsyncTrait = &"hello, world!"; - | ^^^^^^^^^^^^^^^^ `impl Future` needs to be a pointer-like type + | ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible | - = help: the trait `for<'a> PointerLike` is not implemented for `impl Future` +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/wrong-size.rs:9:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. = note: required for the cast from `&&'static str` to `&dyn AsyncTrait` -error: aborting due to 1 previous error; 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/wrong-size.rs:21:12 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/wrong-size.rs:9:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0038`.