diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a845431facac1..84e48151844b0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -410,6 +410,7 @@ impl<'tcx> BorrowExplanation<'tcx> { cx.add_sized_or_copy_bound_info(err, category, &path); if let ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: _, is_implicit_coercion: true, unsize_to: Some(unsize_ty), } = category diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 3bec07afa0fe0..e865592617943 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -565,6 +565,23 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.add_placeholder_from_predicate_note(&mut diag, &path); self.add_sized_or_copy_bound_info(&mut diag, category, &path); + for constraint in &path { + if let ConstraintCategory::Cast { is_raw_ptr_dyn_type_cast: true, .. } = + constraint.category + { + diag.span_note( + constraint.span, + format!("raw pointer casts of trait objects do not cast away lifetimes"), + ); + diag.note(format!( + "this was previously accepted by the compiler but was changed recently" + )); + diag.help(format!( + "see for more information" + )); + } + } + self.buffer_error(diag); } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b4ff3d66f3d5b..0bbdcdffdce7c 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2106,6 +2106,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // should be as limited as possible; the note is prone to false positives and this // constraint usually isn't best to blame. ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: _, unsize_to: Some(unsize_ty), is_implicit_coercion: true, } if target_region == self.universal_regions().fr_static diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 8c51225712093..e6d5f5a770881 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1104,7 +1104,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); let src_ty = self.normalize(src_ty, location); @@ -1112,7 +1116,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1133,7 +1141,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); // The type that we see in the fcx is like @@ -1146,7 +1158,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1175,7 +1191,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1208,7 +1228,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1237,6 +1261,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, is_implicit_coercion, unsize_to: Some(unsize_to), }, @@ -1260,7 +1285,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { .iter() .map(|predicate| predicate.with_self_ty(tcx, self_ty)), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); let outlives_predicate = tcx.mk_predicate(Binder::dummy( @@ -1271,7 +1300,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( outlives_predicate, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); } @@ -1294,7 +1327,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1357,7 +1394,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1505,7 +1546,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // // Note that other checks (such as denying `dyn Send` -> `dyn // Debug`) are in `rustc_hir_typeck`. - if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = *src_tail.kind() + if let ty::Dynamic(src_tty, src_lt, ty::Dyn) = *src_tail.kind() && let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = *dst_tail.kind() && src_tty.principal().is_some() && dst_tty.principal().is_some() @@ -1517,9 +1558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { tcx.mk_poly_existential_predicates( &src_tty.without_auto_traits().collect::>(), ), - // FIXME: Once we disallow casting `*const dyn Trait + 'short` - // to `*const dyn Trait + 'long`, then this can just be `src_lt`. - dst_lt, + src_lt, ty::Dyn, ); let dst_obj = Ty::new_dynamic( @@ -1538,6 +1577,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { dst_obj, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: true, is_implicit_coercion: false, unsize_to: None, }, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 3fc05f2caf2ad..efb34d200b235 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -116,6 +116,7 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation(AnnotationSource), Cast { + is_raw_ptr_dyn_type_cast: bool, /// Whether this cast is a coercion that was automatically inserted by the compiler. is_implicit_coercion: bool, /// Whether this is an unsizing coercion and if yes, this contains the target type. diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 26b2fb4472436..9c42a4ed8e6e9 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -578,8 +578,11 @@ impl Builder { let main = Box::new(main); // SAFETY: dynamic size and alignment of the Box remain the same. See below for why the // lifetime change is justified. - let main = - unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + Send + 'static)) }; + let main = unsafe { + let ptr = Box::into_raw(main) as *mut (dyn FnOnce() + Send + '_); + let ptr: *mut (dyn FnOnce() + Send + 'static) = crate::mem::transmute(ptr); + Box::from_raw(ptr) + }; Ok(JoinInner { // SAFETY: diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.rs b/tests/ui/cast/ptr-to-ptr-different-regions.rs index 0d525edc1332f..144fc1f3c326f 100644 --- a/tests/ui/cast/ptr-to-ptr-different-regions.rs +++ b/tests/ui/cast/ptr-to-ptr-different-regions.rs @@ -1,10 +1,10 @@ -//@ check-pass - // https://github.com/rust-lang/rust/issues/113257 #![deny(trivial_casts)] // The casts here are not trivial. -struct Foo<'a> { a: &'a () } +struct Foo<'a> { + a: &'a (), +} fn extend_lifetime_very_very_safely<'a>(v: *const Foo<'a>) -> *const Foo<'static> { // This should pass because raw pointer casts can do anything they want. @@ -15,6 +15,7 @@ trait Trait {} fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { ptr as _ + //~^ ERROR: lifetime may not live long enough } fn main() { diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.stderr b/tests/ui/cast/ptr-to-ptr-different-regions.stderr new file mode 100644 index 0000000000000..7e2b13976aee0 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-different-regions.stderr @@ -0,0 +1,31 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-different-regions.rs:17:5 + | +LL | fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { + | -- lifetime `'a` defined here +LL | ptr as _ + | ^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Trait` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-ptr-different-regions.rs:17:5 + | +LL | ptr as _ + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `ptr` + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'static)) -> *mut (dyn Trait + 'static) { + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr index 4e43d3b93fa35..c40e84328575f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr @@ -10,6 +10,13 @@ LL | let _send = unsend as *const S>; = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant = note: the struct `S` is invariant over the parameter `T` = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr index 4e43d3b93fa35..c40e84328575f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr @@ -10,6 +10,13 @@ LL | let _send = unsend as *const S>; = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant = note: the struct `S` is invariant over the parameter `T` = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr index b7319e3356bd0..f16647d70bdaa 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr @@ -5,6 +5,14 @@ LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { | -- lifetime `'a` defined here LL | x as _ | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-lt-ext.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 88a89dc4ac1b1..f7d15e2d41f12 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -12,6 +12,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 @@ -27,6 +34,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other @@ -44,6 +58,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 @@ -59,6 +80,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:20:5 @@ -97,6 +125,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 @@ -113,6 +148,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -133,6 +175,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 @@ -149,6 +198,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -168,6 +224,14 @@ LL | require_static(ptr as _) | | | `ptr` escapes the function body here | argument requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:46:20 + | +LL | require_static(ptr as _) + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 11 previous errors diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs index dbeee9d29441e..b4827cb1d4a94 100644 --- a/tests/ui/cast/ptr-to-trait-obj-ok.rs +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -1,5 +1,3 @@ -//@ check-pass - trait Trait<'a> {} fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { @@ -8,6 +6,7 @@ fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { x as _ + //~^ ERROR: lifetime may not live long enough } fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> { @@ -33,6 +32,7 @@ fn cast_inherent_lt_wrap<'a, 'b>( x: *mut (dyn Trait<'static> + 'a), ) -> *mut Wrapper + 'b> { x as _ + //~^ ERROR: lifetime may not live long enough } fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper> { diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.stderr b/tests/ui/cast/ptr-to-trait-obj-ok.stderr new file mode 100644 index 0000000000000..3c6ff469f10e7 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-ok.stderr @@ -0,0 +1,47 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-ok.rs:8:5 + | +LL | fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-ok.rs:8:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-ok.rs:34:5 + | +LL | fn cast_inherent_lt_wrap<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `Wrapper>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects do not cast away lifetimes + --> $DIR/ptr-to-trait-obj-ok.rs:34:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: aborting due to 2 previous errors +