Auto merge of #144458 - compiler-errors:no-witness-mini, r=lcnr
Remove the witness type from coroutine *args* (without actually removing the type) This does as much of rust-lang/rust#144157 as we can without having to break rust-lang/rust#143545 and/or introduce some better way of handling higher ranked assumptions. Namely, it: * Stalls coroutines based off of the *coroutine* type rather than the witness type. * Reworks the dtorck constraint hack to not rely on the witness type. * Removes the witness type from the args of the coroutine, eagerly creating the type for nested obligations when needed (auto/clone impls). I'll experiment with actually removing the witness type in a follow-up. r? lcnr
This commit is contained in:
@@ -86,7 +86,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// them with fresh ty vars.
|
||||
resume_ty: next_ty_var(),
|
||||
yield_ty: next_ty_var(),
|
||||
witness: next_ty_var(),
|
||||
},
|
||||
)
|
||||
.args,
|
||||
|
||||
@@ -379,20 +379,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
// for info on the usage of each of these fields.
|
||||
let dummy_args = match kind {
|
||||
ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
|
||||
ClosureKind::Coroutine(_) => &[
|
||||
"<coroutine_kind>",
|
||||
"<resume_ty>",
|
||||
"<yield_ty>",
|
||||
"<return_ty>",
|
||||
"<witness>",
|
||||
"<upvars>",
|
||||
][..],
|
||||
ClosureKind::Coroutine(_) => {
|
||||
&["<coroutine_kind>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
|
||||
}
|
||||
ClosureKind::CoroutineClosure(_) => &[
|
||||
"<closure_kind>",
|
||||
"<closure_signature_parts>",
|
||||
"<upvars>",
|
||||
"<bound_captures_by_ref>",
|
||||
"<witness>",
|
||||
][..],
|
||||
};
|
||||
|
||||
|
||||
@@ -161,8 +161,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Resume type defaults to `()` if the coroutine has no argument.
|
||||
let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit);
|
||||
|
||||
let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args);
|
||||
|
||||
// Coroutines that come from coroutine closures have not yet determined
|
||||
// their kind ty, so make a fresh infer var which will be constrained
|
||||
// later during upvar analysis. Regular coroutines always have the kind
|
||||
@@ -182,7 +180,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
return_ty: liberated_sig.output(),
|
||||
witness: interior,
|
||||
tupled_upvars_ty,
|
||||
},
|
||||
);
|
||||
@@ -210,7 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
// Compute all of the variables that will be used to populate the coroutine.
|
||||
let resume_ty = self.next_ty_var(expr_span);
|
||||
let interior = self.next_ty_var(expr_span);
|
||||
|
||||
let closure_kind_ty = match expected_kind {
|
||||
Some(kind) => Ty::from_closure_kind(tcx, kind),
|
||||
@@ -243,7 +239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
),
|
||||
tupled_upvars_ty,
|
||||
coroutine_captures_by_ref_ty,
|
||||
coroutine_witness_ty: interior,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -96,14 +96,12 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
|
||||
signature_parts_ty,
|
||||
tupled_upvars_ty,
|
||||
coroutine_captures_by_ref_ty,
|
||||
coroutine_witness_ty,
|
||||
] => ty::CoroutineClosureArgsParts {
|
||||
parent_args,
|
||||
closure_kind_ty: closure_kind_ty.expect_ty(),
|
||||
signature_parts_ty: signature_parts_ty.expect_ty(),
|
||||
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
|
||||
coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
|
||||
coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
|
||||
},
|
||||
_ => bug!("closure args missing synthetics"),
|
||||
}
|
||||
@@ -111,23 +109,16 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
|
||||
|
||||
fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
|
||||
match self[..] {
|
||||
[
|
||||
ref parent_args @ ..,
|
||||
kind_ty,
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
return_ty,
|
||||
witness,
|
||||
tupled_upvars_ty,
|
||||
] => ty::CoroutineArgsParts {
|
||||
[ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
|
||||
ty::CoroutineArgsParts {
|
||||
parent_args,
|
||||
kind_ty: kind_ty.expect_ty(),
|
||||
resume_ty: resume_ty.expect_ty(),
|
||||
yield_ty: yield_ty.expect_ty(),
|
||||
return_ty: return_ty.expect_ty(),
|
||||
witness: witness.expect_ty(),
|
||||
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => bug!("coroutine args missing synthetics"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,9 +913,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
" yield_ty=",
|
||||
print(args.as_coroutine().yield_ty()),
|
||||
" return_ty=",
|
||||
print(args.as_coroutine().return_ty()),
|
||||
" witness=",
|
||||
print(args.as_coroutine().witness())
|
||||
print(args.as_coroutine().return_ty())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1035,9 +1033,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
" upvar_tys=",
|
||||
print(args.as_coroutine_closure().tupled_upvars_ty()),
|
||||
" coroutine_captures_by_ref_ty=",
|
||||
print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
|
||||
" coroutine_witness_ty=",
|
||||
print(args.as_coroutine_closure().coroutine_witness_ty())
|
||||
print(args.as_coroutine_closure().coroutine_captures_by_ref_ty())
|
||||
);
|
||||
}
|
||||
p!("}}");
|
||||
|
||||
@@ -75,9 +75,16 @@ where
|
||||
Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
ty::Coroutine(def_id, args) => {
|
||||
let coroutine_args = args.as_coroutine();
|
||||
Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
|
||||
Ok(ty::Binder::dummy(vec![
|
||||
coroutine_args.tupled_upvars_ty(),
|
||||
Ty::new_coroutine_witness(
|
||||
ecx.cx(),
|
||||
def_id,
|
||||
ecx.cx().mk_args(coroutine_args.parent_args().as_slice()),
|
||||
),
|
||||
]))
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||
@@ -245,7 +252,14 @@ where
|
||||
Movability::Movable => {
|
||||
if ecx.cx().features().coroutine_clone() {
|
||||
let coroutine = args.as_coroutine();
|
||||
Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
|
||||
Ok(ty::Binder::dummy(vec![
|
||||
coroutine.tupled_upvars_ty(),
|
||||
Ty::new_coroutine_witness(
|
||||
ecx.cx(),
|
||||
def_id,
|
||||
ecx.cx().mk_args(coroutine.parent_args().as_slice()),
|
||||
),
|
||||
]))
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ where
|
||||
}
|
||||
|
||||
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
|
||||
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
|
||||
if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
|
||||
return cand;
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ where
|
||||
}
|
||||
|
||||
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
|
||||
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
|
||||
if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
|
||||
return cand;
|
||||
}
|
||||
|
||||
@@ -1432,11 +1432,8 @@ where
|
||||
self.merge_trait_candidates(candidates)
|
||||
}
|
||||
|
||||
fn try_stall_coroutine_witness(
|
||||
&mut self,
|
||||
self_ty: I::Ty,
|
||||
) -> Option<Result<Candidate<I>, NoSolution>> {
|
||||
if let ty::CoroutineWitness(def_id, _) = self_ty.kind() {
|
||||
fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> {
|
||||
if let ty::Coroutine(def_id, _) = self_ty.kind() {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Analysis {
|
||||
defining_opaque_types_and_generators: stalled_generators,
|
||||
|
||||
@@ -355,7 +355,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
|
||||
if let ty::CoroutineWitness(def_id, _) = *ty.kind()
|
||||
if let ty::Coroutine(def_id, _) = *ty.kind()
|
||||
&& def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
|
||||
{
|
||||
ControlFlow::Break(())
|
||||
|
||||
@@ -318,7 +318,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
})
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
ty::Coroutine(def_id, args) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
// in the interior, and sit idle when coroutine yields
|
||||
// (and is subsequently dropped).
|
||||
@@ -346,7 +346,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
// While we conservatively assume that all coroutines require drop
|
||||
// to avoid query cycles during MIR building, we can check the actual
|
||||
// witness during borrowck to avoid unnecessary liveness constraints.
|
||||
if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) {
|
||||
let typing_env = tcx.erase_regions(typing_env);
|
||||
if tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
|
||||
witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
|
||||
}) {
|
||||
constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
|
||||
constraints.outlives.push(args.resume_ty().into());
|
||||
}
|
||||
|
||||
@@ -794,9 +794,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// The auto impl might apply; we don't know.
|
||||
candidates.ambiguous = true;
|
||||
}
|
||||
ty::Coroutine(coroutine_def_id, _)
|
||||
if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
|
||||
{
|
||||
ty::Coroutine(coroutine_def_id, _) => {
|
||||
if self.tcx().is_lang_item(def_id, LangItem::Unpin) {
|
||||
match self.tcx().coroutine_movability(coroutine_def_id) {
|
||||
hir::Movability::Static => {
|
||||
// Immovable coroutines are never `Unpin`, so
|
||||
@@ -804,10 +803,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
hir::Movability::Movable => {
|
||||
// Movable coroutines are always `Unpin`, so add an
|
||||
// unconditional builtin candidate.
|
||||
// unconditional builtin candidate with no sub-obligations.
|
||||
candidates.vec.push(BuiltinCandidate);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if self.should_stall_coroutine(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
// Coroutines implement all other auto traits normally.
|
||||
candidates.vec.push(AutoImplCandidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
@@ -842,13 +849,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
ty::CoroutineWitness(..) => {
|
||||
candidates.vec.push(AutoImplCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
@@ -866,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::UnsafeBinder(_) => {
|
||||
@@ -1153,15 +1155,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ty::Ref(_, _, hir::Mutability::Mut) => {}
|
||||
|
||||
ty::Coroutine(coroutine_def_id, args) => {
|
||||
if self.should_stall_coroutine(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
return;
|
||||
}
|
||||
|
||||
match self.tcx().coroutine_movability(coroutine_def_id) {
|
||||
hir::Movability::Static => {}
|
||||
hir::Movability::Movable => {
|
||||
if self.tcx().features().coroutine_clone() {
|
||||
let resolved_upvars =
|
||||
self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
|
||||
let resolved_witness =
|
||||
self.infcx.shallow_resolve(args.as_coroutine().witness());
|
||||
if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
|
||||
if resolved_upvars.is_ty_var() {
|
||||
// Not yet resolved.
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
@@ -1194,13 +1199,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(coroutine_def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
ty::CoroutineWitness(..) => {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to whatever user-defined impls or param-env clauses exist in this case.
|
||||
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {}
|
||||
@@ -1238,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
@@ -1247,14 +1247,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(coroutine_def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(coroutine_def_id) {
|
||||
ty::Coroutine(coroutine_def_id, _) => {
|
||||
if self.should_stall_coroutine(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(..) => {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
|
||||
// Conditionally `Sized`.
|
||||
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
|
||||
@@ -2196,7 +2196,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
args.as_coroutine()
|
||||
.upvar_tys()
|
||||
.iter()
|
||||
.chain([args.as_coroutine().witness()])
|
||||
.chain([Ty::new_coroutine_witness(
|
||||
self.tcx(),
|
||||
coroutine_def_id,
|
||||
self.tcx().mk_args(args.as_coroutine().parent_args()),
|
||||
)])
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
} else {
|
||||
@@ -2327,9 +2331,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
ty::Binder::dummy(AutoImplConstituents { types: vec![ty], assumptions: vec![] })
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
ty::Coroutine(def_id, args) => {
|
||||
let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
|
||||
let witness = args.as_coroutine().witness();
|
||||
let witness = Ty::new_coroutine_witness(
|
||||
self.tcx(),
|
||||
def_id,
|
||||
self.tcx().mk_args(args.as_coroutine().parent_args()),
|
||||
);
|
||||
ty::Binder::dummy(AutoImplConstituents {
|
||||
types: [ty].into_iter().chain(iter::once(witness)).collect(),
|
||||
assumptions: vec![],
|
||||
@@ -2841,7 +2849,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
obligations
|
||||
}
|
||||
|
||||
fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
|
||||
fn should_stall_coroutine(&self, def_id: DefId) -> bool {
|
||||
match self.infcx.typing_mode() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
|
||||
def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
|
||||
|
||||
@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
|
||||
struct NeedsDropTypes<'tcx, F> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
/// Whether to reveal coroutine witnesses, this is set
|
||||
/// to `false` unless we compute `needs_drop` for a coroutine witness.
|
||||
reveal_coroutine_witnesses: bool,
|
||||
query_ty: Ty<'tcx>,
|
||||
seen_tys: FxHashSet<Ty<'tcx>>,
|
||||
/// A stack of types left to process, and the recursion depth when we
|
||||
@@ -115,6 +112,15 @@ struct NeedsDropTypes<'tcx, F> {
|
||||
adt_components: F,
|
||||
/// Set this to true if an exhaustive list of types involved in
|
||||
/// drop obligation is requested.
|
||||
// FIXME: Calling this bool `exhaustive` is confusing and possibly a footgun,
|
||||
// since it does two things: It makes the iterator yield *all* of the types
|
||||
// that need drop, and it also affects the computation of the drop components
|
||||
// on `Coroutine`s. The latter is somewhat confusing, and probably should be
|
||||
// a function of `typing_env`. See the HACK comment below for why this is
|
||||
// necessary. If this isn't possible, then we probably should turn this into
|
||||
// a `NeedsDropMode` so that we can have a variant like `CollectAllSignificantDrops`,
|
||||
// which will more accurately indicate that we want *all* of the *significant*
|
||||
// drops, which are the two important behavioral changes toggled by this bool.
|
||||
exhaustive: bool,
|
||||
}
|
||||
|
||||
@@ -131,7 +137,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
|
||||
Self {
|
||||
tcx,
|
||||
typing_env,
|
||||
reveal_coroutine_witnesses: exhaustive,
|
||||
seen_tys,
|
||||
query_ty: ty,
|
||||
unchecked_tys: vec![(ty, 0)],
|
||||
@@ -195,16 +200,14 @@ where
|
||||
// for the coroutine witness and check whether any of the contained types
|
||||
// need to be dropped, and only require the captured types to be live
|
||||
// if they do.
|
||||
ty::Coroutine(_, args) => {
|
||||
if self.reveal_coroutine_witnesses {
|
||||
queue_type(self, args.as_coroutine().witness());
|
||||
} else {
|
||||
return Some(self.always_drop_component(ty));
|
||||
ty::Coroutine(def_id, args) => {
|
||||
// FIXME: See FIXME on `exhaustive` field above.
|
||||
if self.exhaustive {
|
||||
for upvar in args.as_coroutine().upvar_tys() {
|
||||
queue_type(self, upvar);
|
||||
}
|
||||
}
|
||||
ty::CoroutineWitness(def_id, args) => {
|
||||
queue_type(self, args.as_coroutine().resume_ty());
|
||||
if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
|
||||
self.reveal_coroutine_witnesses = true;
|
||||
for field_ty in &witness.field_tys {
|
||||
queue_type(
|
||||
self,
|
||||
@@ -212,6 +215,12 @@ where
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Some(self.always_drop_component(ty));
|
||||
}
|
||||
}
|
||||
ty::CoroutineWitness(..) => {
|
||||
unreachable!("witness should be handled in parent");
|
||||
}
|
||||
|
||||
ty::UnsafeBinder(bound_ty) => {
|
||||
|
||||
@@ -131,10 +131,7 @@ bitflags::bitflags! {
|
||||
/// Does this have any binders with bound vars (e.g. that need to be anonymized)?
|
||||
const HAS_BINDER_VARS = 1 << 23;
|
||||
|
||||
/// Does this type have any coroutine witnesses in it?
|
||||
// FIXME: This should probably be changed to track whether the type has any
|
||||
// *coroutines* in it, though this will happen if we remove coroutine witnesses
|
||||
// altogether.
|
||||
/// Does this type have any coroutines in it?
|
||||
const HAS_TY_CORO = 1 << 24;
|
||||
}
|
||||
}
|
||||
@@ -246,11 +243,13 @@ impl<I: Interner> FlagComputation<I> {
|
||||
self.add_flags(TypeFlags::HAS_TY_PARAM);
|
||||
}
|
||||
|
||||
ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
|
||||
ty::Closure(_, args)
|
||||
| ty::CoroutineClosure(_, args)
|
||||
| ty::CoroutineWitness(_, args) => {
|
||||
self.add_args(args.as_slice());
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(_, args) => {
|
||||
ty::Coroutine(_, args) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_CORO);
|
||||
self.add_args(args.as_slice());
|
||||
}
|
||||
|
||||
@@ -101,7 +101,6 @@ use crate::{self as ty, Interner};
|
||||
/// `yield` inside the coroutine.
|
||||
/// * `GR`: The "return type", which is the type of value returned upon
|
||||
/// completion of the coroutine.
|
||||
/// * `GW`: The "coroutine witness".
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct ClosureArgs<I: Interner> {
|
||||
@@ -239,8 +238,6 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
|
||||
/// while the `tupled_upvars_ty`, representing the by-move version of the same
|
||||
/// captures, will be `(String,)`.
|
||||
pub coroutine_captures_by_ref_ty: I::Ty,
|
||||
/// Witness type returned by the generator produced by this coroutine-closure.
|
||||
pub coroutine_witness_ty: I::Ty,
|
||||
}
|
||||
|
||||
impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
@@ -251,7 +248,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
parts.signature_parts_ty.into(),
|
||||
parts.tupled_upvars_ty.into(),
|
||||
parts.coroutine_captures_by_ref_ty.into(),
|
||||
parts.coroutine_witness_ty.into(),
|
||||
])),
|
||||
}
|
||||
}
|
||||
@@ -292,7 +288,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
}
|
||||
|
||||
pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
|
||||
let interior = self.coroutine_witness_ty();
|
||||
let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
|
||||
sig_tys.map_bound(|sig_tys| {
|
||||
let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
|
||||
@@ -302,7 +297,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
panic!()
|
||||
};
|
||||
CoroutineClosureSignature {
|
||||
interior,
|
||||
tupled_inputs_ty,
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
@@ -318,10 +312,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
self.split().coroutine_captures_by_ref_ty
|
||||
}
|
||||
|
||||
pub fn coroutine_witness_ty(self) -> I::Ty {
|
||||
self.split().coroutine_witness_ty
|
||||
}
|
||||
|
||||
pub fn has_self_borrows(&self) -> bool {
|
||||
match self.coroutine_captures_by_ref_ty().kind() {
|
||||
ty::FnPtr(sig_tys, _) => sig_tys
|
||||
@@ -361,7 +351,6 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub struct CoroutineClosureSignature<I: Interner> {
|
||||
pub interior: I::Ty,
|
||||
pub tupled_inputs_ty: I::Ty,
|
||||
pub resume_ty: I::Ty,
|
||||
pub yield_ty: I::Ty,
|
||||
@@ -407,7 +396,6 @@ impl<I: Interner> CoroutineClosureSignature<I> {
|
||||
resume_ty: self.resume_ty,
|
||||
yield_ty: self.yield_ty,
|
||||
return_ty: self.return_ty,
|
||||
witness: self.interior,
|
||||
tupled_upvars_ty,
|
||||
},
|
||||
);
|
||||
@@ -587,11 +575,6 @@ pub struct CoroutineArgsParts<I: Interner> {
|
||||
pub yield_ty: I::Ty,
|
||||
pub return_ty: I::Ty,
|
||||
|
||||
/// The interior type of the coroutine.
|
||||
/// Represents all types that are stored in locals
|
||||
/// in the coroutine's body.
|
||||
pub witness: I::Ty,
|
||||
|
||||
/// The upvars captured by the closure. Remains an inference variable
|
||||
/// until the upvar analysis, which happens late in HIR typeck.
|
||||
pub tupled_upvars_ty: I::Ty,
|
||||
@@ -607,7 +590,6 @@ impl<I: Interner> CoroutineArgs<I> {
|
||||
parts.resume_ty.into(),
|
||||
parts.yield_ty.into(),
|
||||
parts.return_ty.into(),
|
||||
parts.witness.into(),
|
||||
parts.tupled_upvars_ty.into(),
|
||||
])),
|
||||
}
|
||||
@@ -629,15 +611,6 @@ impl<I: Interner> CoroutineArgs<I> {
|
||||
self.split().kind_ty
|
||||
}
|
||||
|
||||
/// This describes the types that can be contained in a coroutine.
|
||||
/// It will be a type variable initially and unified in the last stages of typeck of a body.
|
||||
/// It contains a tuple of all the types that could end up on a coroutine frame.
|
||||
/// The state transformation MIR pass may only produce layouts which mention types
|
||||
/// in this tuple. Upvars are not counted here.
|
||||
pub fn witness(self) -> I::Ty {
|
||||
self.split().witness
|
||||
}
|
||||
|
||||
/// Returns an iterator over the list of types of captured paths by the coroutine.
|
||||
/// In case there was a type error in figuring out the types of the captured path, an
|
||||
/// empty iterator is returned.
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
std::future::ResumeTy,
|
||||
(),
|
||||
(),
|
||||
CoroutineWitness(
|
||||
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
|
||||
[],
|
||||
),
|
||||
(),
|
||||
],
|
||||
),
|
||||
@@ -30,10 +26,6 @@
|
||||
std::future::ResumeTy,
|
||||
(),
|
||||
(),
|
||||
CoroutineWitness(
|
||||
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
|
||||
[],
|
||||
),
|
||||
(),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -5,11 +5,11 @@ LL | let x = async || {};
|
||||
| -- the expected `async` closure body
|
||||
LL |
|
||||
LL | let () = x();
|
||||
| ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
|
||||
| ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?15t> upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}`
|
||||
| |
|
||||
| expected `async` closure body, found `()`
|
||||
|
|
||||
= note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
|
||||
= note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?15t> upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}`
|
||||
found unit type `()`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -21,30 +21,6 @@ LL | Box::new(async { new(|| async { f().await }).await })
|
||||
= help: consider pinning your async block and casting it to a trait object
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/higher-ranked-auto-trait-6.rs:16:5
|
||||
|
|
||||
LL | Box::new(async { new(|| async { f().await }).await })
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
|
||||
found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
|
||||
= note: no two async blocks, even if identical, have the same type
|
||||
= help: consider pinning your async block and casting it to a trait object
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/higher-ranked-auto-trait-6.rs:16:5
|
||||
|
|
||||
LL | Box::new(async { new(|| async { f().await }).await })
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
|
||||
found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}`
|
||||
= note: no two async blocks, even if identical, have the same type
|
||||
= help: consider pinning your async block and casting it to a trait object
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::future::Future;
|
||||
fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
||||
//~^ ERROR future cannot be sent between threads safely
|
||||
async { (ty, ty1) }
|
||||
//~^ ERROR future cannot be sent between threads safely
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
error: future cannot be sent between threads safely
|
||||
--> $DIR/issue-70818.rs:6:5
|
||||
|
|
||||
LL | async { (ty, ty1) }
|
||||
| ^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
|
||||
|
|
||||
note: captured value is not `Send`
|
||||
--> $DIR/issue-70818.rs:6:18
|
||||
|
|
||||
LL | async { (ty, ty1) }
|
||||
| ^^^ has type `U` which is not `Send`
|
||||
note: required by a bound in an opaque type
|
||||
--> $DIR/issue-70818.rs:4:69
|
||||
|
|
||||
LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
||||
| ^^^^
|
||||
help: consider restricting type parameter `U` with trait `Send`
|
||||
|
|
||||
LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
||||
| +++++++++++++++++++
|
||||
|
||||
error: future cannot be sent between threads safely
|
||||
--> $DIR/issue-70818.rs:4:38
|
||||
|
|
||||
@@ -14,5 +35,5 @@ help: consider restricting type parameter `U` with trait `Send`
|
||||
LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
|
||||
| +++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
||||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 18:27}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
|
||||
= note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 18:27}>>` to `Pin<Box<dyn Future<Output = ()> + Send>>`
|
||||
help: consider further restricting type parameter `T` with trait `Sync`
|
||||
|
|
||||
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::future::ready;
|
||||
|
||||
struct NonClone;
|
||||
|
||||
fn main() {
|
||||
fn local() {
|
||||
let inner_non_clone = async {
|
||||
let non_clone = NonClone;
|
||||
let () = ready(()).await;
|
||||
@@ -34,7 +34,9 @@ fn main() {
|
||||
//~^ ERROR : Copy` is not satisfied
|
||||
check_clone(&maybe_copy_clone);
|
||||
//~^ ERROR : Clone` is not satisfied
|
||||
}
|
||||
|
||||
fn non_local() {
|
||||
let inner_non_clone_fn = the_inner_non_clone_fn();
|
||||
check_copy(&inner_non_clone_fn);
|
||||
//~^ ERROR : Copy` is not satisfied
|
||||
@@ -69,3 +71,5 @@ async fn the_maybe_copy_clone_fn() {}
|
||||
|
||||
fn check_copy<T: Copy>(_x: &T) {}
|
||||
fn check_clone<T: Clone>(_x: &T) {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,89 +1,5 @@
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:18:16
|
||||
|
|
||||
LL | check_copy(&inner_non_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:20:17
|
||||
|
|
||||
LL | check_clone(&inner_non_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:27:16
|
||||
|
|
||||
LL | check_copy(&outer_non_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:29:17
|
||||
|
|
||||
LL | check_clone(&outer_non_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:33:16
|
||||
|
|
||||
LL | check_copy(&maybe_copy_clone);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:35:17
|
||||
|
|
||||
LL | check_clone(&maybe_copy_clone);
|
||||
| ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:39:16
|
||||
--> $DIR/clone-impl-async.rs:41:16
|
||||
|
|
||||
LL | check_copy(&inner_non_clone_fn);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -91,13 +7,13 @@ LL | check_copy(&inner_non_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:41:17
|
||||
--> $DIR/clone-impl-async.rs:43:17
|
||||
|
|
||||
LL | check_clone(&inner_non_clone_fn);
|
||||
| ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -105,13 +21,13 @@ LL | check_clone(&inner_non_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:45:16
|
||||
--> $DIR/clone-impl-async.rs:47:16
|
||||
|
|
||||
LL | check_copy(&outer_non_clone_fn);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -119,13 +35,13 @@ LL | check_copy(&outer_non_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:47:17
|
||||
--> $DIR/clone-impl-async.rs:49:17
|
||||
|
|
||||
LL | check_clone(&outer_non_clone_fn);
|
||||
| ----------- ^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -133,13 +49,13 @@ LL | check_clone(&outer_non_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:51:16
|
||||
--> $DIR/clone-impl-async.rs:53:16
|
||||
|
|
||||
LL | check_copy(&maybe_copy_clone_fn);
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -147,13 +63,13 @@ LL | check_copy(&maybe_copy_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:70:18
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:53:17
|
||||
--> $DIR/clone-impl-async.rs:55:17
|
||||
|
|
||||
LL | check_clone(&maybe_copy_clone_fn);
|
||||
| ----------- ^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
|
||||
@@ -161,7 +77,79 @@ LL | check_clone(&maybe_copy_clone_fn);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:71:19
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:18:5
|
||||
|
|
||||
LL | check_copy(&inner_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:20:5
|
||||
|
|
||||
LL | check_clone(&inner_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:13:27: 13:32}`
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:27:5
|
||||
|
|
||||
LL | check_copy(&outer_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:29:5
|
||||
|
|
||||
LL | check_clone(&outer_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:24:27: 24:37}`
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:33:5
|
||||
|
|
||||
LL | check_copy(&maybe_copy_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-async.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-async.rs:35:5
|
||||
|
|
||||
LL | check_clone(&maybe_copy_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{async block@$DIR/clone-impl-async.rs:32:28: 32:38}`
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-async.rs:73:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Copy` is not satisfied
|
||||
--> $DIR/clone-impl-static.rs:14:16
|
||||
--> $DIR/clone-impl-static.rs:14:5
|
||||
|
|
||||
LL | check_copy(&generator);
|
||||
| ---------- ^^^^^^^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
|
||||
|
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl-static.rs:20:18
|
||||
@@ -13,12 +11,10 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}: Clone` is not satisfied
|
||||
--> $DIR/clone-impl-static.rs:16:17
|
||||
--> $DIR/clone-impl-static.rs:16:5
|
||||
|
|
||||
LL | check_clone(&generator);
|
||||
| ----------- ^^^^^^^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:11:5: 11:19}`
|
||||
|
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl-static.rs:21:19
|
||||
|
||||
@@ -42,6 +42,7 @@ fn test3_upvars() {
|
||||
let clonable_0: Vec<u32> = Vec::new();
|
||||
let gen_clone_0 = #[coroutine]
|
||||
move || {
|
||||
yield;
|
||||
drop(clonable_0);
|
||||
};
|
||||
check_copy(&gen_clone_0);
|
||||
|
||||
@@ -1,59 +1,81 @@
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`
|
||||
--> $DIR/clone-impl.rs:47:16
|
||||
--> $DIR/clone-impl.rs:48:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_0);
|
||||
| ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:45:14
|
||||
--> $DIR/clone-impl.rs:46:14
|
||||
|
|
||||
LL | drop(clonable_0);
|
||||
| ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
--> $DIR/clone-impl.rs:92:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`
|
||||
--> $DIR/clone-impl.rs:73:16
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`
|
||||
--> $DIR/clone-impl.rs:60:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:55:5: 55:12}`, the trait `Copy` is not implemented for `Vec<char>`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:57:9
|
||||
|
|
||||
LL | let v = vec!['a'];
|
||||
| - has type `Vec<char>` which does not implement `Copy`
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `v` maybe used later
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:92:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`
|
||||
--> $DIR/clone-impl.rs:74:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:68:5: 68:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:71:14
|
||||
--> $DIR/clone-impl.rs:72:14
|
||||
|
|
||||
LL | drop(clonable_1);
|
||||
| ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
--> $DIR/clone-impl.rs:92:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
--> $DIR/clone-impl.rs:85:16
|
||||
error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
|
||||
--> $DIR/clone-impl.rs:86:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
|
||||
...
|
||||
LL | check_copy(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Copy` is not implemented for `NonClone`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`, the trait `Copy` is not implemented for `NonClone`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:83:14
|
||||
--> $DIR/clone-impl.rs:84:14
|
||||
|
|
||||
LL | drop(non_clonable);
|
||||
| ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
--> $DIR/clone-impl.rs:92:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
@@ -63,22 +85,22 @@ LL + #[derive(Copy)]
|
||||
LL | struct NonClone;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
--> $DIR/clone-impl.rs:87:17
|
||||
error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
|
||||
--> $DIR/clone-impl.rs:88:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`
|
||||
...
|
||||
LL | check_clone(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Clone` is not implemented for `NonClone`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:82:5: 82:12}`, the trait `Clone` is not implemented for `NonClone`
|
||||
|
|
||||
note: captured value does not implement `Clone`
|
||||
--> $DIR/clone-impl.rs:83:14
|
||||
--> $DIR/clone-impl.rs:84:14
|
||||
|
|
||||
LL | drop(non_clonable);
|
||||
| ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone`
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl.rs:92:19
|
||||
--> $DIR/clone-impl.rs:93:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
@@ -88,28 +110,6 @@ LL + #[derive(Clone)]
|
||||
LL | struct NonClone;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`
|
||||
--> $DIR/clone-impl.rs:59:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`, the trait `Copy` is not implemented for `Vec<char>`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:56:9
|
||||
|
|
||||
LL | let v = vec!['a'];
|
||||
| - has type `Vec<char>` which does not implement `Copy`
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `v` maybe used later
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -9,7 +9,7 @@ LL | | drop(a);
|
||||
LL | | });
|
||||
| |______^ coroutine is not `Sync`
|
||||
|
|
||||
= help: within `{main::{closure#0} upvar_tys=() resume_ty=() yield_ty=() return_ty=() witness={main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
|
||||
= help: within `{main::{closure#0} upvar_tys=() resume_ty=() yield_ty=() return_ty=()}`, the trait `Sync` is not implemented for `NotSync`
|
||||
note: coroutine is not `Sync` as this value is used across a yield
|
||||
--> $DIR/coroutine-print-verbose-2.rs:20:9
|
||||
|
|
||||
@@ -34,7 +34,7 @@ LL | | drop(a);
|
||||
LL | | });
|
||||
| |______^ coroutine is not `Send`
|
||||
|
|
||||
= help: within `{main::{closure#1} upvar_tys=() resume_ty=() yield_ty=() return_ty=() witness={main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
|
||||
= help: within `{main::{closure#1} upvar_tys=() resume_ty=() yield_ty=() return_ty=()}`, the trait `Send` is not implemented for `NotSend`
|
||||
note: coroutine is not `Send` as this value is used across a yield
|
||||
--> $DIR/coroutine-print-verbose-2.rs:27:9
|
||||
|
|
||||
|
||||
@@ -11,7 +11,7 @@ LL | | };
|
||||
| |_____^ expected `()`, found coroutine
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str witness={main::{closure#0}}}`
|
||||
found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
error: coroutine cannot be sent between threads safely
|
||||
--> $DIR/ref-upvar-not-send.rs:15:30
|
||||
--> $DIR/ref-upvar-not-send.rs:15:5
|
||||
|
|
||||
LL | assert_send(#[coroutine] move || {
|
||||
| ______________________________^
|
||||
LL | / assert_send(#[coroutine] move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | yield;
|
||||
LL | | let _x = x;
|
||||
LL | | });
|
||||
| |_____^ coroutine is not `Send`
|
||||
| |______^ coroutine is not `Send`
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `*mut ()`
|
||||
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
|
||||
@@ -23,16 +22,15 @@ LL | fn assert_send<T: Send>(_: T) {}
|
||||
| ^^^^ required by this bound in `assert_send`
|
||||
|
||||
error: coroutine cannot be sent between threads safely
|
||||
--> $DIR/ref-upvar-not-send.rs:23:30
|
||||
--> $DIR/ref-upvar-not-send.rs:23:5
|
||||
|
|
||||
LL | assert_send(#[coroutine] move || {
|
||||
| ______________________________^
|
||||
LL | / assert_send(#[coroutine] move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | yield;
|
||||
LL | | let _y = y;
|
||||
LL | | });
|
||||
| |_____^ coroutine is not `Send`
|
||||
| |______^ coroutine is not `Send`
|
||||
|
|
||||
= help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}`, the trait `Send` is not implemented for `*mut ()`
|
||||
note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send`
|
||||
|
||||
@@ -12,7 +12,6 @@ impl<S> Bar for S {
|
||||
type E = impl std::marker::Send;
|
||||
fn foo<T>() -> Self::E {
|
||||
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
//~| ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
async {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,5 @@ error: type parameter `T` is part of concrete type but not used in parameter lis
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^
|
||||
|
||||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-55872-2.rs:13:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ impl<S> Bar for S {
|
||||
fn foo<T>() -> Self::E {
|
||||
//~^ ERROR : Copy` is not satisfied [E0277]
|
||||
//~| ERROR type parameter `T` is part of concrete type
|
||||
//~| ERROR type parameter `T` is part of concrete type
|
||||
async {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}: Copy` is not satisfied
|
||||
--> $DIR/issue-55872-3.rs:14:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}`
|
||||
...
|
||||
LL | async {}
|
||||
| -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}` here
|
||||
|
||||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-55872-3.rs:14:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^
|
||||
|
||||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied
|
||||
--> $DIR/issue-55872-3.rs:14:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
Reference in New Issue
Block a user