mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-17 03:46:07 +00:00
Auto merge of #141762 - compiler-errors:witnesser, r=lcnr
Unify `CoroutineWitness` sooner in typeck, and stall coroutine obligations based off of `TypingEnv` * Stall coroutine obligations based off of `TypingMode` in the old solver. * Eagerly assign `TyKind::CoroutineWitness` to the witness arg of coroutines during typeck, rather than deferring them to the end of typeck. r? lcnr This is part of https://github.com/rust-lang/rust/issues/143017.
This commit is contained in:
commit
e466296627
@ -161,16 +161,7 @@ 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);
|
||||
|
||||
// In the new solver, we can just instantiate this eagerly
|
||||
// with the witness. This will ensure that goals that don't need
|
||||
// to stall on interior types will get processed eagerly.
|
||||
let interior = if self.next_trait_solver() {
|
||||
Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args)
|
||||
} else {
|
||||
self.next_ty_var(expr_span)
|
||||
};
|
||||
|
||||
self.deferred_coroutine_interiors.borrow_mut().push((expr_def_id, interior));
|
||||
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
|
||||
|
||||
@ -625,50 +625,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// trigger query cycle ICEs, as doing so requires MIR.
|
||||
self.select_obligations_where_possible(|_| {});
|
||||
|
||||
let coroutines = std::mem::take(&mut *self.deferred_coroutine_interiors.borrow_mut());
|
||||
debug!(?coroutines);
|
||||
let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
|
||||
else {
|
||||
bug!();
|
||||
};
|
||||
|
||||
let mut obligations = vec![];
|
||||
|
||||
if !self.next_trait_solver() {
|
||||
for &(coroutine_def_id, interior) in coroutines.iter() {
|
||||
debug!(?coroutine_def_id);
|
||||
|
||||
// Create the `CoroutineWitness` type that we will unify with `interior`.
|
||||
let args = ty::GenericArgs::identity_for_item(
|
||||
self.tcx,
|
||||
self.tcx.typeck_root_def_id(coroutine_def_id.to_def_id()),
|
||||
);
|
||||
let witness =
|
||||
Ty::new_coroutine_witness(self.tcx, coroutine_def_id.to_def_id(), args);
|
||||
|
||||
// Unify `interior` with `witness` and collect all the resulting obligations.
|
||||
let span = self.tcx.hir_body_owned_by(coroutine_def_id).value.span;
|
||||
let ty::Infer(ty::InferTy::TyVar(_)) = interior.kind() else {
|
||||
span_bug!(span, "coroutine interior witness not infer: {:?}", interior.kind())
|
||||
};
|
||||
let ok = self
|
||||
.at(&self.misc(span), self.param_env)
|
||||
// Will never define opaque types, as all we do is instantiate a type variable.
|
||||
.eq(DefineOpaqueTypes::Yes, interior, witness)
|
||||
.expect("Failed to unify coroutine interior type");
|
||||
|
||||
obligations.extend(ok.obligations);
|
||||
}
|
||||
}
|
||||
|
||||
if !coroutines.is_empty() {
|
||||
obligations.extend(
|
||||
if defining_opaque_types_and_generators
|
||||
.iter()
|
||||
.any(|def_id| self.tcx.is_coroutine(def_id.to_def_id()))
|
||||
{
|
||||
self.typeck_results.borrow_mut().coroutine_stalled_predicates.extend(
|
||||
self.fulfillment_cx
|
||||
.borrow_mut()
|
||||
.drain_stalled_obligations_for_coroutines(&self.infcx),
|
||||
.drain_stalled_obligations_for_coroutines(&self.infcx)
|
||||
.into_iter()
|
||||
.map(|o| (o.predicate, o.cause)),
|
||||
);
|
||||
}
|
||||
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.coroutine_stalled_predicates
|
||||
.extend(obligations.into_iter().map(|o| (o.predicate, o.cause)));
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
||||
@ -63,8 +63,6 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
|
||||
|
||||
pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, HirId)>>,
|
||||
|
||||
pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, Ty<'tcx>)>>,
|
||||
|
||||
pub(super) deferred_repeat_expr_checks:
|
||||
RefCell<Vec<(&'tcx hir::Expr<'tcx>, Ty<'tcx>, ty::Const<'tcx>)>>,
|
||||
|
||||
@ -103,7 +101,6 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
||||
deferred_cast_checks: RefCell::new(Vec::new()),
|
||||
deferred_transmute_checks: RefCell::new(Vec::new()),
|
||||
deferred_asm_checks: RefCell::new(Vec::new()),
|
||||
deferred_coroutine_interiors: RefCell::new(Vec::new()),
|
||||
deferred_repeat_expr_checks: RefCell::new(Vec::new()),
|
||||
diverging_type_vars: RefCell::new(Default::default()),
|
||||
infer_var_info: RefCell::new(Default::default()),
|
||||
|
||||
@ -714,17 +714,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
self,
|
||||
defining_anchor: Self::LocalDefId,
|
||||
) -> Self::LocalDefIds {
|
||||
if self.next_trait_solver_globally() {
|
||||
let coroutines_defined_by = self
|
||||
.nested_bodies_within(defining_anchor)
|
||||
.iter()
|
||||
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
|
||||
self.mk_local_def_ids_from_iter(
|
||||
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
|
||||
)
|
||||
} else {
|
||||
self.opaque_types_defined_by(defining_anchor)
|
||||
}
|
||||
let coroutines_defined_by = self
|
||||
.nested_bodies_within(defining_anchor)
|
||||
.iter()
|
||||
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
|
||||
self.mk_local_def_ids_from_iter(
|
||||
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,8 +33,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
|
||||
// FIXME(#132279): This should be removed as it causes us to incorrectly
|
||||
// handle opaques in their defining scope.
|
||||
if !self.next_trait_solver() && !(param_env, ty).has_infer() {
|
||||
// handle opaques in their defining scope, and stalled coroutines.
|
||||
if !self.next_trait_solver() && !(param_env, ty).has_infer() && !ty.has_coroutines() {
|
||||
return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty);
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ mod normalize;
|
||||
mod select;
|
||||
|
||||
pub(crate) use delegate::SolverDelegate;
|
||||
pub use fulfill::{FulfillmentCtxt, NextSolverError};
|
||||
pub use fulfill::{FulfillmentCtxt, NextSolverError, StalledOnCoroutines};
|
||||
pub(crate) use normalize::deeply_normalize_for_diagnostics;
|
||||
pub use normalize::{
|
||||
deeply_normalize, deeply_normalize_with_skipped_universes,
|
||||
|
||||
@ -10,7 +10,8 @@ use rustc_infer::traits::{
|
||||
FromSolverError, PredicateObligation, PredicateObligations, TraitEngine,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, TypingMode,
|
||||
self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
TypingMode,
|
||||
};
|
||||
use rustc_next_trait_solver::delegate::SolverDelegate as _;
|
||||
use rustc_next_trait_solver::solve::{
|
||||
@ -254,7 +255,7 @@ where
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
) -> PredicateObligations<'tcx> {
|
||||
let stalled_generators = match infcx.typing_mode() {
|
||||
let stalled_coroutines = match infcx.typing_mode() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
defining_opaque_types_and_generators
|
||||
}
|
||||
@ -264,7 +265,7 @@ where
|
||||
| TypingMode::PostAnalysis => return Default::default(),
|
||||
};
|
||||
|
||||
if stalled_generators.is_empty() {
|
||||
if stalled_coroutines.is_empty() {
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
@ -275,7 +276,7 @@ where
|
||||
.visit_proof_tree(
|
||||
obl.as_goal(),
|
||||
&mut StalledOnCoroutines {
|
||||
stalled_generators,
|
||||
stalled_coroutines,
|
||||
span: obl.cause.span,
|
||||
cache: Default::default(),
|
||||
},
|
||||
@ -297,10 +298,10 @@ where
|
||||
///
|
||||
/// This function can be also return false positives, which will lead to poor diagnostics
|
||||
/// so we want to keep this visitor *precise* too.
|
||||
struct StalledOnCoroutines<'tcx> {
|
||||
stalled_generators: &'tcx ty::List<LocalDefId>,
|
||||
span: Span,
|
||||
cache: DelayedSet<Ty<'tcx>>,
|
||||
pub struct StalledOnCoroutines<'tcx> {
|
||||
pub stalled_coroutines: &'tcx ty::List<LocalDefId>,
|
||||
pub span: Span,
|
||||
pub cache: DelayedSet<Ty<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> inspect::ProofTreeVisitor<'tcx> for StalledOnCoroutines<'tcx> {
|
||||
@ -330,12 +331,14 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
|
||||
}
|
||||
|
||||
if let ty::CoroutineWitness(def_id, _) = *ty.kind()
|
||||
&& def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id))
|
||||
&& def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
ControlFlow::Break(())
|
||||
} else if ty.has_coroutines() {
|
||||
ty.super_visit_with(self)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ use std::marker::PhantomData;
|
||||
use rustc_data_structures::obligation_forest::{
|
||||
Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult,
|
||||
};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::traits::{
|
||||
FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError,
|
||||
@ -12,8 +13,10 @@ use rustc_middle::bug;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, Const, GenericArgsRef, TypeVisitableExt, TypingMode, may_use_unstable_feature,
|
||||
self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode,
|
||||
may_use_unstable_feature,
|
||||
};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
use tracing::{debug, debug_span, instrument};
|
||||
|
||||
@ -26,6 +29,7 @@ use super::{
|
||||
};
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
||||
use crate::solve::StalledOnCoroutines;
|
||||
use crate::traits::normalize::normalize_with_depth_to;
|
||||
use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _};
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
@ -168,8 +172,25 @@ where
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
) -> PredicateObligations<'tcx> {
|
||||
let mut processor =
|
||||
DrainProcessor { removed_predicates: PredicateObligations::new(), infcx };
|
||||
let stalled_coroutines = match infcx.typing_mode() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
defining_opaque_types_and_generators
|
||||
}
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ }
|
||||
| TypingMode::PostAnalysis => return Default::default(),
|
||||
};
|
||||
|
||||
if stalled_coroutines.is_empty() {
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
let mut processor = DrainProcessor {
|
||||
infcx,
|
||||
removed_predicates: PredicateObligations::new(),
|
||||
stalled_coroutines,
|
||||
};
|
||||
let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor);
|
||||
assert!(outcome.errors.is_empty());
|
||||
return processor.removed_predicates;
|
||||
@ -177,6 +198,7 @@ where
|
||||
struct DrainProcessor<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'tcx>,
|
||||
removed_predicates: PredicateObligations<'tcx>,
|
||||
stalled_coroutines: &'tcx ty::List<LocalDefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> {
|
||||
@ -185,10 +207,14 @@ where
|
||||
type OUT = Outcome<Self::Obligation, Self::Error>;
|
||||
|
||||
fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
|
||||
pending_obligation
|
||||
.stalled_on
|
||||
.iter()
|
||||
.any(|&var| self.infcx.ty_or_const_infer_var_changed(var))
|
||||
self.infcx
|
||||
.resolve_vars_if_possible(pending_obligation.obligation.predicate)
|
||||
.visit_with(&mut StalledOnCoroutines {
|
||||
stalled_coroutines: self.stalled_coroutines,
|
||||
span: DUMMY_SP,
|
||||
cache: Default::default(),
|
||||
})
|
||||
.is_break()
|
||||
}
|
||||
|
||||
fn process_obligation(
|
||||
|
||||
@ -842,6 +842,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
candidates.vec.push(AutoImplCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
@ -861,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Coroutine(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::UnsafeBinder(_) => {
|
||||
// Only consider auto impls of unsafe traits when there are
|
||||
// no unsafe fields.
|
||||
@ -1119,12 +1126,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
match *self_ty.kind() {
|
||||
// These impls are built-in because we cannot express sufficiently
|
||||
// generic impls in libcore.
|
||||
ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Error(_)
|
||||
| ty::Tuple(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Pat(..) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) | ty::Tuple(..) | ty::Pat(..) => {
|
||||
candidates.vec.push(BuiltinCandidate);
|
||||
}
|
||||
|
||||
@ -1192,6 +1194,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(coroutine_def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
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(..) => {}
|
||||
|
||||
@ -1229,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
@ -1238,6 +1247,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(coroutine_def_id, _) => {
|
||||
if self.should_stall_coroutine_witness(coroutine_def_id) {
|
||||
candidates.ambiguous = true;
|
||||
} else {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
// Conditionally `Sized`.
|
||||
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
|
||||
candidates.vec.push(SizedCandidate);
|
||||
|
||||
@ -1512,7 +1512,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
defining_opaque_types_and_generators: defining_opaque_types,
|
||||
}
|
||||
| TypingMode::Borrowck { defining_opaque_types } => {
|
||||
defining_opaque_types.is_empty() || !pred.has_opaque_types()
|
||||
defining_opaque_types.is_empty()
|
||||
|| (!pred.has_opaque_types() && !pred.has_coroutines())
|
||||
}
|
||||
// The hidden types of `defined_opaque_types` is not local to the current
|
||||
// inference context, so we can freely move this to the global cache.
|
||||
@ -2811,6 +2812,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
|
||||
obligations
|
||||
}
|
||||
|
||||
fn should_stall_coroutine_witness(&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))
|
||||
}
|
||||
TypingMode::Coherence
|
||||
| TypingMode::PostAnalysis
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
|
||||
|
||||
@ -130,6 +130,12 @@ 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.
|
||||
const HAS_TY_CORO = 1 << 24;
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,10 +246,12 @@ impl<I: Interner> FlagComputation<I> {
|
||||
self.add_flags(TypeFlags::HAS_TY_PARAM);
|
||||
}
|
||||
|
||||
ty::Closure(_, args)
|
||||
| ty::Coroutine(_, args)
|
||||
| ty::CoroutineClosure(_, args)
|
||||
| ty::CoroutineWitness(_, args) => {
|
||||
ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
|
||||
self.add_args(args.as_slice());
|
||||
}
|
||||
|
||||
ty::CoroutineWitness(_, args) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_CORO);
|
||||
self.add_args(args.as_slice());
|
||||
}
|
||||
|
||||
|
||||
@ -269,6 +269,10 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
||||
}
|
||||
|
||||
fn has_coroutines(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_CORO)
|
||||
}
|
||||
|
||||
fn references_error(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_ERROR)
|
||||
}
|
||||
|
||||
@ -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}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
|
||||
| ^^ --- 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}}}`
|
||||
| |
|
||||
| expected `async` closure body, found `()`
|
||||
|
|
||||
= note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
|
||||
= 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}}}`
|
||||
found unit type `()`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@ -38,39 +38,40 @@ fn test2() {
|
||||
check_clone(&gen_copy_1);
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
fn test3_upvars() {
|
||||
let clonable_0: Vec<u32> = Vec::new();
|
||||
let gen_clone_0 = #[coroutine]
|
||||
move || {
|
||||
let v = vec!['a'];
|
||||
yield;
|
||||
drop(v);
|
||||
drop(clonable_0);
|
||||
};
|
||||
check_copy(&gen_clone_0);
|
||||
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
|
||||
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
|
||||
check_clone(&gen_clone_0);
|
||||
}
|
||||
|
||||
fn test3_witness() {
|
||||
let gen_clone_1 = #[coroutine]
|
||||
move || {
|
||||
let v = vec!['a'];
|
||||
yield;
|
||||
drop(v);
|
||||
};
|
||||
check_copy(&gen_clone_1);
|
||||
//~^ ERROR the trait bound `Vec<char>: Copy` is not satisfied
|
||||
check_clone(&gen_clone_1);
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
let clonable_1: Vec<u32> = Vec::new();
|
||||
let gen_clone_1 = #[coroutine]
|
||||
move || {
|
||||
let v = vec!['a'];
|
||||
/*
|
||||
let n = NonClone;
|
||||
drop(n);
|
||||
*/
|
||||
yield;
|
||||
let n = NonClone;
|
||||
drop(n);
|
||||
drop(v);
|
||||
drop(clonable_1);
|
||||
};
|
||||
check_copy(&gen_clone_1);
|
||||
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
|
||||
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
|
||||
check_clone(&gen_clone_1);
|
||||
}
|
||||
|
||||
|
||||
@ -1,104 +1,59 @@
|
||||
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:50:5
|
||||
--> $DIR/clone-impl.rs:47:16
|
||||
|
|
||||
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:48:14
|
||||
--> $DIR/clone-impl.rs:45: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:90:18
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`
|
||||
--> $DIR/clone-impl.rs:50:5
|
||||
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
|
||||
|
|
||||
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<char>`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:46: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:90: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:59:5: 59:12}`
|
||||
--> $DIR/clone-impl.rs:71:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
| ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`, the trait `Copy` is not implemented for `Vec<u32>`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:69:14
|
||||
--> $DIR/clone-impl.rs:71: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:90:18
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`
|
||||
--> $DIR/clone-impl.rs:71:5
|
||||
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
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59: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:65: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:90: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:80:5: 80:12}`
|
||||
--> $DIR/clone-impl.rs:84:5
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
...
|
||||
LL | check_copy(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Copy` is not implemented for `NonClone`
|
||||
| ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Copy` is not implemented for `NonClone`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:82:14
|
||||
--> $DIR/clone-impl.rs:83: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:90:18
|
||||
--> $DIR/clone-impl.rs:91:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
@ -108,22 +63,22 @@ LL + #[derive(Copy)]
|
||||
LL | struct NonClone;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`
|
||||
--> $DIR/clone-impl.rs:86:5
|
||||
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
|
||||
|
|
||||
LL | move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`
|
||||
...
|
||||
LL | check_clone(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Clone` is not implemented for `NonClone`
|
||||
| ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Clone` is not implemented for `NonClone`
|
||||
|
|
||||
note: captured value does not implement `Clone`
|
||||
--> $DIR/clone-impl.rs:82:14
|
||||
--> $DIR/clone-impl.rs:83: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:91:19
|
||||
--> $DIR/clone-impl.rs:92:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
@ -133,6 +88,28 @@ LL + #[derive(Clone)]
|
||||
LL | struct NonClone;
|
||||
|
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
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`.
|
||||
|
||||
@ -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=?6t}`
|
||||
found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str witness={main::{closure#0}}}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ 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,11 +1,11 @@
|
||||
error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied
|
||||
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:17:9: 17:14}`
|
||||
| ^^^^^^^ 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:17:9: 17:14}` here
|
||||
| -------- 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
|
||||
@ -13,6 +13,14 @@ error: type parameter `T` is part of concrete type but not used in parameter lis
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
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 {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user