Skip to content

Commit f0f90eb

Browse files
author
Lukas Markeffsky
committed
borrowck ptr-to-ptr casts via traits
1 parent b28e7ac commit f0f90eb

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22962296
let cast_ty_from = CastTy::from_ty(ty_from);
22972297
let cast_ty_to = CastTy::from_ty(*ty);
22982298
match (cast_ty_from, cast_ty_to) {
2299-
(Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => (),
2299+
(Some(CastTy::Ptr(pointee_from)), Some(CastTy::Ptr(pointee_to))) => {
2300+
let metadata_def_id =
2301+
tcx.require_lang_item(LangItem::Metadata, Some(span));
2302+
let metadata_from =
2303+
Ty::new_projection(tcx, metadata_def_id, [pointee_from.ty]);
2304+
let metadata_to =
2305+
Ty::new_projection(tcx, metadata_def_id, [pointee_to.ty]);
2306+
2307+
let predicate = ty::TraitRef::from_lang_item(
2308+
tcx,
2309+
LangItem::MetadataCast,
2310+
span,
2311+
[metadata_from, metadata_to],
2312+
);
2313+
2314+
self.prove_predicate(
2315+
predicate,
2316+
location.to_locations(),
2317+
ConstraintCategory::Cast { unsize_to: None },
2318+
);
2319+
}
23002320
_ => {
23012321
span_mirbug!(
23022322
self,

tests/ui/traits/metadata-cast-fail-lifetimes.rs

+10
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,13 @@ where
3737
cast(ptr)
3838
//~^ ERROR may not live long enough
3939
}
40+
41+
fn borrowck_cast<'short, 'long: 'short, T, U>(ptr: *mut T) -> *mut U
42+
where
43+
T: ?Sized + Pointee<Metadata = &'short ()>,
44+
U: ?Sized + Pointee<Metadata = &'long ()>,
45+
{
46+
// test that pointer-to-pointer casts are borrow-checked
47+
ptr as _
48+
//~^ ERROR may not live long enough
49+
}

tests/ui/traits/metadata-cast-fail-lifetimes.stderr

+14-1
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,18 @@ LL | cast(ptr)
3636
|
3737
= help: consider adding the following bound: `'short: 'long`
3838

39-
error: aborting due to 3 previous errors
39+
error: lifetime may not live long enough
40+
--> $DIR/metadata-cast-fail-lifetimes.rs:47:5
41+
|
42+
LL | fn borrowck_cast<'short, 'long: 'short, T, U>(ptr: *mut T) -> *mut U
43+
| ------ ----- lifetime `'long` defined here
44+
| |
45+
| lifetime `'short` defined here
46+
...
47+
LL | ptr as _
48+
| ^^^^^^^^ cast requires that `'short` must outlive `'long`
49+
|
50+
= help: consider adding the following bound: `'short: 'long`
51+
52+
error: aborting due to 4 previous errors
4053

0 commit comments

Comments
 (0)