Skip to content

Commit 363590b

Browse files
committed
Merge from rust-lang/rust
2 parents ae1a648 + 5785c1d commit 363590b

File tree

5 files changed

+52
-195
lines changed

5 files changed

+52
-195
lines changed

crates/hir-ty/src/layout.rs

Lines changed: 36 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,22 @@ use base_db::ra_salsa::Cycle;
66
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
77
use hir_def::{
88
layout::{
9-
BackendRepr, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError,
10-
LayoutData, Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout,
9+
Float, Integer, LayoutCalculator, LayoutCalculatorError,
10+
LayoutData, Primitive, ReprOptions, Scalar, StructKind, TargetDataLayout,
1111
WrappingRange,
1212
},
1313
LocalFieldId, StructId,
1414
};
1515
use la_arena::{Idx, RawIdx};
1616
use rustc_abi::AddressSpace;
17-
use rustc_hashes::Hash64;
18-
use rustc_index::{IndexSlice, IndexVec};
17+
use rustc_index::IndexVec;
1918

2019
use triomphe::Arc;
2120

2221
use crate::{
2322
consteval::try_const_usize,
2423
db::{HirDatabase, InternedClosure},
2524
infer::normalize,
26-
layout::adt::struct_variant_idx,
2725
utils::ClosureSubst,
2826
Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
2927
};
@@ -125,82 +123,34 @@ impl<'a> LayoutCx<'a> {
125123
}
126124
}
127125

128-
// FIXME: move this to the `rustc_abi`.
129126
fn layout_of_simd_ty(
130127
db: &dyn HirDatabase,
131128
id: StructId,
129+
repr_packed: bool,
132130
subst: &Substitution,
133131
env: Arc<TraitEnvironment>,
134132
dl: &TargetDataLayout,
135133
) -> Result<Arc<Layout>, LayoutError> {
136-
let fields = db.field_types(id.into());
137-
138-
// Supported SIMD vectors are homogeneous ADTs with at least one field:
134+
// Supported SIMD vectors are homogeneous ADTs with exactly one array field:
139135
//
140-
// * #[repr(simd)] struct S(T, T, T, T);
141-
// * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
142136
// * #[repr(simd)] struct S([T; 4])
143137
//
144138
// where T is a primitive scalar (integer/float/pointer).
145-
146-
let f0_ty = match fields.iter().next() {
147-
Some(it) => it.1.clone().substitute(Interner, subst),
148-
None => return Err(LayoutError::InvalidSimdType),
149-
};
150-
151-
// The element type and number of elements of the SIMD vector
152-
// are obtained from:
153-
//
154-
// * the element type and length of the single array field, if
155-
// the first field is of array type, or
156-
//
157-
// * the homogeneous field type and the number of fields.
158-
let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
159-
// Extract the number of elements from the layout of the array field:
160-
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
161-
else {
162-
return Err(LayoutError::Unknown);
163-
};
164-
165-
(e_ty.clone(), count, true)
166-
} else {
167-
// First ADT field is not an array:
168-
(f0_ty, fields.iter().count() as u64, false)
139+
let fields = db.field_types(id.into());
140+
let mut fields = fields.iter();
141+
let Some(TyKind::Array(e_ty, e_len)) = fields
142+
.next()
143+
.filter(|_| fields.next().is_none())
144+
.map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone())
145+
else {
146+
return Err(LayoutError::InvalidSimdType);
169147
};
170148

171-
// Compute the ABI of the element type:
149+
let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;
172150
let e_ly = db.layout_of_ty(e_ty, env)?;
173-
let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else {
174-
return Err(LayoutError::Unknown);
175-
};
176151

177-
// Compute the size and alignment of the vector:
178-
let size = e_ly
179-
.size
180-
.checked_mul(e_len, dl)
181-
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
182-
let align = dl.llvmlike_vector_align(size);
183-
let size = size.align_to(align.abi);
184-
185-
// Compute the placement of the vector fields:
186-
let fields = if is_array {
187-
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
188-
} else {
189-
FieldsShape::Array { stride: e_ly.size, count: e_len }
190-
};
191-
192-
Ok(Arc::new(Layout {
193-
variants: Variants::Single { index: struct_variant_idx() },
194-
fields,
195-
backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
196-
largest_niche: e_ly.largest_niche,
197-
uninhabited: false,
198-
size,
199-
align,
200-
max_repr_align: None,
201-
unadjusted_abi_align: align.abi,
202-
randomization_seed: Hash64::ZERO,
203-
}))
152+
let cx = LayoutCx::new(dl);
153+
Ok(Arc::new(cx.calc.simd_type(e_ly, e_len, repr_packed)?))
204154
}
205155

