|
1 | 1 | //! Compute the binary representation of a type |
2 | 2 |
|
3 | | -use std::{borrow::Cow, fmt}; |
| 3 | +use std::fmt; |
4 | 4 |
|
5 | 5 | use base_db::salsa::Cycle; |
6 | 6 | use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; |
7 | 7 | use hir_def::{ |
8 | 8 | layout::{ |
9 | | - Abi, FieldsShape, Float, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions, |
10 | | - Scalar, Size, StructKind, TargetDataLayout, WrappingRange, |
| 9 | + Abi, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutS, |
| 10 | + Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout, WrappingRange, |
11 | 11 | }, |
12 | 12 | LocalFieldId, StructId, |
13 | 13 | }; |
14 | 14 | use la_arena::{Idx, RawIdx}; |
15 | 15 | use rustc_abi::AddressSpace; |
16 | 16 | use rustc_index::{IndexSlice, IndexVec}; |
17 | 17 |
|
18 | | -use stdx::never; |
19 | 18 | use triomphe::Arc; |
20 | 19 |
|
21 | 20 | use crate::{ |
@@ -107,19 +106,24 @@ impl fmt::Display for LayoutError { |
107 | 106 | } |
108 | 107 | } |
109 | 108 |
|
110 | | -struct LayoutCx<'a> { |
111 | | - target: &'a TargetDataLayout, |
| 109 | +impl<F> From<LayoutCalculatorError<F>> for LayoutError { |
| 110 | + fn from(err: LayoutCalculatorError<F>) -> Self { |
| 111 | + match err { |
| 112 | + LayoutCalculatorError::UnexpectedUnsized(_) | LayoutCalculatorError::EmptyUnion => { |
| 113 | + LayoutError::Unknown |
| 114 | + } |
| 115 | + LayoutCalculatorError::SizeOverflow => LayoutError::SizeOverflow, |
| 116 | + } |
| 117 | + } |
112 | 118 | } |
113 | 119 |
|
114 | | -impl<'a> LayoutCalculator for LayoutCx<'a> { |
115 | | - type TargetDataLayoutRef = &'a TargetDataLayout; |
116 | | - |
117 | | - fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>) { |
118 | | - never!("{}", txt.into()); |
119 | | - } |
| 120 | +struct LayoutCx<'a> { |
| 121 | + calc: LayoutCalculator<&'a TargetDataLayout>, |
| 122 | +} |
120 | 123 |
|
121 | | - fn current_data_layout(&self) -> &'a TargetDataLayout { |
122 | | - self.target |
| 124 | +impl<'a> LayoutCx<'a> { |
| 125 | + fn new(target: &'a TargetDataLayout) -> Self { |
| 126 | + Self { calc: LayoutCalculator::new(target) } |
123 | 127 | } |
124 | 128 | } |
125 | 129 |
|
@@ -205,8 +209,8 @@ pub fn layout_of_ty_query( |
205 | 209 | let Ok(target) = db.target_data_layout(krate) else { |
206 | 210 | return Err(LayoutError::TargetLayoutNotAvailable); |
207 | 211 | }; |
208 | | - let cx = LayoutCx { target: &target }; |
209 | | - let dl = cx.current_data_layout(); |
| 212 | + let dl = &*target; |
| 213 | + let cx = LayoutCx::new(dl); |
210 | 214 | let ty = normalize(db, trait_env.clone(), ty); |
211 | 215 | let result = match ty.kind(Interner) { |
212 | 216 | TyKind::Adt(AdtId(def), subst) => { |
@@ -281,7 +285,7 @@ pub fn layout_of_ty_query( |
281 | 285 | .collect::<Result<Vec<_>, _>>()?; |
282 | 286 | let fields = fields.iter().map(|it| &**it).collect::<Vec<_>>(); |
283 | 287 | let fields = fields.iter().collect::<IndexVec<_, _>>(); |
284 | | - cx.univariant(dl, &fields, &ReprOptions::default(), kind).ok_or(LayoutError::Unknown)? |
| 288 | + cx.calc.univariant(&fields, &ReprOptions::default(), kind)? |
285 | 289 | } |
286 | 290 | TyKind::Array(element, count) => { |
287 | 291 | let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64; |
@@ -367,12 +371,12 @@ pub fn layout_of_ty_query( |
367 | 371 | }; |
368 | 372 |
|
369 | 373 | // Effectively a (ptr, meta) tuple. |
370 | | - cx.scalar_pair(data_ptr, metadata) |
| 374 | + cx.calc.scalar_pair(data_ptr, metadata) |
371 | 375 | } |
372 | | - TyKind::FnDef(_, _) => layout_of_unit(&cx, dl)?, |
373 | | - TyKind::Never => cx.layout_of_never_type(), |
| 376 | + TyKind::FnDef(_, _) => layout_of_unit(&cx)?, |
| 377 | + TyKind::Never => cx.calc.layout_of_never_type(), |
374 | 378 | TyKind::Dyn(_) | TyKind::Foreign(_) => { |
375 | | - let mut unit = layout_of_unit(&cx, dl)?; |
| 379 | + let mut unit = layout_of_unit(&cx)?; |
376 | 380 | match &mut unit.abi { |
377 | 381 | Abi::Aggregate { sized } => *sized = false, |
378 | 382 | _ => return Err(LayoutError::Unknown), |
@@ -414,8 +418,7 @@ pub fn layout_of_ty_query( |
414 | 418 | .collect::<Result<Vec<_>, _>>()?; |
415 | 419 | let fields = fields.iter().map(|it| &**it).collect::<Vec<_>>(); |
416 | 420 | let fields = fields.iter().collect::<IndexVec<_, _>>(); |
417 | | - cx.univariant(dl, &fields, &ReprOptions::default(), StructKind::AlwaysSized) |
418 | | - .ok_or(LayoutError::Unknown)? |
| 421 | + cx.calc.univariant(&fields, &ReprOptions::default(), StructKind::AlwaysSized)? |
419 | 422 | } |
420 | 423 | TyKind::Coroutine(_, _) | TyKind::CoroutineWitness(_, _) => { |
421 | 424 | return Err(LayoutError::NotImplemented) |
@@ -447,14 +450,14 @@ pub fn layout_of_ty_recover( |
447 | 450 | Err(LayoutError::RecursiveTypeWithoutIndirection) |
448 | 451 | } |
449 | 452 |
|
450 | | -fn layout_of_unit(cx: &LayoutCx<'_>, dl: &TargetDataLayout) -> Result<Layout, LayoutError> { |
451 | | - cx.univariant::<RustcFieldIdx, RustcEnumVariantIdx, &&Layout>( |
452 | | - dl, |
453 | | - IndexSlice::empty(), |
454 | | - &ReprOptions::default(), |
455 | | - StructKind::AlwaysSized, |
456 | | - ) |
457 | | - .ok_or(LayoutError::Unknown) |
| 453 | +fn layout_of_unit(cx: &LayoutCx<'_>) -> Result<Layout, LayoutError> { |
| 454 | + cx.calc |
| 455 | + .univariant::<RustcFieldIdx, RustcEnumVariantIdx, &&Layout>( |
| 456 | + IndexSlice::empty(), |
| 457 | + &ReprOptions::default(), |
| 458 | + StructKind::AlwaysSized, |
| 459 | + ) |
| 460 | + .map_err(Into::into) |
458 | 461 | } |
459 | 462 |
|
460 | 463 | fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty { |
|
0 commit comments