Skip to content

Commit af8f85c

Browse files
committed
Auto merge of #32232 - jonas-schievink:issue31511, r=eddyb
Give a more accurate error on thin-to-fat ptr cast Fixes #31511
2 parents 170f470 + be2698c commit af8f85c

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

src/librustc_typeck/check/cast.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ enum CastError {
100100
CastToBool,
101101
CastToChar,
102102
DifferingKinds,
103+
/// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
104+
SizedUnsizedCast,
103105
IllegalCast,
104106
NeedViaPtr,
105107
NeedViaThinPtr,
@@ -165,6 +167,13 @@ impl<'tcx> CastCheck<'tcx> {
165167
fcx.infcx().ty_to_string(self.cast_ty))
166168
}, self.expr_ty, None);
167169
}
170+
CastError::SizedUnsizedCast => {
171+
fcx.type_error_message(self.span, |actual| {
172+
format!("cannot cast thin pointer `{}` to fat pointer `{}`",
173+
actual,
174+
fcx.infcx().ty_to_string(self.cast_ty))
175+
}, self.expr_ty, None)
176+
}
168177
CastError::DifferingKinds => {
169178
fcx.type_error_struct(self.span, |actual| {
170179
format!("casting `{}` as `{}` is invalid",
@@ -312,7 +321,7 @@ impl<'tcx> CastCheck<'tcx> {
312321

313322
// sized -> unsized? report invalid cast (don't complain about vtable kinds)
314323
if fcx.type_is_known_to_be_sized(m_expr.ty, self.span) {
315-
return Err(CastError::IllegalCast);
324+
return Err(CastError::SizedUnsizedCast);
316325
}
317326

318327
// vtable kinds must match

src/test/compile-fail/cast-rfc0401.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fn main()
8787
//~^^ HELP through a usize first
8888

8989
let _ = 42usize as *const [u8]; //~ ERROR casting
90-
let _ = v as *const [u8]; //~ ERROR casting
90+
let _ = v as *const [u8]; //~ ERROR cannot cast
9191
let _ = fat_v as *const Foo;
9292
//~^ ERROR `core::marker::Sized` is not implemented for the type `[u8]`
9393
let _ = foo as *const str; //~ ERROR casting

src/test/compile-fail/fat-ptr-cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn main() {
2424
//~^^ HELP cast through a thin pointer
2525

2626
// #22955
27-
q as *const [i32]; //~ ERROR casting
27+
q as *const [i32]; //~ ERROR cannot cast
2828

2929
// #21397
3030
let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting

src/test/compile-fail/issue-31511.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn cast_thin_to_fat(x: *const ()) {
12+
x as *const [u8];
13+
//~^ ERROR: cannot cast thin pointer `*const ()` to fat pointer `*const [u8]`
14+
}
15+
16+
fn main() {}

0 commit comments

Comments
 (0)