@@ -165,6 +165,12 @@ pub enum CastError {
165165 NonScalar ,
166166 UnknownExprPtrKind ,
167167 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 > ) ,
168174}
169175
170176impl From < ErrorGuaranteed > for CastError {
@@ -522,6 +528,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
522528 . diagnostic ( )
523529 . emit ( ) ;
524530 }
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+ }
525560 CastError :: UnknownCastPtrKind | CastError :: UnknownExprPtrKind => {
526561 let unknown_cast_to = match e {
527562 CastError :: UnknownCastPtrKind => true ,
@@ -900,7 +935,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
900935 match fcx. pointer_kind ( m_cast. ty , self . span ) ? {
901936 None => Err ( CastError :: UnknownCastPtrKind ) ,
902937 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 ) ) ,
904945 }
905946 }
906947
0 commit comments