11//! Compute the binary representation of a type
22
3+ use std:: fmt;
4+
35use chalk_ir:: { AdtId , FloatTy , IntTy , TyKind , UintTy } ;
46use hir_def:: {
57 layout:: {
@@ -26,12 +28,6 @@ pub use self::{
2628 target:: target_data_layout_query,
2729} ;
2830
29- macro_rules! user_error {
30- ( $it: expr) => {
31- return Err ( LayoutError :: UserError ( format!( $it) . into( ) ) )
32- } ;
33- }
34-
3531mod adt;
3632mod target;
3733
@@ -73,13 +69,38 @@ pub type Variants = hir_def::layout::Variants<RustcFieldIdx, RustcEnumVariantIdx
7369
7470#[ derive( Debug , PartialEq , Eq , Clone ) ]
7571pub enum LayoutError {
76- UserError ( Box < str > ) ,
77- SizeOverflow ,
78- TargetLayoutNotAvailable ,
79- HasPlaceholder ,
72+ HasErrorConst ,
8073 HasErrorType ,
74+ HasPlaceholder ,
75+ InvalidSimdType ,
8176 NotImplemented ,
77+ RecursiveTypeWithoutIndirection ,
78+ SizeOverflow ,
79+ TargetLayoutNotAvailable ,
8280 Unknown ,
81+ UserReprTooSmall ,
82+ }
83+
84+ impl std:: error:: Error for LayoutError { }
85+ impl fmt:: Display for LayoutError {
86+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
87+ match self {
88+ LayoutError :: HasErrorConst => write ! ( f, "type contains an unevaluatable const" ) ,
89+ LayoutError :: HasErrorType => write ! ( f, "type contains an error" ) ,
90+ LayoutError :: HasPlaceholder => write ! ( f, "type contains placeholders" ) ,
91+ LayoutError :: InvalidSimdType => write ! ( f, "invalid simd type definition" ) ,
92+ LayoutError :: NotImplemented => write ! ( f, "not implemented" ) ,
93+ LayoutError :: RecursiveTypeWithoutIndirection => {
94+ write ! ( f, "recursive type without indirection" )
95+ }
96+ LayoutError :: SizeOverflow => write ! ( f, "size overflow" ) ,
97+ LayoutError :: TargetLayoutNotAvailable => write ! ( f, "target layout not available" ) ,
98+ LayoutError :: Unknown => write ! ( f, "unknown" ) ,
99+ LayoutError :: UserReprTooSmall => {
100+ write ! ( f, "the `#[repr]` hint is too small to hold the discriminants of the enum" )
101+ }
102+ }
103+ }
83104}
84105
85106struct LayoutCx < ' a > {
@@ -118,9 +139,7 @@ fn layout_of_simd_ty(
118139
119140 let f0_ty = match fields. iter ( ) . next ( ) {
120141 Some ( it) => it. 1 . clone ( ) . substitute ( Interner , subst) ,
121- None => {
122- user_error ! ( "simd type with zero fields" ) ;
123- }
142+ None => return Err ( LayoutError :: InvalidSimdType ) ,
124143 } ;
125144
126145 // The element type and number of elements of the SIMD vector
@@ -134,7 +153,7 @@ fn layout_of_simd_ty(
134153 // Extract the number of elements from the layout of the array field:
135154 let FieldsShape :: Array { count, .. } = db. layout_of_ty ( f0_ty. clone ( ) , env. clone ( ) ) ?. fields
136155 else {
137- user_error ! ( "Array with non array layout" ) ;
156+ return Err ( LayoutError :: Unknown ) ;
138157 } ;
139158
140159 ( e_ty. clone ( ) , count, true )
@@ -146,7 +165,7 @@ fn layout_of_simd_ty(
146165 // Compute the ABI of the element type:
147166 let e_ly = db. layout_of_ty ( e_ty, env. clone ( ) ) ?;
148167 let Abi :: Scalar ( e_abi) = e_ly. abi else {
149- user_error ! ( "simd type with inner non scalar type" ) ;
168+ return Err ( LayoutError :: Unknown ) ;
150169 } ;
151170
152171 // Compute the size and alignment of the vector:
@@ -259,9 +278,7 @@ pub fn layout_of_ty_query(
259278 cx. univariant ( dl, & fields, & ReprOptions :: default ( ) , kind) . ok_or ( LayoutError :: Unknown ) ?
260279 }
261280 TyKind :: Array ( element, count) => {
262- let count = try_const_usize ( db, & count) . ok_or ( LayoutError :: UserError ( Box :: from (
263- "unevaluated or mistyped const generic parameter" ,
264- ) ) ) ? as u64 ;
281+ let count = try_const_usize ( db, & count) . ok_or ( LayoutError :: HasErrorConst ) ? as u64 ;
265282 let element = db. layout_of_ty ( element. clone ( ) , trait_env. clone ( ) ) ?;
266283 let size = element. size . checked_mul ( count, dl) . ok_or ( LayoutError :: SizeOverflow ) ?;
267284
@@ -352,7 +369,7 @@ pub fn layout_of_ty_query(
352369 let mut unit = layout_of_unit ( & cx, dl) ?;
353370 match unit. abi {
354371 Abi :: Aggregate { ref mut sized } => * sized = false ,
355- _ => user_error ! ( "bug" ) ,
372+ _ => return Err ( LayoutError :: Unknown ) ,
356373 }
357374 unit
358375 }
@@ -418,7 +435,7 @@ pub fn layout_of_ty_recover(
418435 _: & Ty ,
419436 _: & Arc < TraitEnvironment > ,
420437) -> Result < Arc < Layout > , LayoutError > {
421- user_error ! ( "infinite sized recursive type" ) ;
438+ Err ( LayoutError :: RecursiveTypeWithoutIndirection )
422439}
423440
424441fn layout_of_unit ( cx : & LayoutCx < ' _ > , dl : & TargetDataLayout ) -> Result < Layout , LayoutError > {
0 commit comments