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.rs | 52 |
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)); |