Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/eval/shim/simd.rs')
-rw-r--r--crates/hir-ty/src/mir/eval/shim/simd.rs52
1 files changed, 23 insertions, 29 deletions
diff --git a/crates/hir-ty/src/mir/eval/shim/simd.rs b/crates/hir-ty/src/mir/eval/shim/simd.rs
index bc331a23d9..4c64a70a7a 100644
--- a/crates/hir-ty/src/mir/eval/shim/simd.rs
+++ b/crates/hir-ty/src/mir/eval/shim/simd.rs
@@ -2,7 +2,6 @@
use std::cmp::Ordering;
-use crate::TyKind;
use crate::consteval::try_const_usize;
use super::*;
@@ -22,23 +21,21 @@ macro_rules! not_supported {
};
}
-impl Evaluator<'_> {
- fn detect_simd_ty(&self, ty: &Ty) -> Result<(usize, Ty)> {
- match ty.kind(Interner) {
- TyKind::Adt(id, subst) => {
- let len = match subst.as_slice(Interner).get(1).and_then(|it| it.constant(Interner))
- {
+impl<'db> Evaluator<'db> {
+ fn detect_simd_ty(&self, ty: Ty<'db>) -> Result<'db, (usize, Ty<'db>)> {
+ match ty.kind() {
+ TyKind::Adt(adt_def, subst) => {
+ let len = match subst.as_slice().get(1).and_then(|it| it.konst()) {
Some(len) => len,
_ => {
- if let AdtId::StructId(id) = id.0 {
+ if let AdtId::StructId(id) = adt_def.def_id().0 {
let struct_data = id.fields(self.db);
let fields = struct_data.fields();
let Some((first_field, _)) = fields.iter().next() else {
not_supported!("simd type with no field");
};
let field_ty = self.db.field_types(id.into())[first_field]
- .clone()
- .substitute(Interner, subst);
+ .instantiate(self.interner(), subst);
return Ok((fields.len(), field_ty));
}
return Err(MirEvalError::InternalError(
@@ -48,14 +45,12 @@ impl Evaluator<'_> {
};
match try_const_usize(self.db, len) {
Some(len) => {
- let Some(ty) =
- subst.as_slice(Interner).first().and_then(|it| it.ty(Interner))
- else {
+ let Some(ty) = subst.as_slice().first().and_then(|it| it.ty()) else {
return Err(MirEvalError::InternalError(
"simd type with no ty param".into(),
));
};
- Ok((len as usize, ty.clone()))
+ Ok((len as usize, ty))
}
None => Err(MirEvalError::InternalError(
"simd type with unevaluatable len param".into(),
@@ -69,12 +64,12 @@ impl Evaluator<'_> {
pub(super) fn exec_simd_intrinsic(
&mut self,
name: &str,
- args: &[IntervalAndTy],
- _generic_args: &Substitution,
+ args: &[IntervalAndTy<'db>],
+ _generic_args: GenericArgs<'db>,
destination: Interval,
- _locals: &Locals,
+ _locals: &Locals<'db>,
_span: MirSpan,
- ) -> Result<()> {
+ ) -> Result<'db, ()> {
match name {
"and" | "or" | "xor" => {
let [left, right] = args else {
@@ -99,8 +94,8 @@ impl Evaluator<'_> {
let [left, right] = args else {
return Err(MirEvalError::InternalError("simd args are not provided".into()));
};
- let (len, ty) = self.detect_simd_ty(&left.ty)?;
- let is_signed = matches!(ty.as_builtin(), Some(BuiltinType::Int(_)));
+ let (len, ty) = self.detect_simd_ty(left.ty)?;
+ let is_signed = matches!(ty.kind(), TyKind::Int(_));
let size = left.interval.size / len;
let dest_size = destination.size / len;
let mut destination_bytes = vec![];
@@ -114,12 +109,11 @@ impl Evaluator<'_> {
break;
}
}
- if is_signed {
- if let Some((&l, &r)) = l.iter().zip(r).next_back() {
- if l != r {
- result = (l as i8).cmp(&(r as i8));
- }
- }
+ if is_signed
+ && let Some((&l, &r)) = l.iter().zip(r).next_back()
+ && l != r
+ {
+ result = (l as i8).cmp(&(r as i8));
}
let result = match result {
Ordering::Less => ["lt", "le", "ne"].contains(&name),
@@ -138,7 +132,7 @@ impl Evaluator<'_> {
"simd_bitmask args are not provided".into(),
));
};
- let (op_len, _) = self.detect_simd_ty(&op.ty)?;
+ let (op_len, _) = self.detect_simd_ty(op.ty)?;
let op_count = op.interval.size / op_len;
let mut result: u64 = 0;
for (i, val) in op.get(self)?.chunks(op_count).enumerate() {
@@ -154,7 +148,7 @@ impl Evaluator<'_> {
"simd_shuffle args are not provided".into(),
));
};
- let TyKind::Array(_, index_len) = index.ty.kind(Interner) else {
+ let TyKind::Array(_, index_len) = index.ty.kind() else {
return Err(MirEvalError::InternalError(
"simd_shuffle index argument has non-array type".into(),
));
@@ -167,7 +161,7 @@ impl Evaluator<'_> {
));
}
};
- let (left_len, _) = self.detect_simd_ty(&left.ty)?;
+ let (left_len, _) = self.detect_simd_ty(left.ty)?;
let left_size = left.interval.size / left_len;
let vector =
left.get(self)?.chunks(left_size).chain(right.get(self)?.chunks(left_size));