@@ -165,6 +165,12 @@ pub enum CastError {
165
165
NonScalar ,
166
166
UnknownExprPtrKind ,
167
167
UnknownCastPtrKind ,
168
+ /// Cast of int to (possibly) fat raw pointer.
169
+ ///
170
+ /// Argument is the specific name of the metadata in plain words, such as "a vtable"
171
+ /// or "a length". If this argument is None, then the metadata is unknown, for example,
172
+ /// when we're typechecking a type parameter with a ?Sized bound.
173
+ IntToFatCast ( Option < & ' static str > ) ,
168
174
}
169
175
170
176
impl From < ErrorGuaranteed > for CastError {
@@ -522,6 +528,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
522
528
. diagnostic ( )
523
529
. emit ( ) ;
524
530
}
531
+ CastError :: IntToFatCast ( known_metadata) => {
532
+ let mut err = struct_span_err ! (
533
+ fcx. tcx. sess,
534
+ self . cast_span,
535
+ E0606 ,
536
+ "cannot cast `{}` to a pointer that {} wide" ,
537
+ fcx. ty_to_string( self . expr_ty) ,
538
+ if known_metadata. is_some( ) { "is" } else { "may be" }
539
+ ) ;
540
+
541
+ err. span_label (
542
+ self . cast_span ,
543
+ format ! (
544
+ "creating a `{}` requires both an address and {}" ,
545
+ self . cast_ty,
546
+ known_metadata. unwrap_or( "type-specific metadata" ) ,
547
+ ) ,
548
+ ) ;
549
+
550
+ if fcx. tcx . sess . is_nightly_build ( ) {
551
+ err. span_label (
552
+ self . expr . span ,
553
+ "consider casting this expression to `*const ()`, \
554
+ then using `core::ptr::from_raw_parts`",
555
+ ) ;
556
+ }
557
+
558
+ err. emit ( ) ;
559
+ }
525
560
CastError :: UnknownCastPtrKind | CastError :: UnknownExprPtrKind => {
526
561
let unknown_cast_to = match e {
527
562
CastError :: UnknownCastPtrKind => true ,
@@ -900,7 +935,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
900
935
match fcx. pointer_kind ( m_cast. ty , self . span ) ? {
901
936
None => Err ( CastError :: UnknownCastPtrKind ) ,
902
937
Some ( PointerKind :: Thin ) => Ok ( CastKind :: AddrPtrCast ) ,
903
- _ => Err ( CastError :: IllegalCast ) ,
938
+ Some ( PointerKind :: Vtable ( _) ) => Err ( CastError :: IntToFatCast ( Some ( "a vtable" ) ) ) ,
939
+ Some ( PointerKind :: Length ) => Err ( CastError :: IntToFatCast ( Some ( "a length" ) ) ) ,
940
+ Some (
941
+ PointerKind :: OfProjection ( _)
942
+ | PointerKind :: OfOpaque ( _, _)
943
+ | PointerKind :: OfParam ( _) ,
944
+ ) => Err ( CastError :: IntToFatCast ( None ) ) ,
904
945
}
905
946
}
906
947
0 commit comments