Replace tuple of infer vars for upvar_tys with single infer var
This commit allows us to decide the number of captures required after completing capture ananysis, which is required as part of implementing RFC-2229. Co-authored-by: Aman Arora <me@aman-arora.com> Co-authored-by: Jenny Wills <wills.jenniferg@gmail.com>
This commit is contained in:
parent
25d2d09da7
commit
dc183702da
@ -96,15 +96,25 @@ fn compute_components(
|
||||
}
|
||||
|
||||
ty::Closure(_, ref substs) => {
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
compute_components(tcx, upvar_ty, out, visited);
|
||||
if substs.as_closure().is_valid() {
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
compute_components(tcx, upvar_ty, out, visited);
|
||||
}
|
||||
} else {
|
||||
let tupled_ty = substs.as_closure().tupled_upvars_ty();
|
||||
compute_components(tcx, tupled_ty, out, visited);
|
||||
}
|
||||
}
|
||||
|
||||
ty::Generator(_, ref substs, _) => {
|
||||
// Same as the closure case
|
||||
for upvar_ty in substs.as_generator().upvar_tys() {
|
||||
compute_components(tcx, upvar_ty, out, visited);
|
||||
if substs.as_generator().is_valid() {
|
||||
for upvar_ty in substs.as_generator().upvar_tys() {
|
||||
compute_components(tcx, upvar_ty, out, visited);
|
||||
}
|
||||
} else {
|
||||
let tupled_ty = substs.as_generator().tupled_upvars_ty();
|
||||
compute_components(tcx, tupled_ty, out, visited);
|
||||
}
|
||||
|
||||
// We ignore regions in the generator interior as we don't
|
||||
|
@ -663,18 +663,13 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, substs));
|
||||
if substs.as_generator().is_valid() {
|
||||
// Search for the first inference variable
|
||||
p!(" upvar_tys=(");
|
||||
let mut uninferred_ty =
|
||||
substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer());
|
||||
if uninferred_ty.next().is_some() {
|
||||
p!(write("unavailable"));
|
||||
} else {
|
||||
self = self.comma_sep(substs.as_generator().upvar_tys())?;
|
||||
}
|
||||
p!(")");
|
||||
p!(" upvar_tys=(");
|
||||
if !substs.as_generator().is_valid() {
|
||||
p!("unavailable");
|
||||
} else {
|
||||
self = self.comma_sep(substs.as_generator().upvar_tys())?;
|
||||
}
|
||||
p!(")");
|
||||
}
|
||||
|
||||
if substs.as_generator().is_valid() {
|
||||
@ -704,24 +699,17 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, substs));
|
||||
if substs.as_closure().is_valid() {
|
||||
// Search for the first inference variable
|
||||
let mut uninferred_ty =
|
||||
substs.as_closure().upvar_tys().filter(|ty| ty.is_ty_infer());
|
||||
if uninferred_ty.next().is_some() {
|
||||
// If the upvar substs contain an inference variable we haven't
|
||||
// finished capture analysis.
|
||||
p!(" closure_substs=(unavailable)");
|
||||
} else {
|
||||
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
|
||||
p!(
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(substs.as_closure().sig_as_fn_ptr_ty())
|
||||
);
|
||||
p!(" upvar_tys=(");
|
||||
self = self.comma_sep(substs.as_closure().upvar_tys())?;
|
||||
p!(")");
|
||||
}
|
||||
if !substs.as_closure().is_valid() {
|
||||
p!(" closure_substs=(unavailable)");
|
||||
} else {
|
||||
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
|
||||
p!(
|
||||
" closure_sig_as_fn_ptr_ty=",
|
||||
print(substs.as_closure().sig_as_fn_ptr_ty())
|
||||
);
|
||||
p!(" upvar_tys=(");
|
||||
self = self.comma_sep(substs.as_closure().upvar_tys())?;
|
||||
p!(")");
|
||||
}
|
||||
}
|
||||
p!("]");
|
||||
|
@ -656,6 +656,14 @@ impl<'tcx> UpvarSubsts<'tcx> {
|
||||
};
|
||||
tupled_upvars_ty.expect_ty().tuple_fields()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
|
||||
match self {
|
||||
UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
|
||||
UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
|
@ -441,6 +441,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
|
||||
for required_region in required_region_bounds {
|
||||
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
|
||||
infcx: self,
|
||||
op: |r| self.sub_regions(infer::CallReturn(span), required_region, r),
|
||||
});
|
||||
}
|
||||
@ -509,6 +510,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
|
||||
infcx: self,
|
||||
op: |r| self.sub_regions(infer::CallReturn(span), least_region, r),
|
||||
});
|
||||
}
|
||||
@ -543,6 +545,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
);
|
||||
|
||||
concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
|
||||
infcx: self,
|
||||
op: |r| {
|
||||
self.member_constraint(
|
||||
opaque_type_def_id,
|
||||
@ -683,11 +686,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
//
|
||||
// We ignore any type parameters because impl trait values are assumed to
|
||||
// capture all the in-scope type parameters.
|
||||
struct ConstrainOpaqueTypeRegionVisitor<OP> {
|
||||
struct ConstrainOpaqueTypeRegionVisitor<'cx, 'tcx, OP> {
|
||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
op: OP,
|
||||
}
|
||||
|
||||
impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<OP>
|
||||
impl<'cx, 'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'cx, 'tcx, OP>
|
||||
where
|
||||
OP: FnMut(ty::Region<'tcx>),
|
||||
{
|
||||
@ -717,24 +721,36 @@ where
|
||||
ty::Closure(_, ref substs) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
upvar_ty.visit_with(self);
|
||||
}
|
||||
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
|
||||
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
|
||||
// Not yet resolved.
|
||||
ty.super_visit_with(self);
|
||||
} else {
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
upvar_ty.visit_with(self);
|
||||
}
|
||||
|
||||
substs.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
||||
substs.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
||||
}
|
||||
}
|
||||
|
||||
ty::Generator(_, ref substs, _) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
// Also skip the witness type, because that has no free regions.
|
||||
|
||||
for upvar_ty in substs.as_generator().upvar_tys() {
|
||||
upvar_ty.visit_with(self);
|
||||
}
|
||||
let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
|
||||
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
|
||||
// Not yet resolved.
|
||||
ty.super_visit_with(self);
|
||||
} else {
|
||||
for upvar_ty in substs.as_generator().upvar_tys() {
|
||||
upvar_ty.visit_with(self);
|
||||
}
|
||||
|
||||
substs.as_generator().return_ty().visit_with(self);
|
||||
substs.as_generator().yield_ty().visit_with(self);
|
||||
substs.as_generator().resume_ty().visit_with(self);
|
||||
substs.as_generator().return_ty().visit_with(self);
|
||||
substs.as_generator().yield_ty().visit_with(self);
|
||||
substs.as_generator().resume_ty().visit_with(self);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
ty.super_visit_with(self);
|
||||
|
@ -1307,6 +1307,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let mut generator = None;
|
||||
let mut outer_generator = None;
|
||||
let mut next_code = Some(&obligation.cause.code);
|
||||
|
||||
let mut seen_upvar_tys_infer_tuple = false;
|
||||
|
||||
while let Some(code) = next_code {
|
||||
debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
|
||||
match code {
|
||||
@ -1327,6 +1330,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
outer_generator = Some(did);
|
||||
}
|
||||
ty::GeneratorWitness(..) => {}
|
||||
ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
|
||||
// By introducing a tuple of upvar types into the chain of obligations
|
||||
// of a generator, the first non-generator item is now the tuple itself,
|
||||
// we shall ignore this.
|
||||
|
||||
seen_upvar_tys_infer_tuple = true;
|
||||
}
|
||||
_ if generator.is_none() => {
|
||||
trait_ref = Some(derived_obligation.parent_trait_ref.skip_binder());
|
||||
target_ty = Some(ty);
|
||||
|
@ -110,7 +110,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
// check if *any* of those are trivial.
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
|
||||
ty::Closure(_, ref substs) => {
|
||||
substs.as_closure().upvar_tys().all(|t| trivial_dropck_outlives(tcx, t))
|
||||
trivial_dropck_outlives(tcx, substs.as_closure().tupled_upvars_ty())
|
||||
}
|
||||
|
||||
ty::Adt(def, _) => {
|
||||
|
@ -1631,7 +1631,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(substs.as_closure().upvar_tys().collect()))
|
||||
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
|
||||
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
|
||||
// Not yet resolved.
|
||||
Ambiguous
|
||||
} else {
|
||||
Where(ty::Binder::bind(substs.as_closure().upvar_tys().collect()))
|
||||
}
|
||||
}
|
||||
|
||||
ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => {
|
||||
@ -1700,11 +1706,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
tys.iter().map(|k| k.expect_ty()).collect()
|
||||
}
|
||||
|
||||
ty::Closure(_, ref substs) => substs.as_closure().upvar_tys().collect(),
|
||||
ty::Closure(_, ref substs) => {
|
||||
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
|
||||
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
|
||||
// The inference variable will be replaced by a tuple once capture analysis
|
||||
// completes. If the tuple meets a bound, so do all the elements within it.
|
||||
vec![ty]
|
||||
} else {
|
||||
substs.as_closure().upvar_tys().collect()
|
||||
}
|
||||
}
|
||||
|
||||
ty::Generator(_, ref substs, _) => {
|
||||
let witness = substs.as_generator().witness();
|
||||
substs.as_generator().upvar_tys().chain(iter::once(witness)).collect()
|
||||
let upvar_tys_resolved =
|
||||
self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
|
||||
|
||||
if let ty::Infer(ty::TyVar(_)) = upvar_tys_resolved.kind() {
|
||||
// The inference variable will be replaced by a tuple once capture analysis
|
||||
// completes, if the tuple meets a bound, so do all the elements within it.
|
||||
let witness_resolved =
|
||||
self.infcx.shallow_resolve(substs.as_generator().witness());
|
||||
vec![upvar_tys_resolved, witness_resolved]
|
||||
} else {
|
||||
let witness = substs.as_generator().witness();
|
||||
substs.as_generator().upvar_tys().chain(iter::once(witness)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
ty::GeneratorWitness(types) => {
|
||||
|
@ -592,10 +592,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
// anyway, except via auto trait matching (which
|
||||
// only inspects the upvar types).
|
||||
walker.skip_current_subtree(); // subtree handled below
|
||||
for upvar_ty in substs.as_closure().upvar_tys() {
|
||||
// FIXME(eddyb) add the type to `walker` instead of recursing.
|
||||
self.compute(upvar_ty.into());
|
||||
}
|
||||
// FIXME(eddyb) add the type to `walker` instead of recursing.
|
||||
self.compute(substs.as_closure().tupled_upvars_ty().into());
|
||||
}
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
|
@ -210,12 +210,20 @@ fn dtorck_constraint_for_ty<'tcx>(
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::Closure(_, substs) => rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in substs.as_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty, constraints)?;
|
||||
ty::Closure(_, substs) => {
|
||||
if !substs.as_closure().is_valid() {
|
||||
// By the time this code runs, all type variables ought to
|
||||
// be fully resolved.
|
||||
return Err(NoSolution);
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in substs.as_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty, constraints)?;
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?
|
||||
}
|
||||
|
||||
ty::Generator(_, substs, _movability) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
@ -241,6 +249,12 @@ fn dtorck_constraint_for_ty<'tcx>(
|
||||
// derived from lifetimes attached to the upvars and resume
|
||||
// argument, and we *do* incorporate those here.
|
||||
|
||||
if !substs.as_generator().is_valid() {
|
||||
// By the time this code runs, all type variables ought to
|
||||
// be fully resolved.
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
constraints.outlives.extend(
|
||||
substs
|
||||
.as_generator()
|
||||
|
@ -81,19 +81,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.tcx.closure_base_def_id(expr_def_id.to_def_id()),
|
||||
);
|
||||
|
||||
let tupled_upvars_ty =
|
||||
self.tcx.mk_tup(self.tcx.upvars_mentioned(expr_def_id).iter().flat_map(|upvars| {
|
||||
upvars.iter().map(|(&var_hir_id, _)| {
|
||||
// Create type variables (for now) to represent the transformed
|
||||
// types of upvars. These will be unified during the upvar
|
||||
// inference phase (`upvar.rs`).
|
||||
self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
// FIXME(eddyb) distinguish upvar inference variables from the rest.
|
||||
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||
span: self.tcx.hir().span(var_hir_id),
|
||||
})
|
||||
})
|
||||
}));
|
||||
let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||
span: self.tcx.hir().span(expr.hir_id),
|
||||
});
|
||||
|
||||
if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ use crate::astconv::AstConv;
|
||||
use crate::check::FnCtxt;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{Coercion, InferOk, InferResult};
|
||||
use rustc_middle::ty::adjustment::{
|
||||
@ -221,11 +222,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// unsafe qualifier.
|
||||
self.coerce_from_fn_pointer(a, a_f, b)
|
||||
}
|
||||
ty::Closure(_, substs_a) => {
|
||||
ty::Closure(closure_def_id_a, substs_a) => {
|
||||
// Non-capturing closures are coercible to
|
||||
// function pointers or unsafe function pointers.
|
||||
// It cannot convert closures that require unsafe.
|
||||
self.coerce_closure_to_fn(a, substs_a, b)
|
||||
self.coerce_closure_to_fn(a, closure_def_id_a, substs_a, b)
|
||||
}
|
||||
_ => {
|
||||
// Otherwise, just use unification rules.
|
||||
@ -762,6 +763,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
fn coerce_closure_to_fn(
|
||||
&self,
|
||||
a: Ty<'tcx>,
|
||||
closure_def_id_a: DefId,
|
||||
substs_a: SubstsRef<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
) -> CoerceResult<'tcx> {
|
||||
@ -772,7 +774,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
let b = self.shallow_resolve(b);
|
||||
|
||||
match b.kind() {
|
||||
ty::FnPtr(fn_ty) if substs_a.as_closure().upvar_tys().next().is_none() => {
|
||||
// At this point we haven't done capture analysis, which means
|
||||
// that the ClosureSubsts just contains an inference variable instead
|
||||
// of tuple of captured types.
|
||||
//
|
||||
// All we care here is if any variable is being captured and not the exact paths,
|
||||
// so we check `upvars_mentioned` for root variables being captured.
|
||||
ty::FnPtr(fn_ty)
|
||||
if self
|
||||
.tcx
|
||||
.upvars_mentioned(closure_def_id_a.expect_local())
|
||||
.map_or(true, |u| u.is_empty()) =>
|
||||
{
|
||||
// We coerce the closure, which has fn type
|
||||
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
|
||||
// to
|
||||
@ -906,8 +919,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Function items or non-capturing closures of differing IDs or InternalSubsts.
|
||||
let (a_sig, b_sig) = {
|
||||
let is_capturing_closure = |ty| {
|
||||
if let &ty::Closure(_, substs) = ty {
|
||||
substs.as_closure().upvar_tys().next().is_some()
|
||||
if let &ty::Closure(closure_def_id, _substs) = ty {
|
||||
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -202,9 +202,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
"analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}",
|
||||
closure_hir_id, substs, final_upvar_tys
|
||||
);
|
||||
for (upvar_ty, final_upvar_ty) in substs.upvar_tys().zip(final_upvar_tys) {
|
||||
self.demand_suptype(span, upvar_ty, final_upvar_ty);
|
||||
}
|
||||
|
||||
// Build a tuple (U0..Un) of the final upvar types U0..Un
|
||||
// and unify the upvar tupe type in the closure with it:
|
||||
let final_tupled_upvars_type = self.tcx.mk_tup(final_upvar_tys.iter());
|
||||
self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type);
|
||||
|
||||
// If we are also inferred the closure kind here,
|
||||
// process any deferred resolutions.
|
||||
|
@ -11,6 +11,7 @@ LL | F: Send + 'static,
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
|
||||
= note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
|
||||
= note: required because it appears within the type `(&std::sync::mpsc::Receiver<()>,)`
|
||||
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6]`
|
||||
|
||||
error[E0277]: `Sender<()>` cannot be shared between threads safely
|
||||
@ -26,6 +27,7 @@ LL | F: Send + 'static,
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Sender<()>`
|
||||
= note: required because of the requirements on the impl of `Send` for `&Sender<()>`
|
||||
= note: required because it appears within the type `(&Sender<()>,)`
|
||||
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6 _]`
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6] as Generator>::Return == [generator@$DIR/generator-yielding-or-returning-itself.rs:15:34: 19:6]`
|
||||
--> $DIR/generator-yielding-or-returning-itself.rs:15:5
|
||||
|
|
||||
LL | pub fn want_cyclic_generator_return<T>(_: T)
|
||||
@ -14,7 +14,7 @@ LL | want_cyclic_generator_return(|| {
|
||||
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>
|
||||
for more information
|
||||
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _]`
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6] as Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6]`
|
||||
--> $DIR/generator-yielding-or-returning-itself.rs:28:5
|
||||
|
|
||||
LL | pub fn want_cyclic_generator_yield<T>(_: T)
|
||||
|
@ -9,6 +9,7 @@ LL | assert_send(|| {
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
||||
= note: required because of the requirements on the impl of `Send` for `&Cell<i32>`
|
||||
= note: required because it appears within the type `(&Cell<i32>,)`
|
||||
= note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6 _]`
|
||||
|
||||
error: generator cannot be shared between threads safely
|
||||
|
@ -9,7 +9,8 @@ LL | assert_send(|| {
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Cell<i32>`
|
||||
= note: required because of the requirements on the impl of `Send` for `&'_#3r Cell<i32>`
|
||||
= note: required because it appears within the type `[main::{closure#1} upvar_tys=(&'_#3r Cell<i32>) _#16t]`
|
||||
= note: required because it appears within the type `(&'_#3r Cell<i32>,)`
|
||||
= note: required because it appears within the type `[main::{closure#1} upvar_tys=(&'_#3r Cell<i32>) _#17t]`
|
||||
|
||||
error: generator cannot be shared between threads safely
|
||||
--> $DIR/generator-print-verbose-2.rs:12:5
|
||||
|
@ -12,7 +12,7 @@ LL | | };
|
||||
| |_____^ expected `()`, found generator
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found generator `[main::{closure#0} upvar_tys=(unavailable) _#5t]`
|
||||
found generator `[main::{closure#0} upvar_tys=(unavailable)]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]` cannot be unpinned
|
||||
error[E0277]: `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6]` cannot be unpinned
|
||||
--> $DIR/static-not-unpin.rs:14:18
|
||||
|
|
||||
LL | fn assert_unpin<T: Unpin>(_: T) {
|
||||
| ----- required by this bound in `assert_unpin`
|
||||
...
|
||||
LL | assert_unpin(generator);
|
||||
| ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]`
|
||||
| ^^^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,7 +7,7 @@ LL | 5
|
||||
= note: expected type `std::result::Result<{integer}, _>`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6 _] as Generator>::Return == i32`
|
||||
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32`
|
||||
--> $DIR/type-mismatch-signature-deduction.rs:5:13
|
||||
|
|
||||
LL | fn foo() -> impl Generator<Return = i32> {
|
||||
|
@ -12,6 +12,7 @@ LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
|
||||
= help: within `Cell<i32>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<i32>`
|
||||
= note: required because it appears within the type `Cell<i32>`
|
||||
= note: required because of the requirements on the impl of `UnwindSafe` for `&Cell<i32>`
|
||||
= note: required because it appears within the type `(&Cell<i32>,)`
|
||||
= note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -10,6 +10,7 @@ LL | bar(move|| foo(x));
|
||||
| `Rc<usize>` cannot be sent between threads safely
|
||||
|
|
||||
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`, the trait `Send` is not implemented for `Rc<usize>`
|
||||
= note: required because it appears within the type `(Rc<usize>,)`
|
||||
= note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,3 +1,11 @@
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/issue-36053-2.rs:7:32
|
||||
|
|
||||
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _`
|
||||
| |
|
||||
| expected signature of `for<'r> fn(&'r &str) -> _`
|
||||
|
||||
error[E0599]: no method named `count` found for struct `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` in the current scope
|
||||
--> $DIR/issue-36053-2.rs:7:55
|
||||
|
|
||||
@ -20,14 +28,6 @@ LL | pub struct Filter<I, P> {
|
||||
`Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: Iterator`
|
||||
which is required by `&mut Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>: Iterator`
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/issue-36053-2.rs:7:32
|
||||
|
|
||||
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| ^^^^^^ -------------- found signature of `for<'r> fn(&'r str) -> _`
|
||||
| |
|
||||
| expected signature of `for<'r> fn(&'r &str) -> _`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0599, E0631.
|
||||
|
@ -19,6 +19,7 @@ LL | F: Send + 'static,
|
||||
= help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6]`, the trait `Send` is not implemented for `Rc<()>`
|
||||
= note: required because it appears within the type `Port<()>`
|
||||
= note: required because it appears within the type `Foo`
|
||||
= note: required because it appears within the type `(Foo,)`
|
||||
= note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user