mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 10:39:45 +00:00
Merge pull request #19331 from lnicola/sync-from-rust
minor: Sync from downstream
This commit is contained in:
commit
be48993351
10 changed files with 106 additions and 246 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
|
@ -626,7 +626,6 @@ dependencies = [
|
||||||
"oorandom",
|
"oorandom",
|
||||||
"project-model",
|
"project-model",
|
||||||
"ra-ap-rustc_abi",
|
"ra-ap-rustc_abi",
|
||||||
"ra-ap-rustc_hashes",
|
|
||||||
"ra-ap-rustc_index",
|
"ra-ap-rustc_index",
|
||||||
"ra-ap-rustc_pattern_analysis",
|
"ra-ap-rustc_pattern_analysis",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
|
|
@ -1504,9 +1503,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_abi"
|
name = "ra-ap-rustc_abi"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b42cccfff8091a4c3397736518774dbad619e82f8def6f70d8e46dbbe396007"
|
checksum = "f1651b0f7e8c3eb7c27a88f39d277e69c32bfe58e3be174d286c1a24d6a7a4d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.7.0",
|
"bitflags 2.7.0",
|
||||||
"ra-ap-rustc_hashes",
|
"ra-ap-rustc_hashes",
|
||||||
|
|
@ -1516,18 +1515,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_hashes"
|
name = "ra-ap-rustc_hashes"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46d8bd34ed6552c8cac1764106ef5adbeef3e5c7700e0ceb4c83a47a631894fe"
|
checksum = "2bcd85e93dc0ea850bcfe7957a115957df799ccbc9eea488bdee5ec6780d212b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-stable-hash",
|
"rustc-stable-hash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_index"
|
name = "ra-ap-rustc_index"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93799e4dccbbd47f8b66bc0aa42effc1b7077aaee09d8a40b86b8d659b80c7b7"
|
checksum = "62b295fc0640cd9fe0ecab872ee4a17a96f90a3998ec9f0c4765e9b8415c12cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_index_macros",
|
"ra-ap-rustc_index_macros",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
|
@ -1535,9 +1534,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_index_macros"
|
name = "ra-ap-rustc_index_macros"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30baa5d00f94ba437a9dcaf7ae074ebe4f367bb05a4c2835e0aa2e7af3463aac"
|
checksum = "c675f4257023aa933882906f13802cae287e88cc39ab13cbb96809083db0c801"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1546,9 +1545,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_lexer"
|
name = "ra-ap-rustc_lexer"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3004d1d1b50afe3e1f9cdd428a282da7ffbf5f26dd8bf04af0d651d44e4873d8"
|
checksum = "c8358702c2a510ea84ba5801ddc047d9ad9520902cfb0e6173277610cdce2c9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"unicode-properties",
|
"unicode-properties",
|
||||||
|
|
@ -1557,9 +1556,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_parse_format"
|
name = "ra-ap-rustc_parse_format"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb57e5124a64aaaf92c06130fbc1b8e1d547b5a2a96081f1f848e31c211df5d2"
|
checksum = "b98f402011d46732c35c47bfd111dec0495747fef2ec900ddee7fe15d78449a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_index",
|
"ra-ap-rustc_index",
|
||||||
"ra-ap-rustc_lexer",
|
"ra-ap-rustc_lexer",
|
||||||
|
|
@ -1567,9 +1566,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ra-ap-rustc_pattern_analysis"
|
name = "ra-ap-rustc_pattern_analysis"
|
||||||
version = "0.98.0"
|
version = "0.100.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e427c3d30e4bdff28abd6b0ef3e6f4dfab44acd9468a4954eeff8717d8df8819"
|
checksum = "bef3ff73fa4653252ffe1d1e9177a446f49ef46d97140e4816b7ff2dad59ed53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ra-ap-rustc_index",
|
"ra-ap-rustc_index",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
|
|
|
||||||
12
Cargo.toml
12
Cargo.toml
|
|
@ -85,12 +85,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
|
||||||
vfs = { path = "./crates/vfs", version = "0.0.0" }
|
vfs = { path = "./crates/vfs", version = "0.0.0" }
|
||||||
edition = { path = "./crates/edition", version = "0.0.0" }
|
edition = { path = "./crates/edition", version = "0.0.0" }
|
||||||
|
|
||||||
ra-ap-rustc_hashes = { version = "0.98", default-features = false }
|
ra-ap-rustc_hashes = { version = "0.100", default-features = false }
|
||||||
ra-ap-rustc_lexer = { version = "0.98", default-features = false }
|
ra-ap-rustc_lexer = { version = "0.100", default-features = false }
|
||||||
ra-ap-rustc_parse_format = { version = "0.98", default-features = false }
|
ra-ap-rustc_parse_format = { version = "0.100", default-features = false }
|
||||||
ra-ap-rustc_index = { version = "0.98", default-features = false }
|
ra-ap-rustc_index = { version = "0.100", default-features = false }
|
||||||
ra-ap-rustc_abi = { version = "0.98", default-features = false }
|
ra-ap-rustc_abi = { version = "0.100", default-features = false }
|
||||||
ra-ap-rustc_pattern_analysis = { version = "0.98", default-features = false }
|
ra-ap-rustc_pattern_analysis = { version = "0.100", default-features = false }
|
||||||
|
|
||||||
# local crates that aren't published to crates.io. These should not have versions.
|
# local crates that aren't published to crates.io. These should not have versions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ indexmap.workspace = true
|
||||||
rustc_apfloat = "0.2.0"
|
rustc_apfloat = "0.2.0"
|
||||||
|
|
||||||
ra-ap-rustc_abi.workspace = true
|
ra-ap-rustc_abi.workspace = true
|
||||||
ra-ap-rustc_hashes.workspace = true
|
|
||||||
ra-ap-rustc_index.workspace = true
|
ra-ap-rustc_index.workspace = true
|
||||||
ra-ap-rustc_pattern_analysis.workspace = true
|
ra-ap-rustc_pattern_analysis.workspace = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,14 @@ use base_db::ra_salsa::Cycle;
|
||||||
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
layout::{
|
layout::{
|
||||||
BackendRepr, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError,
|
Float, Integer, LayoutCalculator, LayoutCalculatorError, LayoutData, Primitive,
|
||||||
LayoutData, Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout,
|
ReprOptions, Scalar, StructKind, TargetDataLayout, WrappingRange,
|
||||||
WrappingRange,
|
|
||||||
},
|
},
|
||||||
LocalFieldId, StructId,
|
LocalFieldId, StructId,
|
||||||
};
|
};
|
||||||
use la_arena::{Idx, RawIdx};
|
use la_arena::{Idx, RawIdx};
|
||||||
use rustc_abi::AddressSpace;
|
use rustc_abi::AddressSpace;
|
||||||
use rustc_hashes::Hash64;
|
use rustc_index::IndexVec;
|
||||||
use rustc_index::{IndexSlice, IndexVec};
|
|
||||||
|
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
|
@ -23,7 +21,6 @@ use crate::{
|
||||||
consteval::try_const_usize,
|
consteval::try_const_usize,
|
||||||
db::{HirDatabase, InternedClosure},
|
db::{HirDatabase, InternedClosure},
|
||||||
infer::normalize,
|
infer::normalize,
|
||||||
layout::adt::struct_variant_idx,
|
|
||||||
utils::ClosureSubst,
|
utils::ClosureSubst,
|
||||||
Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
|
Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
|
||||||
};
|
};
|
||||||
|
|
@ -125,82 +122,34 @@ impl<'a> LayoutCx<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move this to the `rustc_abi`.
|
|
||||||
fn layout_of_simd_ty(
|
fn layout_of_simd_ty(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
id: StructId,
|
id: StructId,
|
||||||
|
repr_packed: bool,
|
||||||
subst: &Substitution,
|
subst: &Substitution,
|
||||||
env: Arc<TraitEnvironment>,
|
env: Arc<TraitEnvironment>,
|
||||||
dl: &TargetDataLayout,
|
dl: &TargetDataLayout,
|
||||||
) -> Result<Arc<Layout>, LayoutError> {
|
) -> Result<Arc<Layout>, LayoutError> {
|
||||||
let fields = db.field_types(id.into());
|
// Supported SIMD vectors are homogeneous ADTs with exactly one array field:
|
||||||
|
|
||||||
// Supported SIMD vectors are homogeneous ADTs with at least one field:
|
|
||||||
//
|
//
|
||||||
// * #[repr(simd)] struct S(T, T, T, T);
|
|
||||||
// * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
|
|
||||||
// * #[repr(simd)] struct S([T; 4])
|
// * #[repr(simd)] struct S([T; 4])
|
||||||
//
|
//
|
||||||
// where T is a primitive scalar (integer/float/pointer).
|
// where T is a primitive scalar (integer/float/pointer).
|
||||||
|
let fields = db.field_types(id.into());
|
||||||
let f0_ty = match fields.iter().next() {
|
let mut fields = fields.iter();
|
||||||
Some(it) => it.1.clone().substitute(Interner, subst),
|
let Some(TyKind::Array(e_ty, e_len)) = fields
|
||||||
None => return Err(LayoutError::InvalidSimdType),
|
.next()
|
||||||
|
.filter(|_| fields.next().is_none())
|
||||||
|
.map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone())
|
||||||
|
else {
|
||||||
|
return Err(LayoutError::InvalidSimdType);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The element type and number of elements of the SIMD vector
|
let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;
|
||||||
// are obtained from:
|
|
||||||
//
|
|
||||||
// * the element type and length of the single array field, if
|
|
||||||
// the first field is of array type, or
|
|
||||||
//
|
|
||||||
// * the homogeneous field type and the number of fields.
|
|
||||||
let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
|
|
||||||
// Extract the number of elements from the layout of the array field:
|
|
||||||
let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
|
|
||||||
else {
|
|
||||||
return Err(LayoutError::Unknown);
|
|
||||||
};
|
|
||||||
|
|
||||||
(e_ty.clone(), count, true)
|
|
||||||
} else {
|
|
||||||
// First ADT field is not an array:
|
|
||||||
(f0_ty, fields.iter().count() as u64, false)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the ABI of the element type:
|
|
||||||
let e_ly = db.layout_of_ty(e_ty, env)?;
|
let e_ly = db.layout_of_ty(e_ty, env)?;
|
||||||
let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else {
|
|
||||||
return Err(LayoutError::Unknown);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the size and alignment of the vector:
|
let cx = LayoutCx::new(dl);
|
||||||
let size = e_ly
|
Ok(Arc::new(cx.calc.simd_type(e_ly, e_len, repr_packed)?))
|
||||||
.size
|
|
||||||
.checked_mul(e_len, dl)
|
|
||||||
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
|
|
||||||
let align = dl.llvmlike_vector_align(size);
|
|
||||||
let size = size.align_to(align.abi);
|
|
||||||
|
|
||||||
// Compute the placement of the vector fields:
|
|
||||||
let fields = if is_array {
|
|
||||||
FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
|
|
||||||
} else {
|
|
||||||
FieldsShape::Array { stride: e_ly.size, count: e_len }
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Arc::new(Layout {
|
|
||||||
variants: Variants::Single { index: struct_variant_idx() },
|
|
||||||
fields,
|
|
||||||
backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
|
|
||||||
largest_niche: e_ly.largest_niche,
|
|
||||||
uninhabited: false,
|
|
||||||
size,
|
|
||||||
align,
|
|
||||||
max_repr_align: None,
|
|
||||||
unadjusted_abi_align: align.abi,
|
|
||||||
randomization_seed: Hash64::ZERO,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_of_ty_query(
|
pub fn layout_of_ty_query(
|
||||||
|
|
@ -215,13 +164,14 @@ pub fn layout_of_ty_query(
|
||||||
let dl = &*target;
|
let dl = &*target;
|
||||||
let cx = LayoutCx::new(dl);
|
let cx = LayoutCx::new(dl);
|
||||||
let ty = normalize(db, trait_env.clone(), ty);
|
let ty = normalize(db, trait_env.clone(), ty);
|
||||||
let result = match ty.kind(Interner) {
|
let kind = ty.kind(Interner);
|
||||||
|
let result = match kind {
|
||||||
TyKind::Adt(AdtId(def), subst) => {
|
TyKind::Adt(AdtId(def), subst) => {
|
||||||
if let hir_def::AdtId::StructId(s) = def {
|
if let hir_def::AdtId::StructId(s) = def {
|
||||||
let data = db.struct_data(*s);
|
let data = db.struct_data(*s);
|
||||||
let repr = data.repr.unwrap_or_default();
|
let repr = data.repr.unwrap_or_default();
|
||||||
if repr.simd() {
|
if repr.simd() {
|
||||||
return layout_of_simd_ty(db, *s, subst, trait_env, &target);
|
return layout_of_simd_ty(db, *s, repr.packed(), subst, trait_env, &target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return db.layout_of_adt(*def, subst.clone(), trait_env);
|
return db.layout_of_adt(*def, subst.clone(), trait_env);
|
||||||
|
|
@ -241,42 +191,51 @@ pub fn layout_of_ty_query(
|
||||||
valid_range: WrappingRange { start: 0, end: 0x10FFFF },
|
valid_range: WrappingRange { start: 0, end: 0x10FFFF },
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
chalk_ir::Scalar::Int(i) => scalar(
|
chalk_ir::Scalar::Int(i) => Layout::scalar(
|
||||||
dl,
|
dl,
|
||||||
Primitive::Int(
|
scalar_unit(
|
||||||
match i {
|
dl,
|
||||||
IntTy::Isize => dl.ptr_sized_integer(),
|
Primitive::Int(
|
||||||
IntTy::I8 => Integer::I8,
|
match i {
|
||||||
IntTy::I16 => Integer::I16,
|
IntTy::Isize => dl.ptr_sized_integer(),
|
||||||
IntTy::I32 => Integer::I32,
|
IntTy::I8 => Integer::I8,
|
||||||
IntTy::I64 => Integer::I64,
|
IntTy::I16 => Integer::I16,
|
||||||
IntTy::I128 => Integer::I128,
|
IntTy::I32 => Integer::I32,
|
||||||
},
|
IntTy::I64 => Integer::I64,
|
||||||
true,
|
IntTy::I128 => Integer::I128,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
chalk_ir::Scalar::Uint(i) => scalar(
|
chalk_ir::Scalar::Uint(i) => Layout::scalar(
|
||||||
dl,
|
dl,
|
||||||
Primitive::Int(
|
scalar_unit(
|
||||||
match i {
|
dl,
|
||||||
UintTy::Usize => dl.ptr_sized_integer(),
|
Primitive::Int(
|
||||||
UintTy::U8 => Integer::I8,
|
match i {
|
||||||
UintTy::U16 => Integer::I16,
|
UintTy::Usize => dl.ptr_sized_integer(),
|
||||||
UintTy::U32 => Integer::I32,
|
UintTy::U8 => Integer::I8,
|
||||||
UintTy::U64 => Integer::I64,
|
UintTy::U16 => Integer::I16,
|
||||||
UintTy::U128 => Integer::I128,
|
UintTy::U32 => Integer::I32,
|
||||||
},
|
UintTy::U64 => Integer::I64,
|
||||||
false,
|
UintTy::U128 => Integer::I128,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
chalk_ir::Scalar::Float(f) => scalar(
|
chalk_ir::Scalar::Float(f) => Layout::scalar(
|
||||||
dl,
|
dl,
|
||||||
Primitive::Float(match f {
|
scalar_unit(
|
||||||
FloatTy::F16 => Float::F16,
|
dl,
|
||||||
FloatTy::F32 => Float::F32,
|
Primitive::Float(match f {
|
||||||
FloatTy::F64 => Float::F64,
|
FloatTy::F16 => Float::F16,
|
||||||
FloatTy::F128 => Float::F128,
|
FloatTy::F32 => Float::F32,
|
||||||
}),
|
FloatTy::F64 => Float::F64,
|
||||||
|
FloatTy::F128 => Float::F128,
|
||||||
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
TyKind::Tuple(len, tys) => {
|
TyKind::Tuple(len, tys) => {
|
||||||
|
|
@ -293,56 +252,16 @@ pub fn layout_of_ty_query(
|
||||||
TyKind::Array(element, count) => {
|
TyKind::Array(element, count) => {
|
||||||
let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64;
|
let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64;
|
||||||
let element = db.layout_of_ty(element.clone(), trait_env)?;
|
let element = db.layout_of_ty(element.clone(), trait_env)?;
|
||||||
let size = element
|
cx.calc.array_like::<_, _, ()>(&element, Some(count))?
|
||||||
.size
|
|
||||||
.checked_mul(count, dl)
|
|
||||||
.ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
|
|
||||||
|
|
||||||
let backend_repr = BackendRepr::Memory { sized: true };
|
|
||||||
|
|
||||||
let largest_niche = if count != 0 { element.largest_niche } else { None };
|
|
||||||
let uninhabited = if count != 0 { element.uninhabited } else { false };
|
|
||||||
|
|
||||||
Layout {
|
|
||||||
variants: Variants::Single { index: struct_variant_idx() },
|
|
||||||
fields: FieldsShape::Array { stride: element.size, count },
|
|
||||||
backend_repr,
|
|
||||||
largest_niche,
|
|
||||||
uninhabited,
|
|
||||||
align: element.align,
|
|
||||||
size,
|
|
||||||
max_repr_align: None,
|
|
||||||
unadjusted_abi_align: element.align.abi,
|
|
||||||
randomization_seed: Hash64::ZERO,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TyKind::Slice(element) => {
|
TyKind::Slice(element) => {
|
||||||
let element = db.layout_of_ty(element.clone(), trait_env)?;
|
let element = db.layout_of_ty(element.clone(), trait_env)?;
|
||||||
Layout {
|
cx.calc.array_like::<_, _, ()>(&element, None)?
|
||||||
variants: Variants::Single { index: struct_variant_idx() },
|
}
|
||||||
fields: FieldsShape::Array { stride: element.size, count: 0 },
|
TyKind::Str => {
|
||||||
backend_repr: BackendRepr::Memory { sized: false },
|
let element = scalar_unit(dl, Primitive::Int(Integer::I8, false));
|
||||||
largest_niche: None,
|
cx.calc.array_like::<_, _, ()>(&Layout::scalar(dl, element), None)?
|
||||||
uninhabited: false,
|
|
||||||
align: element.align,
|
|
||||||
size: Size::ZERO,
|
|
||||||
max_repr_align: None,
|
|
||||||
unadjusted_abi_align: element.align.abi,
|
|
||||||
randomization_seed: Hash64::ZERO,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
TyKind::Str => Layout {
|
|
||||||
variants: Variants::Single { index: struct_variant_idx() },
|
|
||||||
fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
|
|
||||||
backend_repr: BackendRepr::Memory { sized: false },
|
|
||||||
largest_niche: None,
|
|
||||||
uninhabited: false,
|
|
||||||
align: dl.i8_align,
|
|
||||||
size: Size::ZERO,
|
|
||||||
max_repr_align: None,
|
|
||||||
unadjusted_abi_align: dl.i8_align.abi,
|
|
||||||
randomization_seed: Hash64::ZERO,
|
|
||||||
},
|
|
||||||
// Potentially-wide pointers.
|
// Potentially-wide pointers.
|
||||||
TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => {
|
TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => {
|
||||||
let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA));
|
let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA));
|
||||||
|
|
@ -380,17 +299,12 @@ pub fn layout_of_ty_query(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Effectively a (ptr, meta) tuple.
|
// Effectively a (ptr, meta) tuple.
|
||||||
cx.calc.scalar_pair(data_ptr, metadata)
|
LayoutData::scalar_pair(dl, data_ptr, metadata)
|
||||||
}
|
}
|
||||||
TyKind::FnDef(_, _) => layout_of_unit(&cx)?,
|
TyKind::Never => LayoutData::never_type(dl),
|
||||||
TyKind::Never => cx.calc.layout_of_never_type(),
|
TyKind::FnDef(..) | TyKind::Dyn(_) | TyKind::Foreign(_) => {
|
||||||
TyKind::Dyn(_) | TyKind::Foreign(_) => {
|
let sized = matches!(kind, TyKind::FnDef(..));
|
||||||
let mut unit = layout_of_unit(&cx)?;
|
LayoutData::unit(dl, sized)
|
||||||
match &mut unit.backend_repr {
|
|
||||||
BackendRepr::Memory { sized } => *sized = false,
|
|
||||||
_ => return Err(LayoutError::Unknown),
|
|
||||||
}
|
|
||||||
unit
|
|
||||||
}
|
}
|
||||||
TyKind::Function(_) => {
|
TyKind::Function(_) => {
|
||||||
let mut ptr = scalar_unit(dl, Primitive::Pointer(dl.instruction_address_space));
|
let mut ptr = scalar_unit(dl, Primitive::Pointer(dl.instruction_address_space));
|
||||||
|
|
@ -462,16 +376,6 @@ pub fn layout_of_ty_recover(
|
||||||
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
Err(LayoutError::RecursiveTypeWithoutIndirection)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_of_unit(cx: &LayoutCx<'_>) -> Result<Layout, LayoutError> {
|
|
||||||
cx.calc
|
|
||||||
.univariant::<RustcFieldIdx, RustcEnumVariantIdx, &&Layout>(
|
|
||||||
IndexSlice::empty(),
|
|
||||||
&ReprOptions::default(),
|
|
||||||
StructKind::AlwaysSized,
|
|
||||||
)
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
|
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
|
||||||
match pointee.kind(Interner) {
|
match pointee.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => {
|
TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => {
|
||||||
|
|
@ -502,9 +406,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
|
||||||
Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
|
Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
|
|
||||||
Layout::scalar(dl, scalar_unit(dl, value))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,12 @@ use triomphe::Arc;
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
lang_items::is_unsafe_cell,
|
lang_items::is_unsafe_cell,
|
||||||
layout::{field_ty, Layout, LayoutError, RustcEnumVariantIdx},
|
layout::{field_ty, Layout, LayoutError},
|
||||||
Substitution, TraitEnvironment,
|
Substitution, TraitEnvironment,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::LayoutCx;
|
use super::LayoutCx;
|
||||||
|
|
||||||
pub(crate) fn struct_variant_idx() -> RustcEnumVariantIdx {
|
|
||||||
RustcEnumVariantIdx(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout_of_adt_query(
|
pub fn layout_of_adt_query(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
def: AdtId,
|
def: AdtId,
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,7 @@ fn simd_types() {
|
||||||
check_size_and_align(
|
check_size_and_align(
|
||||||
r#"
|
r#"
|
||||||
#[repr(simd)]
|
#[repr(simd)]
|
||||||
struct SimdType(i64, i64);
|
struct SimdType([i64; 2]);
|
||||||
struct Goal(SimdType);
|
struct Goal(SimdType);
|
||||||
"#,
|
"#,
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@ extern crate ra_ap_rustc_index as rustc_index;
|
||||||
#[cfg(feature = "in-rust-tree")]
|
#[cfg(feature = "in-rust-tree")]
|
||||||
extern crate rustc_abi;
|
extern crate rustc_abi;
|
||||||
|
|
||||||
#[cfg(feature = "in-rust-tree")]
|
|
||||||
extern crate rustc_hashes;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "in-rust-tree"))]
|
#[cfg(not(feature = "in-rust-tree"))]
|
||||||
extern crate ra_ap_rustc_abi as rustc_abi;
|
extern crate ra_ap_rustc_abi as rustc_abi;
|
||||||
|
|
||||||
|
|
@ -24,9 +21,6 @@ extern crate rustc_pattern_analysis;
|
||||||
#[cfg(not(feature = "in-rust-tree"))]
|
#[cfg(not(feature = "in-rust-tree"))]
|
||||||
extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis;
|
extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis;
|
||||||
|
|
||||||
#[cfg(not(feature = "in-rust-tree"))]
|
|
||||||
extern crate ra_ap_rustc_hashes as rustc_hashes;
|
|
||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
mod chalk_db;
|
mod chalk_db;
|
||||||
mod chalk_ext;
|
mod chalk_ext;
|
||||||
|
|
|
||||||
|
|
@ -12311,40 +12311,6 @@ fn main() {
|
||||||
```
|
```
|
||||||
|
|
||||||
will unnecessarily extend the stack frame.
|
will unnecessarily extend the stack frame.
|
||||||
"##,
|
|
||||||
default_severity: Severity::Allow,
|
|
||||||
warn_since: None,
|
|
||||||
deny_since: None,
|
|
||||||
},
|
|
||||||
Lint {
|
|
||||||
label: "unsized_tuple_coercion",
|
|
||||||
description: r##"# `unsized_tuple_coercion`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#42877]
|
|
||||||
|
|
||||||
[#42877]: https://github.com/rust-lang/rust/issues/42877
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
|
|
||||||
|
|
||||||
```rust,ignore (partial-example)
|
|
||||||
impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
|
|
||||||
```
|
|
||||||
|
|
||||||
This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(unsized_tuple_coercion)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
|
|
||||||
let y : &([i32; 3], [i32]) = &x;
|
|
||||||
assert_eq!(y.1[0], 4);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
|
|
||||||
"##,
|
"##,
|
||||||
default_severity: Severity::Allow,
|
default_severity: Severity::Allow,
|
||||||
warn_since: None,
|
warn_since: None,
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,8 @@ fn analyze_source_file_dispatch(
|
||||||
/// SSE2 intrinsics to quickly find all newlines.
|
/// SSE2 intrinsics to quickly find all newlines.
|
||||||
#[target_feature(enable = "sse2")]
|
#[target_feature(enable = "sse2")]
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
|
||||||
|
#[allow(unsafe_op_in_unsafe_fn)]
|
||||||
unsafe fn analyze_source_file_sse2(
|
unsafe fn analyze_source_file_sse2(
|
||||||
src: &str,
|
src: &str,
|
||||||
lines: &mut Vec<TextSize>,
|
lines: &mut Vec<TextSize>,
|
||||||
|
|
@ -287,17 +289,17 @@ unsafe fn analyze_source_file_sse2(
|
||||||
|
|
||||||
// For character in the chunk, see if its byte value is < 0, which
|
// For character in the chunk, see if its byte value is < 0, which
|
||||||
// indicates that it's part of a UTF-8 char.
|
// indicates that it's part of a UTF-8 char.
|
||||||
let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
|
let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
|
||||||
// Create a bit mask from the comparison results.
|
// Create a bit mask from the comparison results.
|
||||||
let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
|
let multibyte_mask = _mm_movemask_epi8(multibyte_test);
|
||||||
|
|
||||||
// If the bit mask is all zero, we only have ASCII chars here:
|
// If the bit mask is all zero, we only have ASCII chars here:
|
||||||
if multibyte_mask == 0 {
|
if multibyte_mask == 0 {
|
||||||
assert!(intra_chunk_offset == 0);
|
assert!(intra_chunk_offset == 0);
|
||||||
|
|
||||||
// Check for newlines in the chunk
|
// Check for newlines in the chunk
|
||||||
let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
|
let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
|
||||||
let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
|
let newlines_mask = _mm_movemask_epi8(newlines_test);
|
||||||
|
|
||||||
if newlines_mask != 0 {
|
if newlines_mask != 0 {
|
||||||
// All control characters are newlines, record them
|
// All control characters are newlines, record them
|
||||||
|
|
@ -354,15 +356,19 @@ unsafe fn analyze_source_file_sse2(
|
||||||
// The mask is a 64-bit integer, where each 4-bit corresponds to a u8 in the
|
// The mask is a 64-bit integer, where each 4-bit corresponds to a u8 in the
|
||||||
// input vector. The least significant 4 bits correspond to the first byte in
|
// input vector. The least significant 4 bits correspond to the first byte in
|
||||||
// the vector.
|
// the vector.
|
||||||
|
// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
|
||||||
|
#[allow(unsafe_op_in_unsafe_fn)]
|
||||||
unsafe fn move_mask(v: std::arch::aarch64::uint8x16_t) -> u64 {
|
unsafe fn move_mask(v: std::arch::aarch64::uint8x16_t) -> u64 {
|
||||||
use std::arch::aarch64::*;
|
use std::arch::aarch64::*;
|
||||||
|
|
||||||
let nibble_mask = unsafe { vshrn_n_u16(vreinterpretq_u16_u8(v), 4) };
|
let nibble_mask = vshrn_n_u16(vreinterpretq_u16_u8(v), 4);
|
||||||
unsafe { vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0) }
|
vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[target_feature(enable = "neon")]
|
#[target_feature(enable = "neon")]
|
||||||
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
|
#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
|
||||||
|
// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
|
||||||
|
#[allow(unsafe_op_in_unsafe_fn)]
|
||||||
unsafe fn analyze_source_file_neon(
|
unsafe fn analyze_source_file_neon(
|
||||||
src: &str,
|
src: &str,
|
||||||
lines: &mut Vec<TextSize>,
|
lines: &mut Vec<TextSize>,
|
||||||
|
|
@ -376,7 +382,7 @@ unsafe fn analyze_source_file_neon(
|
||||||
|
|
||||||
let chunk_count = src.len() / CHUNK_SIZE;
|
let chunk_count = src.len() / CHUNK_SIZE;
|
||||||
|
|
||||||
let newline = unsafe { vdupq_n_s8(b'\n' as i8) };
|
let newline = vdupq_n_s8(b'\n' as i8);
|
||||||
|
|
||||||
// This variable keeps track of where we should start decoding a
|
// This variable keeps track of where we should start decoding a
|
||||||
// chunk. If a multi-byte character spans across chunk boundaries,
|
// chunk. If a multi-byte character spans across chunk boundaries,
|
||||||
|
|
@ -390,7 +396,7 @@ unsafe fn analyze_source_file_neon(
|
||||||
|
|
||||||
// For character in the chunk, see if its byte value is < 0, which
|
// For character in the chunk, see if its byte value is < 0, which
|
||||||
// indicates that it's part of a UTF-8 char.
|
// indicates that it's part of a UTF-8 char.
|
||||||
let multibyte_test = unsafe { vcltzq_s8(chunk) };
|
let multibyte_test = vcltzq_s8(chunk);
|
||||||
// Create a bit mask from the comparison results.
|
// Create a bit mask from the comparison results.
|
||||||
let multibyte_mask = unsafe { move_mask(multibyte_test) };
|
let multibyte_mask = unsafe { move_mask(multibyte_test) };
|
||||||
|
|
||||||
|
|
@ -399,7 +405,7 @@ unsafe fn analyze_source_file_neon(
|
||||||
assert!(intra_chunk_offset == 0);
|
assert!(intra_chunk_offset == 0);
|
||||||
|
|
||||||
// Check for newlines in the chunk
|
// Check for newlines in the chunk
|
||||||
let newlines_test = unsafe { vceqq_s8(chunk, newline) };
|
let newlines_test = vceqq_s8(chunk, newline);
|
||||||
let mut newlines_mask = unsafe { move_mask(newlines_test) };
|
let mut newlines_mask = unsafe { move_mask(newlines_test) };
|
||||||
|
|
||||||
// If the bit mask is not all zero, there are newlines in this chunk.
|
// If the bit mask is not all zero, there are newlines in this chunk.
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
daf59857d6d2b87af4b846316bf1561a6083ed51
|
2c6a12ec44d0426c8939123c2f2cf27d2217de13
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue