about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-03-18 16:17:18 +0000
committerMichael Goulet <michael@errs.io>2025-03-18 17:35:26 +0000
commit93b31d9b21f5a7066cba65ecbf85f2ef16dec891 (patch)
tree94c6676930328bffb770b7534629f61ac121cd9a
parent75530e9f72a1990ed2305e16fd51d02f47048f12 (diff)
downloadrust-93b31d9b21f5a7066cba65ecbf85f2ef16dec891.tar.gz
rust-93b31d9b21f5a7066cba65ecbf85f2ef16dec891.zip
Remove existing AFIDT implementation
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs5
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs95
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs50
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs6
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs25
-rw-r--r--tests/crashes/136286.rs7
-rw-r--r--tests/crashes/137706.rs7
-rw-r--r--tests/crashes/137895.rs6
-rw-r--r--tests/ui/async-await/dyn/mut-is-pointer-like.rs4
-rw-r--r--tests/ui/async-await/dyn/mut-is-pointer-like.stderr64
-rw-r--r--tests/ui/async-await/dyn/works.rs4
-rw-r--r--tests/ui/async-await/dyn/works.stderr74
-rw-r--r--tests/ui/async-await/dyn/wrong-size.rs4
-rw-r--r--tests/ui/async-await/dyn/wrong-size.stderr38
18 files changed, 177 insertions, 301 deletions
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<ty::PolyExistentialPredicate<'tcx>> {
-        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<Item = ()>;
-}
-
-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 <https://github.com/rust-lang/rust/issues/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<Output = ()>> = 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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<Output = ()>> = 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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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<Output = ()>>`
+
+error[E0277]: the trait bound `dyn AsyncTrait<Output = ()>: 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<Output = ()>`
+
+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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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 <https://github.com/rust-lang/rust/issues/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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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<Output = ()>` needs to have the same ABI as a pointer
+    // FIXME ~^ ERROR `impl Future<Output = ()>` 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 <https://github.com/rust-lang/rust/issues/133119> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0277]: `impl Future<Output = ()>` 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<Output = ()>` needs to be a pointer-like type
+   |                              ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
    |
-   = help: the trait `for<'a> PointerLike` is not implemented for `impl Future<Output = ()>`
+note: for a trait to be dyn compatible it needs to allow building a vtable
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $DIR/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 <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $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.
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0038`.