|
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