1
1
//! Compute the binary representation of a type
2
2
3
+ use std:: fmt;
4
+
3
5
use chalk_ir:: { AdtId , FloatTy , IntTy , TyKind , UintTy } ;
4
6
use hir_def:: {
5
7
layout:: {
@@ -26,12 +28,6 @@ pub use self::{
26
28
target:: target_data_layout_query,
27
29
} ;
28
30
29
- macro_rules! user_error {
30
- ( $it: expr) => {
31
- return Err ( LayoutError :: UserError ( format!( $it) . into( ) ) )
32
- } ;
33
- }
34
-
35
31
mod adt;
36
32
mod target;
37
33
@@ -73,13 +69,38 @@ pub type Variants = hir_def::layout::Variants<RustcFieldIdx, RustcEnumVariantIdx
73
69
74
70
#[ derive( Debug , PartialEq , Eq , Clone ) ]
75
71
pub enum LayoutError {
76
- UserError ( Box < str > ) ,
77
- SizeOverflow ,
78
- TargetLayoutNotAvailable ,
79
- HasPlaceholder ,
72
+ HasErrorConst ,
80
73
HasErrorType ,
74
+ HasPlaceholder ,
75
+ InvalidSimdType ,
81
76
NotImplemented ,
77
+ RecursiveTypeWithoutIndirection ,
78
+ SizeOverflow ,
79
+ TargetLayoutNotAvailable ,
82
80
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
+ }
83
104
}
84
105
85
106
struct LayoutCx < ' a > {
@@ -118,9 +139,7 @@ fn layout_of_simd_ty(
118
139
119
140
let f0_ty = match fields. iter ( ) . next ( ) {
120
141
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 ) ,
124
143
} ;
125
144
126
145
// The element type and number of elements of the SIMD vector
@@ -134,7 +153,7 @@ fn layout_of_simd_ty(
134
153
// Extract the number of elements from the layout of the array field:
135
154
let FieldsShape :: Array { count, .. } = db. layout_of_ty ( f0_ty. clone ( ) , env. clone ( ) ) ?. fields
136
155
else {
137
- user_error ! ( "Array with non array layout" ) ;
156
+ return Err ( LayoutError :: Unknown ) ;
138
157
} ;
139
158
140
159
( e_ty. clone ( ) , count, true )
@@ -146,7 +165,7 @@ fn layout_of_simd_ty(
146
165
// Compute the ABI of the element type:
147
166
let e_ly = db. layout_of_ty ( e_ty, env. clone ( ) ) ?;
148
167
let Abi :: Scalar ( e_abi) = e_ly. abi else {
149
- user_error ! ( "simd type with inner non scalar type" ) ;
168
+ return Err ( LayoutError :: Unknown ) ;
150
169
} ;
151
170
152
171
// Compute the size and alignment of the vector:
@@ -259,9 +278,7 @@ pub fn layout_of_ty_query(
259
278
cx. univariant ( dl, & fields, & ReprOptions :: default ( ) , kind) . ok_or ( LayoutError :: Unknown ) ?
260
279
}
261
280
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 ;
265
282
let element = db. layout_of_ty ( element. clone ( ) , trait_env. clone ( ) ) ?;
266
283
let size = element. size . checked_mul ( count, dl) . ok_or ( LayoutError :: SizeOverflow ) ?;
267
284
@@ -352,7 +369,7 @@ pub fn layout_of_ty_query(
352
369
let mut unit = layout_of_unit ( & cx, dl) ?;
353
370
match unit. abi {
354
371
Abi :: Aggregate { ref mut sized } => * sized = false ,
355
- _ => user_error ! ( "bug" ) ,
372
+ _ => return Err ( LayoutError :: Unknown ) ,
356
373
}
357
374
unit
358
375
}
@@ -418,7 +435,7 @@ pub fn layout_of_ty_recover(
418
435
_: & Ty ,
419
436
_: & Arc < TraitEnvironment > ,
420
437
) -> Result < Arc < Layout > , LayoutError > {
421
- user_error ! ( "infinite sized recursive type" ) ;
438
+ Err ( LayoutError :: RecursiveTypeWithoutIndirection )
422
439
}
423
440
424
441
fn layout_of_unit ( cx : & LayoutCx < ' _ > , dl : & TargetDataLayout ) -> Result < Layout , LayoutError > {
0 commit comments