206156
pub fn layout_of_ty_query(
@@ -215,13 +165,14 @@ pub fn layout_of_ty_query(
215165
let dl = &*target;
216166
let cx = LayoutCx::new(dl);
217167
let ty = normalize(db, trait_env.clone(), ty);
218-
let result = match ty.kind(Interner) {
168+
let kind = ty.kind(Interner);
169+
let result = match kind {
219170
TyKind::Adt(AdtId(def), subst) => {
220171
if let hir_def::AdtId::StructId(s) = def {
221172
let data = db.struct_data(*s);
222173
let repr = data.repr.unwrap_or_default();
223174
if repr.simd() {
224-
return layout_of_simd_ty(db, *s, subst, trait_env, &target);
175+
return layout_of_simd_ty(db, *s, repr.packed(), subst, trait_env, &target);
225176
}
226177
};
227178
return db.layout_of_adt(*def, subst.clone(), trait_env);
@@ -241,7 +192,7 @@ pub fn layout_of_ty_query(
241192
valid_range: WrappingRange { start: 0, end: 0x10FFFF },
242193
},
243194
),
244-
chalk_ir::Scalar::Int(i) => scalar(
195+
chalk_ir::Scalar::Int(i) => Layout::scalar(dl, scalar_unit(
245196
dl,
246197
Primitive::Int(
247198
match i {
@@ -254,8 +205,8 @@ pub fn layout_of_ty_query(
254205
},
255206
true,
256207
),
257-
),
258-
chalk_ir::Scalar::Uint(i) => scalar(
208+
)),
209+
chalk_ir::Scalar::Uint(i) => Layout::scalar(dl, scalar_unit(
259210
dl,
260211
Primitive::Int(
261212
match i {
@@ -268,16 +219,16 @@ pub fn layout_of_ty_query(
268219
},
269220
false,
270221
),
271-
),
272-
chalk_ir::Scalar::Float(f) => scalar(
222+
)),
223+
chalk_ir::Scalar::Float(f) => Layout::scalar(dl, scalar_unit(
273224
dl,
274225
Primitive::Float(match f {
275226
FloatTy::F16 => Float::F16,
276227
FloatTy::F32 => Float::F32,
277228
FloatTy::F64 => Float::F64,
278229
FloatTy::F128 => Float::F128,
279230
}),
280-
),
231+
)),
281232
},
282233
TyKind::Tuple(len, tys) => {
283234
let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
@@ -293,56 +244,16 @@ pub fn layout_of_ty_query(
293244
TyKind::Array(element, count) => {
294245
let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64;
295246
let element = db.layout_of_ty(element.clone(), trait_env)?;
296-
let size = element
297-
.size
298-
.checked_mul(count, dl)
299-
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
300-
301-
let backend_repr = BackendRepr::Memory { sized: true };
302-
303-
let largest_niche = if count != 0 { element.largest_niche } else { None };
304-
let uninhabited = if count != 0 { element.uninhabited } else { false };
305-
306-
Layout {
307-
variants: Variants::Single { index: struct_variant_idx() },
308-
fields: FieldsShape::Array { stride: element.size, count },
309-
backend_repr,
310-
largest_niche,
311-
uninhabited,
312-
align: element.align,
313-
size,
314-
max_repr_align: None,
315-
unadjusted_abi_align: element.align.abi,
316-
randomization_seed: Hash64::ZERO,
317-
}
247+
cx.calc.array_like::<_, _, ()>(&element, Some(count))?
318248
}
319249
TyKind::Slice(element) => {
320250
let element = db.layout_of_ty(element.clone(), trait_env)?;
321-
Layout {
322-
variants: Variants::Single { index: struct_variant_idx() },
323-
fields: FieldsShape::Array { stride: element.size, count: 0 },
324-
backend_repr: BackendRepr::Memory { sized: false },
325-
largest_niche: None,
326-
uninhabited: false,
327-
align: element.align,
328-
size: Size::ZERO,
329-
max_repr_align: None,
330-
unadjusted_abi_align: element.align.abi,
331-
randomization_seed: Hash64::ZERO,
332-
}
251+
cx.calc.array_like::<_, _, ()>(&element, None)?
252+
}
253+
TyKind::Str => {
254+
let element = scalar_unit(dl, Primitive::Int(Integer::I8, false));
255+
cx.calc.array_like::<_, _, ()>(&Layout::scalar(dl, element), None)?
333256
}
334-
TyKind::Str => Layout {
335-
variants: Variants::Single { index: struct_variant_idx() },
336-
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
337-
backend_repr: BackendRepr::Memory { sized: false },
338-
largest_niche: None,
339-
uninhabited: false,
340-
align: dl.i8_align,
341-
size: Size::ZERO,
342-
max_repr_align: None,
343-
unadjusted_abi_align: dl.i8_align.abi,
344-
randomization_seed: Hash64::ZERO,
345-
},
346257
// Potentially-wide pointers.
347258
TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => {
348259
let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA));
@@ -380,17 +291,12 @@ pub fn layout_of_ty_query(
380291
};
381292

382293
// Effectively a (ptr, meta) tuple.
383-
cx.calc.scalar_pair(data_ptr, metadata)
294+
LayoutData::scalar_pair(dl, data_ptr, metadata)
384295
}
385-
TyKind::FnDef(_, _) => layout_of_unit(&cx)?,
386-
TyKind::Never => cx.calc.layout_of_never_type(),
387-
TyKind::Dyn(_) | TyKind::Foreign(_) => {
388-
let mut unit = layout_of_unit(&cx)?;
389-
match &mut unit.backend_repr {
390-
BackendRepr::Memory { sized } => *sized = false,
391-
_ => return Err(LayoutError::Unknown),
392-
}
393-
unit
296+
TyKind::Never => LayoutData::never_type(dl),
297+
TyKind::FnDef(..) | TyKind::Dyn(_) | TyKind::Foreign(_) => {
298+
let sized = matches!(kind, TyKind::FnDef(..));
299+
LayoutData::unit(dl, sized)
394300
}
395301
TyKind::Function(_) => {
396302
let mut ptr = scalar_unit(dl, Primitive::Pointer(dl.instruction_address_space));
@@ -459,16 +365,6 @@ pub fn layout_of_ty_recover(
459365
Err(LayoutError::RecursiveTypeWithoutIndirection)
460366
}
461367

462-
fn layout_of_unit(cx: &LayoutCx<'_>) -> Result<Layout, LayoutError> {
463-
cx.calc
464-
.univariant::<RustcFieldIdx, RustcEnumVariantIdx, &&Layout>(
465-
IndexSlice::empty(),
466-
&ReprOptions::default(),
467-
StructKind::AlwaysSized,
468-
)
469-
.map_err(Into::into)
470-
}
471-
472368
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
473369
match pointee.kind(Interner) {
474370
TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => {
@@ -499,9 +395,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
499395
Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
500396
}
501397

502-
fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
503-
Layout::scalar(dl, scalar_unit(dl, value))
504-
}
505-
506398
#[cfg(test)]
507399
mod tests;

crates/hir-ty/src/layout/adt.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,12 @@ use triomphe::Arc;
1616
use crate::{
1717
db::HirDatabase,
1818
lang_items::is_unsafe_cell,
19-
layout::{field_ty, Layout, LayoutError, RustcEnumVariantIdx},
19+
layout::{field_ty, Layout, LayoutError},
2020
Substitution, TraitEnvironment,
2121
};
2222

2323
use super::LayoutCx;
2424

25-
pub(crate) fn struct_variant_idx() -> RustcEnumVariantIdx {
26-
RustcEnumVariantIdx(0)
27-
}
28-
2925
pub fn layout_of_adt_query(
3026
db: &dyn HirDatabase,
3127
def: AdtId,

crates/hir-ty/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ extern crate ra_ap_rustc_index as rustc_index;
1212
#[cfg(feature = "in-rust-tree")]
1313
extern crate rustc_abi;
1414

15-
#[cfg(feature = "in-rust-tree")]
16-
extern crate rustc_hashes;
17-
1815
#[cfg(not(feature = "in-rust-tree"))]
1916
extern crate ra_ap_rustc_abi as rustc_abi;
2017

crates/ide-db/src/generated/lints.rs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12311,40 +12311,6 @@ fn main() {
1231112311
```
1231212312

1231312313
will unnecessarily extend the stack frame.
12314-
"##,
12315-
default_severity: Severity::Allow,
12316-
warn_since: None,
12317-
deny_since: None,
12318-
},
12319-
Lint {
12320-
label: "unsized_tuple_coercion",
12321-
description: r##"# `unsized_tuple_coercion`
12322-
12323-
The tracking issue for this feature is: [#42877]
12324-
12325-
[#42877]: https://github.com/rust-lang/rust/issues/42877
12326-
12327-
------------------------
12328-
12329-
This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
12330-
12331-
```rust,ignore (partial-example)
12332-
impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
12333-
```
12334-
12335-
This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
12336-
12337-
```rust
12338-
#![feature(unsized_tuple_coercion)]
12339-
12340-
fn main() {
12341-
let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
12342-
let y : &([i32; 3], [i32]) = &x;
12343-
assert_eq!(y.1[0], 4);
12344-
}
12345-
```
12346-
12347-
[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
1234812314
"##,
1234912315
default_severity: Severity::Allow,
1235012316
warn_since: None,

0 commit comments

Comments
 (0)