mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #136776 - BoxyUwU:forbid_object_lifetime_casts, r=lcnr
Forbid freely casting lifetime bounds of dyn-types Fixes rust-lang/rust#136702 Reference PR: - https://github.com/rust-lang/reference/pull/1951 Background reading about VTable calls/dyn compatibility: https://hackmd.io/zUp-sgZ0RFuFgsNfD4JqYw This PR causes us to start enforcing that lifetimes of dyn types are constrained through pointer casts. Currently on stable casting `*mut dyn Trait + 'a` to `*mut dyn Trait + 'b` passes with no requirements on `'a` or `'b`. Under this PR we now require `'a` to outlive `'b`. Even though the pointee of `*mut` pointers is considered to be invariant, we still use subtyping rather than equality. This mirrors how we support coercing `&mut dyn Trait + 'a` to `&mut dyn Trait + 'b` while requiring only `'a: 'b`. I believe this coercion is sound as there is no way for safe code to `mem::swap` two `dyn Trait`'s, and the same is definitely true of raw pointers. See the changes to this test: https://github.com/rust-lang/rust/pull/136776/files#diff-5523f20a800287a89c9f3e92646c887f3f7599be006b29dd9315f734a2137764 We also do not enforce any constraints on the lifetime of the dyn types if there are multiple pointer indirections. For example `*mut *mut dyn Trait + 'a` is allowed to be casted to `*mut *mut dyn Trait + 'b` with no requirements on `'a` or 'b`. This case is just a normal thin pointer cast where we do not care about the pointee type as there is no VTable in play. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-3b6c8da342bb6530524158d686455a545bb8fd6f59cf5ff50d1d991ce74c9649 Finally, this is about *any* cast where the pointee is *unsized* with dyn-type metadata, not just *literally* the pointee type being a dyn-type. E.g. casting `*mut Wrapper<dyn Trait + 'a>` to `*mut Wrapper<dyn Trait + 'b>` requires `'a: 'b` under this PR. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-ca0c44df62ae1ad1be70f892f01a59714336c7baf78602a5887ac1cf81145c96 ### Breakage This is a breaking change. Crater Report Comment: https://github.com/rust-lang/rust/pull/136776#issuecomment-3594165533 Generated Report: https://crater-reports.s3.amazonaws.com/pr-136776-2/index.html The majority of the breakage is caused by the `metrics` crate with 142 of the regressions, and the `may` crate with 14 of the regressions. The `metrics` crate has been fixed and has backported the fix to previous versions of the crate that were also affected. The`may` crate has also been fixed. PRs against affected crates have been opened and can be seen here: - secona/belalang#6 - tyilo/multi-vec#1 - luksan/lox#1 - pfzetto/bring-your-own-memory-demo#1 - vitorhnn/bfr#1 - paperartifact/PPSMC#1 - orengine/orengine#33 - maroider/async_scoped_task#1 - WorldSEnder/scoped_worker_thread#1 - Wind-Corporation/trapiron#5 - Thombrom/snek#1 - Xudong-Huang/may#113 - metrics-rs/metrics#564 - DouglasDwyer/micropool#1 - Magicolo/phylactery#8 - HellButcher/pulz#29 - UxuginPython/rrtk#1 - wvwwvwwv/scalable-delayed-dealloc#4 - ultimaweapon/tsuki#32 There were six regressions I've not filed PRs against: - https://github.com/weiznich/diesel_benches depends on a ~6year old version of diesel (where the regression is) - https://crates.io/crates/cogo/0.1.36 is an old version of cogo, since that release cogo has already been updated to not depend on pattern this PR breaks - https://github.com/cruise-automation/webviz-rust-framework is an archived read only repo so 🤷♀️ - makepad_render, doesn't seem to have source available and is 6 years old 🤷♀️ - outsource-heap - not on github - zaplib - I couldn't get it to compile locally as it failed to compile a dependency r? `@ghost`
This commit is contained in:
@@ -410,6 +410,7 @@ fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
|
||||
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
|
||||
|
||||
@@ -541,6 +541,23 @@ pub(crate) fn report_region_error(
|
||||
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 cannot extend lifetimes"),
|
||||
);
|
||||
diag.note(format!(
|
||||
"this was previously accepted by the compiler but was changed recently"
|
||||
));
|
||||
diag.help(format!(
|
||||
"see <https://github.com/rust-lang/rust/issues/141402> for more information"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
self.buffer_error(diag);
|
||||
}
|
||||
|
||||
|
||||
@@ -1697,6 +1697,7 @@ pub(crate) fn best_blame_constraint(
|
||||
// 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 to_region == self.universal_regions().fr_static
|
||||
|
||||
@@ -1113,7 +1113,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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);
|
||||
@@ -1121,7 +1125,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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,
|
||||
@@ -1142,7 +1150,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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
|
||||
@@ -1155,7 +1167,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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,
|
||||
@@ -1184,7 +1200,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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,
|
||||
@@ -1217,7 +1237,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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,
|
||||
@@ -1246,6 +1270,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
trait_ref,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion,
|
||||
unsize_to: Some(unsize_to),
|
||||
},
|
||||
@@ -1271,7 +1296,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
*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,
|
||||
@@ -1334,7 +1363,11 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
*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,
|
||||
@@ -1491,55 +1524,90 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
trait_ref,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: false,
|
||||
is_implicit_coercion: true,
|
||||
unsize_to: None,
|
||||
},
|
||||
);
|
||||
} else if let ty::Dynamic(src_tty, _src_lt) =
|
||||
} else if let ty::Dynamic(src_tty, src_lt) =
|
||||
*self.struct_tail(src.ty, location).kind()
|
||||
&& let ty::Dynamic(dst_tty, dst_lt) =
|
||||
*self.struct_tail(dst.ty, location).kind()
|
||||
&& src_tty.principal().is_some()
|
||||
&& dst_tty.principal().is_some()
|
||||
{
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
match (src_tty.principal(), dst_tty.principal()) {
|
||||
(Some(_), Some(_)) => {
|
||||
// This checks (lifetime part of) vtable validity for pointer casts,
|
||||
// which is irrelevant when there are aren't principal traits on
|
||||
// both sides (aka only auto traits).
|
||||
//
|
||||
// Note that other checks (such as denying `dyn Send` -> `dyn
|
||||
// Debug`) are in `rustc_hir_typeck`.
|
||||
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck` as FCW.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
// Remove auto traits.
|
||||
// Auto trait checks are handled in `rustc_hir_typeck`.
|
||||
let src_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&src_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
src_lt,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
);
|
||||
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
|
||||
// Trait parameters are invariant, the only part that actually has
|
||||
// subtyping here is the lifetime bound of the dyn-type.
|
||||
//
|
||||
// For example in `dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd` we would
|
||||
// require that `'a == 'c` but only that `'b: 'd`.
|
||||
//
|
||||
// We must not allow freely casting lifetime bounds of dyn-types as it
|
||||
// may allow for inaccessible VTable methods being callable: #136702
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: true,
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
(None, None) => {
|
||||
// The principalless (no non-auto traits) case:
|
||||
// You can only cast `dyn Send + 'long` to `dyn Send + 'short`.
|
||||
self.constraints.outlives_constraints.push(
|
||||
OutlivesConstraint {
|
||||
sup: src_lt.as_var(),
|
||||
sub: dst_lt.as_var(),
|
||||
locations: location.to_locations(),
|
||||
span: location.to_locations().span(self.body),
|
||||
category: ConstraintCategory::Cast {
|
||||
is_raw_ptr_dyn_type_cast: true,
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
variance_info: ty::VarianceDiagInfo::default(),
|
||||
from_closure: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
(None, Some(_)) => bug!(
|
||||
"introducing a principal should have errored in HIR typeck"
|
||||
),
|
||||
// FIXME: Once we disallow casting `*const dyn Trait + 'short`
|
||||
// to `*const dyn Trait + 'long`, then this can just be `src_lt`.
|
||||
dst_lt,
|
||||
);
|
||||
let dst_obj = Ty::new_dynamic(
|
||||
tcx,
|
||||
tcx.mk_poly_existential_predicates(
|
||||
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
|
||||
),
|
||||
dst_lt,
|
||||
);
|
||||
|
||||
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
|
||||
|
||||
self.sub_types(
|
||||
src_obj,
|
||||
dst_obj,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast {
|
||||
is_implicit_coercion: false,
|
||||
unsize_to: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
(Some(_), None) => {
|
||||
bug!("dropping the principal should have been an unsizing cast")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CastKind::Transmute => {
|
||||
|
||||
@@ -108,6 +108,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.
|
||||
|
||||
@@ -111,7 +111,12 @@ fn drop(&mut self) {
|
||||
// SAFETY: dynamic size and alignment of the Box remain the same. See below for why the
|
||||
// lifetime change is justified.
|
||||
let rust_start = unsafe {
|
||||
Box::from_raw(Box::into_raw(Box::new(rust_start)) as *mut (dyn FnOnce() + Send + 'static))
|
||||
let ptr = Box::into_raw(Box::new(rust_start));
|
||||
let ptr = crate::mem::transmute::<
|
||||
*mut (dyn FnOnce() + Send + '_),
|
||||
*mut (dyn FnOnce() + Send + 'static),
|
||||
>(ptr);
|
||||
Box::from_raw(ptr)
|
||||
};
|
||||
|
||||
let init = Box::new(ThreadInit { handle: thread.clone(), rust_start });
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//@ check-pass
|
||||
|
||||
// We allow extending lifetimes of object types if they are behind two layers
|
||||
// of pointer indirection (as opposed to one). This is because this is the more
|
||||
// general case of casting between two sized types (`*mut T as *mut U`).
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn bar<'a>(a: *mut *mut (dyn Trait + 'a)) -> *mut *mut (dyn Trait + 'static) {
|
||||
a as _
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,20 +1,24 @@
|
||||
//@ 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.
|
||||
// This should pass because raw pointer casts can do anything they want when
|
||||
// VTables are not involved
|
||||
v as *const Foo<'static>
|
||||
}
|
||||
|
||||
trait Trait {}
|
||||
|
||||
// We want to forbid this as extending lifetimes on object types may allow for
|
||||
// uncallable VTable methods to become accessible.
|
||||
fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) {
|
||||
ptr as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-different-regions.rs:20: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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-different-regions.rs:20:5
|
||||
|
|
||||
LL | ptr as _
|
||||
| ^^^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> 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
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// We want to forbid extending lifetimes on object types behind ptrs
|
||||
// as it may allow for uncallable VTable methods to become accessible.
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
struct MyWrap<T: ?Sized>(T);
|
||||
|
||||
fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> {
|
||||
a as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,31 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5
|
||||
|
|
||||
LL | fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | a as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `MyWrap<dyn Trait>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5
|
||||
|
|
||||
LL | a as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `a`
|
||||
|
|
||||
LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> {
|
||||
LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'a)> {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> {
|
||||
LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'static)>) -> *mut MyWrap<(dyn Trait + 'static)> {
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// Test cases involving principal-less traits (dyn Send without a primary trait).
|
||||
|
||||
struct Wrapper<T: ?Sized>(T);
|
||||
|
||||
// Cast to same auto trait
|
||||
|
||||
fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'b) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'b> {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'static> {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
// Cast to different auto trait
|
||||
|
||||
fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'static> {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
// Cast away principal trait
|
||||
trait Trait {}
|
||||
|
||||
fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'b) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
x as _
|
||||
//~^ ERROR: lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn unprincipled_wrap3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut Wrapper<dyn Send + 'b> {
|
||||
x as _
|
||||
//~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid
|
||||
}
|
||||
|
||||
fn unprincipled_wrap3_static<'a>(
|
||||
x: *mut (dyn Trait + Send + 'a)
|
||||
) -> *mut Wrapper<dyn Send + 'static> {
|
||||
x as _
|
||||
//~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,274 @@
|
||||
error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:63:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:70:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: the trait objects may have different vtables
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:8:5
|
||||
|
|
||||
LL | fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + '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 Send`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:8:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:13:5
|
||||
|
|
||||
LL | fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `dyn Send`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:13:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
|
||||
|
|
||||
LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'a) {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Send + 'static) {
|
||||
|
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:18:5
|
||||
|
|
||||
LL | fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + '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<dyn Send>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:18:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:23:5
|
||||
|
|
||||
LL | fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'static> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `Wrapper<dyn Send>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:23:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
|
||||
|
|
||||
LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'static> {
|
||||
LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'a> {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Send + 'static> {
|
||||
LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper<dyn Send + 'static> {
|
||||
|
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:30:5
|
||||
|
|
||||
LL | fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + '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 Sync`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:30:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:35:5
|
||||
|
|
||||
LL | fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `dyn Sync`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:35:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
|
||||
|
|
||||
LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) {
|
||||
LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'a) {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) {
|
||||
LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Sync + 'static) {
|
||||
|
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:40:5
|
||||
|
|
||||
LL | fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + '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<dyn Sync>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:40:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:45:5
|
||||
|
|
||||
LL | fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'static> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `Wrapper<dyn Sync>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:45:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
|
||||
|
|
||||
LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'static> {
|
||||
LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'a> {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'static> {
|
||||
LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper<dyn Sync + 'static> {
|
||||
|
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:53:5
|
||||
|
|
||||
LL | fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + '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 Send`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:53:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:58:5
|
||||
|
|
||||
LL | fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x as _
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of a mutable pointer to `dyn Send`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-ptr-principalless.rs:58:5
|
||||
|
|
||||
LL | x as _
|
||||
| ^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
|
||||
|
|
||||
LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'a) {
|
||||
|
|
||||
help: alternatively, add an explicit `'static` bound to this reference
|
||||
|
|
||||
LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) {
|
||||
LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'static)) -> *mut (dyn Send + 'static) {
|
||||
|
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0606`.
|
||||
@@ -6,6 +6,14 @@ LL | fn m<'a>() {
|
||||
LL | let unsend: *const dyn Cat<'a> = &();
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
|
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -6,6 +6,14 @@ LL | fn m<'a>() {
|
||||
LL | let unsend: *const dyn Cat<'a> = &();
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
|
||||
note: raw pointer casts of trait objects cannot extend lifetimes
|
||||
--> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17
|
||||
|
|
||||
LL | let _send = unsend as *const S<dyn Cat<'static>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this was previously accepted by the compiler but was changed recently
|
||||
= help: see <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -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 cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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 <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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<Assoc = dyn Send>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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<Assoc = dyn Send>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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<Assoc = dyn Trait<'_>>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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<Assoc = dyn Trait<'_>>`
|
||||
= note: mutable pointers are invariant over their type parameter
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
note: raw pointer casts of trait objects cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> 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 cannot extend 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 <https://github.com/rust-lang/rust/issues/141402> for more information
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
//@ check-pass
|
||||
|
||||
// Casting pointers to object types has some special rules in order to
|
||||
// ensure VTables stay valid. E.g.
|
||||
// - Cannot introduce new autotraits
|
||||
// - Cannot extend or shrink lifetimes in trait arguments
|
||||
// - Cannot extend the lifetime of the object type
|
||||
//
|
||||
// This test is a mostly miscellaneous set of examples of casts that do
|
||||
// uphold these rules
|
||||
|
||||
trait Trait<'a> {}
|
||||
|
||||
fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> {
|
||||
x as _
|
||||
}
|
||||
|
||||
fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) {
|
||||
fn cast_inherent_lt<'a: 'b, 'b>(
|
||||
x: *mut (dyn Trait<'static> + 'a)
|
||||
) -> *mut (dyn Trait<'static> + 'b) {
|
||||
x as _
|
||||
}
|
||||
|
||||
@@ -14,7 +25,11 @@ fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<
|
||||
x as _
|
||||
}
|
||||
|
||||
fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
|
||||
fn unprincipled<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
|
||||
x as _
|
||||
}
|
||||
|
||||
fn remove_principal<'a: 'b, 'b, 't>(x: *mut (dyn Trait<'t> + Send + 'a)) -> *mut (dyn Send + 'b) {
|
||||
x as _
|
||||
}
|
||||
|
||||
@@ -29,7 +44,7 @@ fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trai
|
||||
x as _
|
||||
}
|
||||
|
||||
fn cast_inherent_lt_wrap<'a, 'b>(
|
||||
fn cast_inherent_lt_wrap<'a: 'b, 'b>(
|
||||
x: *mut (dyn Trait<'static> + 'a),
|
||||
) -> *mut Wrapper<dyn Trait<'static> + 'b> {
|
||||
x as _
|
||||
@@ -39,7 +54,7 @@ fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapp
|
||||
x as _
|
||||
}
|
||||
|
||||
fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
|
||||
fn unprincipled_wrap<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
|
||||
x as _
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user