diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs index e10b0938955af..ebcc244c8bc53 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/src/librustc_infer/infer/region_constraints/mod.rs @@ -13,7 +13,9 @@ use rustc_hir::def_id::DefId; use rustc_index::vec::IndexVec; use rustc_middle::ty::ReStatic; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{ReLateBound, ReVar}; +use rustc_middle::ty::{ + OutlivesPredicate, ReLateBound, ReVar, RegionKind, RegionOutlivesPredicate, +}; use rustc_middle::ty::{Region, RegionVid}; use rustc_span::Span; @@ -137,7 +139,7 @@ pub enum Constraint<'tcx> { RegSubReg(Region<'tcx>, Region<'tcx>), } -impl Constraint<'_> { +impl<'tcx> Constraint<'tcx> { pub fn involves_placeholders(&self) -> bool { match self { Constraint::VarSubVar(_, _) => false, @@ -145,6 +147,18 @@ impl Constraint<'_> { Constraint::RegSubReg(r, s) => r.is_placeholder() || s.is_placeholder(), } } + + pub fn to_region_outlives_predicate(&self, tcx: TyCtxt<'tcx>) -> RegionOutlivesPredicate<'tcx> { + match self { + Self::VarSubVar(a, b) => OutlivesPredicate( + tcx.mk_region(RegionKind::ReVar(*a)), + tcx.mk_region(RegionKind::ReVar(*b)), + ), + Self::RegSubVar(a, b) => OutlivesPredicate(a, tcx.mk_region(RegionKind::ReVar(*b))), + Self::VarSubReg(a, b) => OutlivesPredicate(tcx.mk_region(RegionKind::ReVar(*a)), b), + Self::RegSubReg(a, b) => OutlivesPredicate(a, b), + } + } } /// `VerifyGenericBound(T, _, R, RS)`: the parameter type `T` (or diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index c5813ae57a653..0cb2a9a53e64f 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -30,7 +30,10 @@ use crate::ty::{self, DefIdTree, Ty, TypeAndMut}; use crate::ty::{AdtDef, AdtKind, Const, Region}; use crate::ty::{BindingMode, BoundVar}; use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid}; -use crate::ty::{ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, ProjectionTy}; +use crate::ty::{ + ExistentialPredicate, InferTy, ParamTy, PolyFnSig, Predicate, ProjectionTy, + RegionOutlivesPredicate, +}; use crate::ty::{InferConst, ParamConst}; use crate::ty::{List, TyKind, TyS}; use rustc_ast::ast; @@ -91,6 +94,7 @@ pub struct CtxtInterners<'tcx> { canonical_var_infos: InternedSet<'tcx, List>, region: InternedSet<'tcx, RegionKind>, existential_predicates: InternedSet<'tcx, List>>, + region_outlives_predicates: InternedSet<'tcx, List>>, predicates: InternedSet<'tcx, List>>, clauses: InternedSet<'tcx, List>>, goal: InternedSet<'tcx, GoalKind<'tcx>>, @@ -109,6 +113,7 @@ impl<'tcx> CtxtInterners<'tcx> { substs: Default::default(), region: Default::default(), existential_predicates: Default::default(), + region_outlives_predicates: Default::default(), canonical_var_infos: Default::default(), predicates: Default::default(), clauses: Default::default(), @@ -1588,6 +1593,7 @@ nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>} nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>} nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} +nop_list_lift! {region_outlives_predicates; RegionOutlivesPredicate<'a> => RegionOutlivesPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo} nop_list_lift! {projs; ProjectionKind => ProjectionKind} @@ -2010,6 +2016,14 @@ impl<'tcx> Borrow<[ExistentialPredicate<'tcx>]> } } +impl<'tcx> Borrow<[RegionOutlivesPredicate<'tcx>]> + for Interned<'tcx, List>> +{ + fn borrow<'a>(&'a self) -> &'a [RegionOutlivesPredicate<'tcx>] { + &self.0[..] + } +} + impl<'tcx> Borrow<[Predicate<'tcx>]> for Interned<'tcx, List>> { fn borrow<'a>(&'a self) -> &'a [Predicate<'tcx>] { &self.0[..] @@ -2083,6 +2097,7 @@ slice_interners!( substs: _intern_substs(GenericArg<'tcx>), canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo), existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>), + region_outlives_predicates: _intern_region_outlive_predicates(RegionOutlivesPredicate<'tcx>), predicates: _intern_predicates(Predicate<'tcx>), clauses: _intern_clauses(Clause<'tcx>), goal_list: _intern_goals(Goal<'tcx>), @@ -2329,8 +2344,12 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List>>) -> Ty<'tcx> { - self.mk_ty(GeneratorWitness(types)) + pub fn mk_generator_witness( + self, + types: ty::Binder<&'tcx List>>, + region_outlives: ty::Binder<&'tcx List>>, + ) -> Ty<'tcx> { + self.mk_ty(GeneratorWitness(types, region_outlives)) } #[inline] @@ -2441,6 +2460,16 @@ impl<'tcx> TyCtxt<'tcx> { self._intern_existential_predicates(eps) } + pub fn intern_region_outlives_predicates( + self, + predicates: &[RegionOutlivesPredicate<'tcx>], + ) -> &'tcx List> { + if predicates.is_empty() { + List::empty() + } else { + self._intern_region_outlive_predicates(predicates) + } + } pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List> { // FIXME consider asking the input slice to be sorted to avoid // re-interning permutations, in which case that would be asserted @@ -2509,6 +2538,15 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_existential_predicates(xs)) } + pub fn mk_region_outlives_predicates< + I: InternAs<[RegionOutlivesPredicate<'tcx>], &'tcx List>>, + >( + self, + iter: I, + ) -> I::Output { + iter.intern_with(|xs| self.intern_region_outlives_predicates(xs)) + } + pub fn mk_predicates], &'tcx List>>>( self, iter: I, diff --git a/src/librustc_middle/ty/fast_reject.rs b/src/librustc_middle/ty/fast_reject.rs index 2a937d6581d6a..67ccdca7045eb 100644 --- a/src/librustc_middle/ty/fast_reject.rs +++ b/src/librustc_middle/ty/fast_reject.rs @@ -84,7 +84,7 @@ pub fn simplify_type( } ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)), ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)), - ty::GeneratorWitness(ref tys) => { + ty::GeneratorWitness(ref tys, _) => { Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())) } ty::Never => Some(NeverSimplifiedType), diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index a88f362810995..a8a1fc8f639af 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -81,7 +81,7 @@ impl FlagComputation { self.add_substs(substs); } - &ty::GeneratorWitness(ref ts) => { + &ty::GeneratorWitness(ref ts, _) => { let mut computation = FlagComputation::new(); computation.add_tys(&ts.skip_binder()[..]); self.add_bound_computation(&computation); diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 0abe44b31065d..05c8ac8119c28 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -795,6 +795,7 @@ impl<'a, T> IntoIterator for &'a List { } impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} +impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List> {} impl List { #[inline(always)] @@ -1371,7 +1372,7 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder>; /// equality between arbitrary types. Processing an instance of /// Form #2 eventually yields one of these `ProjectionPredicate` /// instances to normalize the LHS. -#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] #[derive(HashStable, TypeFoldable)] pub struct ProjectionPredicate<'tcx> { pub projection_ty: ProjectionTy<'tcx>, diff --git a/src/librustc_middle/ty/print/obsolete.rs b/src/librustc_middle/ty/print/obsolete.rs index 757a8bd23f62b..eeacced6ac61e 100644 --- a/src/librustc_middle/ty/print/obsolete.rs +++ b/src/librustc_middle/ty/print/obsolete.rs @@ -151,7 +151,7 @@ impl DefPathBasedNames<'tcx> { | ty::UnnormalizedProjection(..) | ty::Projection(..) | ty::Param(_) - | ty::GeneratorWitness(_) + | ty::GeneratorWitness(..) | ty::Opaque(..) => { if debug { output.push_str(&format!("`{:?}`", t)); diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 2d2704fc2bd89..bc01e6c32da08 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -643,7 +643,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("]")) } - ty::GeneratorWitness(types) => { + ty::GeneratorWitness(types, _) => { p!(in_binder(&types)); } ty::Closure(did, substs) => { diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index f4f0b6c41b92f..07aadf07ccaef 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -308,19 +308,38 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> { } } +impl<'tcx> Relate<'tcx> for ty::RegionOutlivesPredicate<'tcx> { + fn relate>( + relation: &mut R, + a: &Self, + b: &Self, + ) -> RelateResult<'tcx, Self> { + let a_region = relation.relate(&a.0, &b.0)?; + let b_region = relation.relate(&a.1, &b.1)?; + Ok(ty::OutlivesPredicate(a_region, b_region)) + } +} + #[derive(Debug, Clone, TypeFoldable)] -struct GeneratorWitness<'tcx>(&'tcx ty::List>); +struct GeneratorWitness<'tcx>( + &'tcx ty::List>, + &'tcx ty::List>, +); impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { fn relate>( relation: &mut R, - a: &GeneratorWitness<'tcx>, - b: &GeneratorWitness<'tcx>, - ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> { + a: &Self, + b: &Self, + ) -> RelateResult<'tcx, Self> { assert_eq!(a.0.len(), b.0.len()); + assert_eq!(a.1.len(), b.1.len()); let tcx = relation.tcx(); let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(a, b)))?; - Ok(GeneratorWitness(types)) + let predicates = tcx.mk_region_outlives_predicates( + a.1.iter().zip(b.1).map(|(a, b)| relation.relate(a, b)), + )?; + Ok(GeneratorWitness(types, predicates)) } } @@ -396,14 +415,19 @@ pub fn super_relate_tys>( Ok(tcx.mk_generator(a_id, substs, movability)) } - (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => { + ( + &ty::GeneratorWitness(a_types, a_outlive_predicates), + &ty::GeneratorWitness(b_types, b_outlive_predicates), + ) => { // Wrap our types with a temporary GeneratorWitness struct // inside the binder so we can related them - let a_types = a_types.map_bound(GeneratorWitness); - let b_types = b_types.map_bound(GeneratorWitness); + let a_witness = a_types.fuse(a_outlive_predicates, GeneratorWitness); + let b_witness = b_types.fuse(b_outlive_predicates, GeneratorWitness); // Then remove the GeneratorWitness for the result - let types = relation.relate(&a_types, &b_types)?.map_bound(|witness| witness.0); - Ok(tcx.mk_generator_witness(types)) + let types = relation.relate(&a_witness, &b_witness)?.map_bound(|witness| witness.0); + let predicates = + relation.relate(&a_witness, &b_witness)?.map_bound(|witness| witness.1); + Ok(tcx.mk_generator_witness(types, predicates)) } (&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => { diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 1c0ffe12314b3..0e0c762c4b6ae 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -800,6 +800,16 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> } } +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { + fn super_fold_with>(&self, folder: &mut F) -> Self { + fold_list(*self, folder, |tcx, v| tcx.intern_region_outlives_predicates(v)) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|p| p.visit_with(visitor)) + } +} + impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { fold_list(*self, folder, |tcx, v| tcx.intern_type_list(v)) @@ -884,7 +894,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::Generator(did, substs, movability) => { ty::Generator(did, substs.fold_with(folder), movability) } - ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)), + ty::GeneratorWitness(types, region_outlives) => { + ty::GeneratorWitness(types.fold_with(folder), region_outlives) + } ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)), ty::Projection(ref data) => ty::Projection(data.fold_with(folder)), ty::UnnormalizedProjection(ref data) => { @@ -928,7 +940,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::FnPtr(ref f) => f.visit_with(visitor), ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor), ty::Generator(_did, ref substs, _) => substs.visit_with(visitor), - ty::GeneratorWitness(ref types) => types.visit_with(visitor), + ty::GeneratorWitness(ref types, _) => types.visit_with(visitor), ty::Closure(_did, ref substs) => substs.visit_with(visitor), ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => { data.visit_with(visitor) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index ac5477edcc3c0..59a763c20bf2d 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -168,7 +168,10 @@ pub enum TyKind<'tcx> { /// A type representin the types stored inside a generator. /// This should only appear in GeneratorInteriors. - GeneratorWitness(Binder<&'tcx List>>), + GeneratorWitness( + Binder<&'tcx List>>, + Binder<&'tcx List>>, + ), /// The never type `!` Never, diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index b46caf7985208..e1daccb11aa39 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -734,7 +734,7 @@ impl<'tcx> ty::TyS<'tcx> { | ty::Dynamic(..) | ty::Foreign(_) | ty::Generator(..) - | ty::GeneratorWitness(_) + | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Opaque(..) | ty::Param(_) diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs index b6cadd0099656..8da2813a076f8 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/src/librustc_middle/ty/walk.rs @@ -154,7 +154,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::FnDef(_, substs) => { stack.extend(substs.iter().copied().rev()); } - ty::GeneratorWitness(ts) => { + ty::GeneratorWitness(ts, _) => { stack.extend(ts.skip_binder().iter().cloned().rev().map(|ty| ty.into())); } ty::FnPtr(sig) => { diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index b81a454cac408..0a1488c985c33 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -65,7 +65,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), ty::Foreign(def_id) => self.print_def_path(def_id, &[]), - ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"), + ty::GeneratorWitness(..) => bug!("type_name: unexpected `GeneratorWitness`"), } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 611d03405e2c8..5141a3fa38c8f 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -702,7 +702,7 @@ fn compute_layout<'tcx>( // MIR types let allowed_upvars = tcx.erase_regions(upvars); let allowed = match interior.kind { - ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s), + ty::GeneratorWitness(s, _) => tcx.erase_late_bound_regions(&s), _ => bug!(), }; diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs index 53df140e0b5ae..08e369a616eeb 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/src/librustc_symbol_mangling/v0.rs @@ -460,7 +460,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { self = r.print(self)?; } - ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"), + ty::GeneratorWitness(..) => bug!("symbol_names: unexpected `GeneratorWitness`"), } // Only cache types that do not refer to an enclosing diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs index dfbb07424487d..c749df59646c8 100644 --- a/src/librustc_trait_selection/traits/select.rs +++ b/src/librustc_trait_selection/traits/select.rs @@ -2312,7 +2312,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { substs.as_generator().upvar_tys().chain(iter::once(witness)).collect() } - ty::GeneratorWitness(types) => { + ty::GeneratorWitness(types, _) => { // This is sound because no regions in the witness can refer to // the binder outside the witness. So we'll effectivly reuse // the implicit binder around the witness. @@ -2335,7 +2335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn collect_predicates_for_types( &mut self, - param_env: ty::ParamEnv<'tcx>, + mut param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, @@ -2359,6 +2359,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .skip_binder() .iter() .flat_map(|ty| { + let param_env = if let ty::GeneratorWitness(_, predicates) = ty.kind { + let predicates: Vec<_> = param_env + .caller_bounds + .to_vec() + .into_iter() + .chain( + predicates + .skip_binder() + .into_iter() + .map(|&p| ty::Binder::bind(p).to_predicate()), + ) + .collect(); + param_env.caller_bounds = self.infcx.tcx.mk_predicates(predicates.iter()); + param_env + } else { + param_env + }; // binder moved -\ let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs index 97994b465b54c..effa1d736c7b4 100644 --- a/src/librustc_ty/needs_drop.rs +++ b/src/librustc_ty/needs_drop.rs @@ -107,7 +107,7 @@ where let witness = substs.witness(); let interior_tys = match &witness.kind { - ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys), + ty::GeneratorWitness(tys, _) => tcx.erase_late_bound_regions(tys), _ => bug!(), }; diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index ce376a08ea604..1bbf41a3eb441 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -188,7 +188,20 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); + let region_constraints = visitor.fcx.with_region_constraints(|constraints_data| { + constraints_data + .constraints + .keys() + .map(|constraints| constraints.to_region_outlives_predicate(fcx.tcx)) + .collect::>() + }); + debug!("region outlives inside generator: {:?}", region_constraints); + + let region_outlives_list = fcx.tcx.mk_region_outlives_predicates(region_constraints.iter()); + + let witness = fcx + .tcx + .mk_generator_witness(ty::Binder::bind(type_list), ty::Binder::bind(region_outlives_list)); // Store the generator types and spans into the tables for this generator. visitor.fcx.inh.tables.borrow_mut().generator_interior_types = type_causes; diff --git a/src/test/ui/async-await/issues/issue-64552.rs b/src/test/ui/async-await/issues/issue-64552.rs new file mode 100644 index 0000000000000..bf9a3e90ebed1 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-64552.rs @@ -0,0 +1,18 @@ +// edition: 2018 + +async fn use_async(_val: T) {} + +struct MyStruct<'a, T: 'a> { + val: &'a T +} + +unsafe impl<'a, T: 'a> Send for MyStruct<'a, T> {} + +async fn use_my_struct(val: MyStruct<'static, &'static u8>) { + use_async(val).await; +} + +fn main() { + let first_struct: MyStruct<'static, &'static u8> = MyStruct { val: &&26 }; + needs_send(use_my_struct(second_struct)); +}