mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 13:06:49 +00:00
Remove existing AFIDT implementation
This commit is contained in:
parent
75530e9f72
commit
93b31d9b21
@ -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.
|
||||
|
@ -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 {:?} {:?}",
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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>(
|
||||
|
@ -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,
|
||||
|
@ -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) => {
|
||||
|
@ -1,7 +0,0 @@
|
||||
//@ known-bug: #136286
|
||||
//@ compile-flags: --edition=2024
|
||||
|
||||
#![feature(async_fn_in_dyn_trait)]
|
||||
trait A {
|
||||
async fn b(self: A);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
//@ known-bug: #137706
|
||||
//@ needs-rustc-debug-assertions
|
||||
trait A {
|
||||
fn b() -> impl IntoIterator<Item = ()>;
|
||||
}
|
||||
|
||||
impl A<()> for dyn A {}
|
@ -1,6 +0,0 @@
|
||||
//@ known-bug: #137895
|
||||
trait A {
|
||||
fn b() -> impl ?Sized + 'a;
|
||||
}
|
||||
|
||||
impl A for dyn A {}
|
@ -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;
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
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`.
|
||||
|
Loading…
Reference in New Issue
Block a user